Commit 2ddf37ba authored by skuhne@chromium.org's avatar skuhne@chromium.org

This CL is adding a minimize function for clicks on launcher items if only a...

This CL is adding a minimize function for clicks on launcher items if only a single item (already active) is associated with it. This is done to avoid that the user clicks and nothing happens (and people expect it to do that). The feature is guarded by a flag.

If the minimize action is not wanted, we use a bouncing animation which gives the user at least some feedback that he has done something.

BUG=231663
TEST=unittest & visual

Review URL: https://chromiumcodereview.appspot.com/14328031

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195362 0039d316-1c4b-4281-b951-d872f2087c98
parent f95cc396
......@@ -6898,6 +6898,12 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_FLAGS_SHOW_LAUNCHER_ALIGNMENT_MENU_DESCRIPTION" desc="Description for the flag to show a menu that lets you change the alignment of the launcher.">
Enables a menu that allows changing the side the launcher is aligned to.
</message>
<message name="IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_NAME" desc="Name for the flag which allows to minimize a window upon launcher item click under certain conditions.">
Disallow launcher to minimize-on-click
</message>
<message name="IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_DESCRIPTION" desc="Description for the flag which allows to minimize a window upon launcher item click under certain conditions.">
Disallow the launcher to minimize a window if a launcher item gets clicked which has only a single, already active, window associated with it.
</message>
<message name="IDS_FLAGS_SHOW_TOUCH_HUD_NAME" desc="Name for the flag to show a heads-up display for tracking touch-points.">
Show HUD for touch points
......
......@@ -971,6 +971,13 @@ const Experiment kExperiments[] = {
kOsAll,
SINGLE_VALUE_TYPE(switches::kShowLauncherAlignmentMenu)
},
{
"disable-minimize-on-second-launcher-item-click",
IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_NAME,
IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_DESCRIPTION,
kOsAll,
SINGLE_VALUE_TYPE(switches::kDisableMinimizeOnSecondLauncherItemClick)
},
{
"show-touch-hud",
IDS_FLAGS_SHOW_TOUCH_HUD_NAME,
......
......@@ -88,9 +88,13 @@ void AppShortcutLauncherItemController::Activate() {
TabStripModel* tab_strip = browser->tab_strip_model();
int index = tab_strip->GetIndexOfWebContents(content);
DCHECK_NE(TabStripModel::kNoTab, index);
tab_strip->ActivateTabAt(index, false);
browser->window()->Show();
ash::wm::ActivateWindow(browser->window()->GetNativeWindow());
int old_index = tab_strip->active_index();
if (index != old_index)
tab_strip->ActivateTabAt(index, false);
app_controller_->ActivateWindowOrMinimizeIfActive(
browser->window(),
index == old_index && GetRunningApplications().size() == 1);
}
void AppShortcutLauncherItemController::Close() {
......
......@@ -14,6 +14,7 @@
#include "chrome/browser/extensions/app_icon_loader.h"
#include "chrome/browser/extensions/extension_prefs.h"
class BaseWindow;
class BrowserLauncherItemControllerTest;
class LauncherItemController;
class Profile;
......@@ -256,6 +257,10 @@ class ChromeLauncherController
virtual const extensions::Extension* GetExtensionForAppID(
const std::string& app_id) const = 0;
// Activates a |window|. If |allow_minimize| is true and the system allows
// it, the the window will get minimized instead.
virtual void ActivateWindowOrMinimizeIfActive(BaseWindow* window,
bool allow_minimize) = 0;
// ash::LauncherDelegate overrides:
virtual void OnBrowserShortcutClicked(int event_flags) OVERRIDE = 0;
virtual void ItemClicked(const ash::LauncherItem& item,
......
......@@ -70,6 +70,7 @@
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/corewm/window_animations.h"
using extensions::Extension;
using content::WebContents;
......@@ -873,6 +874,23 @@ const Extension* ChromeLauncherControllerPerApp::GetExtensionForAppID(
return profile_->GetExtensionService()->GetInstalledExtension(app_id);
}
void ChromeLauncherControllerPerApp::ActivateWindowOrMinimizeIfActive(
BaseWindow* window,
bool allow_minimize) {
if (window->IsActive() && allow_minimize) {
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableMinimizeOnSecondLauncherItemClick)) {
AnimateWindow(window->GetNativeWindow(),
views::corewm::WINDOW_ANIMATION_TYPE_BOUNCE);
} else {
window->Minimize();
}
} else {
window->Show();
window->Activate();
}
}
void ChromeLauncherControllerPerApp::OnBrowserShortcutClicked(
int event_flags) {
if (event_flags & ui::EF_CONTROL_DOWN) {
......@@ -888,9 +906,8 @@ void ChromeLauncherControllerPerApp::OnBrowserShortcutClicked(
return;
}
aura::Window* window = last_browser->window()->GetNativeWindow();
window->Show();
ash::wm::ActivateWindow(window);
ActivateWindowOrMinimizeIfActive(last_browser->window(),
GetBrowserApplicationList(0).size() == 2);
}
void ChromeLauncherControllerPerApp::ItemClicked(const ash::LauncherItem& item,
......
......@@ -35,6 +35,7 @@
#include "ui/aura/window_observer.h"
class AppSyncUIState;
class BaseWindow;
class Browser;
class BrowserLauncherItemControllerTest;
class ExtensionEnableFlow;
......@@ -252,6 +253,11 @@ class ChromeLauncherControllerPerApp
virtual const extensions::Extension* GetExtensionForAppID(
const std::string& app_id) const OVERRIDE;
// Activates a |window|. If |allow_minimize| is true and the system allows
// it, the the window will get minimized instead.
virtual void ActivateWindowOrMinimizeIfActive(BaseWindow* window,
bool allow_minimize) OVERRIDE;
// ash::LauncherDelegate overrides:
virtual void OnBrowserShortcutClicked(int event_flags) OVERRIDE;
virtual void ItemClicked(const ash::LauncherItem& item,
......
......@@ -254,6 +254,28 @@ class LauncherPerAppAppBrowserTestNoDefaultBrowser
DISALLOW_COPY_AND_ASSIGN(LauncherPerAppAppBrowserTestNoDefaultBrowser);
};
// Since the default for minimizing on click might change, I added both classes
// to either get the minimize on click or not.
class LauncherPerAppAppBrowserNoMinimizeOnClick
: public LauncherPlatformPerAppAppBrowserTest {
protected:
LauncherPerAppAppBrowserNoMinimizeOnClick() {}
virtual ~LauncherPerAppAppBrowserNoMinimizeOnClick() {}
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
LauncherPlatformPerAppAppBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(
switches::kDisableMinimizeOnSecondLauncherItemClick);
}
private:
DISALLOW_COPY_AND_ASSIGN(LauncherPerAppAppBrowserNoMinimizeOnClick);
};
typedef LauncherPlatformPerAppAppBrowserTest
LauncherPerAppAppBrowserMinimizeOnClick;
// Test that we can launch a platform app and get a running item.
IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, LaunchUnpinned) {
int item_count = launcher_model()->item_count();
......@@ -552,7 +574,8 @@ IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, WindowActivation) {
}
// Confirm that Click behavior for app windows is correnct.
IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, AppClickBehavior) {
IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserNoMinimizeOnClick,
AppClickBehavior) {
// Launch a platform app and create a window for it.
const Extension* extension1 = LoadAndLaunchPlatformApp("launch");
ShellWindow* window1 = CreateShellWindow(extension1);
......@@ -588,6 +611,64 @@ IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest, AppClickBehavior) {
EXPECT_TRUE(window1->GetBaseWindow()->IsMaximized());
}
// Confirm the minimizing click behavior for apps.
IN_PROC_BROWSER_TEST_F(LauncherPerAppAppBrowserMinimizeOnClick,
PackagedAppClickBehaviorInMinimizeMode) {
// Launch one platform app and create a window for it.
const Extension* extension1 = LoadAndLaunchPlatformApp("launch");
ShellWindow* window1 = CreateShellWindow(extension1);
EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
// Confirm that a controller item was created and is the correct state.
const ash::LauncherItem& item1 = GetLastLauncherItem();
LauncherItemController* item1_controller = GetItemController(item1.id);
EXPECT_EQ(ash::TYPE_PLATFORM_APP, item1.type);
EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
EXPECT_EQ(LauncherItemController::TYPE_APP, item1_controller->type());
// Since it is already active, clicking it should minimize.
TestEvent click_event(ui::ET_MOUSE_PRESSED);
item1_controller->Clicked(click_event);
EXPECT_FALSE(window1->GetNativeWindow()->IsVisible());
EXPECT_FALSE(window1->GetBaseWindow()->IsActive());
EXPECT_TRUE(window1->GetBaseWindow()->IsMinimized());
EXPECT_EQ(ash::STATUS_RUNNING, item1.status);
// Clicking the item again should activate the window again.
item1_controller->Clicked(click_event);
EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
EXPECT_EQ(ash::STATUS_ACTIVE, item1.status);
// Maximizing a window should preserve state after minimize + click.
window1->GetBaseWindow()->Maximize();
window1->GetBaseWindow()->Minimize();
item1_controller->Clicked(click_event);
EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
EXPECT_TRUE(window1->GetBaseWindow()->IsMaximized());
window1->GetBaseWindow()->Restore();
EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
EXPECT_FALSE(window1->GetBaseWindow()->IsMaximized());
// Creating a second window of the same type should change the behavior so
// that a click does not change the activation state.
ShellWindow* window1a = CreateShellWindow(extension1);
EXPECT_TRUE(window1a->GetNativeWindow()->IsVisible());
EXPECT_TRUE(window1a->GetBaseWindow()->IsActive());
// The first click does nothing.
item1_controller->Clicked(click_event);
EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
EXPECT_TRUE(window1a->GetNativeWindow()->IsVisible());
EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
EXPECT_FALSE(window1a->GetBaseWindow()->IsActive());
// The second neither.
item1_controller->Clicked(click_event);
EXPECT_TRUE(window1->GetNativeWindow()->IsVisible());
EXPECT_TRUE(window1a->GetNativeWindow()->IsVisible());
EXPECT_TRUE(window1->GetBaseWindow()->IsActive());
EXPECT_FALSE(window1a->GetBaseWindow()->IsActive());
}
// Confirm that click behavior for app panels is correct.
IN_PROC_BROWSER_TEST_F(LauncherPlatformPerAppAppBrowserTest,
AppPanelClickBehavior) {
......
......@@ -853,6 +853,13 @@ const Extension* ChromeLauncherControllerPerBrowser::GetExtensionForAppID(
return profile_->GetExtensionService()->GetInstalledExtension(app_id);
}
void ChromeLauncherControllerPerBrowser::ActivateWindowOrMinimizeIfActive(
BaseWindow* window,
bool allow_minimize) {
window->Show();
window->Activate();
}
void ChromeLauncherControllerPerBrowser::OnBrowserShortcutClicked(
int event_flags) {
if (event_flags & ui::EF_CONTROL_DOWN) {
......
......@@ -30,6 +30,7 @@
#include "ui/aura/window_observer.h"
class AppSyncUIState;
class BaseWindow;
class Browser;
class BrowserLauncherItemControllerTest;
class ExtensionEnableFlow;
......@@ -241,6 +242,11 @@ class ChromeLauncherControllerPerBrowser
virtual const extensions::Extension* GetExtensionForAppID(
const std::string& app_id) const OVERRIDE;
// Activates a |window|. If |allow_minimize| is true and the system allows
// it, the the window will get minimized instead.
virtual void ActivateWindowOrMinimizeIfActive(BaseWindow* window,
bool allow_minimize) OVERRIDE;
// ash::LauncherDelegate overrides:
virtual void OnBrowserShortcutClicked(int event_flags) OVERRIDE;
virtual void ItemClicked(const ash::LauncherItem& item,
......
......@@ -144,18 +144,18 @@ void ShellWindowLauncherItemController::Clicked(const ui::Event& event) {
// activate it.
if (ash::wm::MoveWindowToEventRoot(panel->GetNativeWindow(), event)) {
if (!panel->GetBaseWindow()->IsActive())
ShowAndActivate(panel);
ShowAndActivateOrMinimize(panel);
} else {
if (panel->GetBaseWindow()->IsActive())
panel->GetBaseWindow()->Minimize();
else
ShowAndActivate(panel);
ShowAndActivateOrMinimize(panel);
}
} else if (launcher_controller()->GetPerAppInterface() ||
shell_windows_.size() == 1) {
ShellWindow* window_to_show = last_active_shell_window_ ?
last_active_shell_window_ : shell_windows_.front();
ShowAndActivate(window_to_show);
ShowAndActivateOrMinimize(window_to_show);
} else {
// TODO(stevenjb): Deprecate
if (!last_active_shell_window_ ||
......@@ -169,7 +169,7 @@ void ShellWindowLauncherItemController::Clicked(const ui::Event& event) {
}
}
if (last_active_shell_window_)
ShowAndActivate(last_active_shell_window_);
ShowAndActivateOrMinimize(last_active_shell_window_);
}
}
......@@ -178,7 +178,7 @@ void ShellWindowLauncherItemController::ActivateIndexedApp(size_t index) {
return;
ShellWindowList::iterator it = shell_windows_.begin();
std::advance(it, index);
ShowAndActivate(*it);
ShowAndActivateOrMinimize(*it);
}
ChromeLauncherAppMenuItems
......@@ -219,9 +219,10 @@ void ShellWindowLauncherItemController::OnWindowPropertyChanged(
}
}
void ShellWindowLauncherItemController::ShowAndActivate(
void ShellWindowLauncherItemController::ShowAndActivateOrMinimize(
ShellWindow* shell_window) {
// Always activate windows when shown from the launcher.
shell_window->GetBaseWindow()->Show();
shell_window->GetBaseWindow()->Activate();
// Either show or minimize windows when shown from the launcher.
launcher_controller()->ActivateWindowOrMinimizeIfActive(
shell_window->GetBaseWindow(),
GetApplicationList().size() == 2);
}
......@@ -80,7 +80,7 @@ class ShellWindowLauncherItemController : public LauncherItemController,
private:
typedef std::list<ShellWindow*> ShellWindowList;
void ShowAndActivate(ShellWindow* shell_window);
void ShowAndActivateOrMinimize(ShellWindow* shell_window);
// List of associated shell windows
ShellWindowList shell_windows_;
......
......@@ -338,6 +338,11 @@ const char kDisableIPPooling[] = "disable-ip-pooling";
const char kDisableLocalOnlyInstantExtendedAPI[] =
"disable-local-only-instant-extended-api";
// Disable the behavior that the second click on a launcher item (the click when
// the item is already active) minimizes the item.
const char kDisableMinimizeOnSecondLauncherItemClick[] =
"disable-minimize-on-second-launcher-item-click";
// Disables the native Autofill UI, which is part of the browser process rather
// than part of the renderer process. http://crbug.com/51644
const char kDisableNativeAutofillUi[] = "disable-new-autofill-ui";
......
......@@ -103,6 +103,7 @@ extern const char kDisableInstantExtendedAPI[];
extern const char kDisableIPv6[];
extern const char kDisableIPPooling[];
extern const char kDisableLocalOnlyInstantExtendedAPI[];
extern const char kDisableMinimizeOnSecondLauncherItemClick[];
extern const char kDisableNativeAutofillUi[];
extern const char kDisableNTPOtherSessionsMenu[];
extern const char kDisablePopupBlocking[];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment