diff --git a/ash/accelerators/accelerator_commands.cc b/ash/accelerators/accelerator_commands.cc new file mode 100644 index 00000000000000..24b8a62b13e84f --- /dev/null +++ b/ash/accelerators/accelerator_commands.cc @@ -0,0 +1,36 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/accelerators/accelerator_commands.h" + +#include "ash/shell.h" +#include "ash/shell_delegate.h" +#include "ash/wm/window_cycle_controller.h" +#include "ash/wm/window_util.h" + +namespace ash { +namespace accelerators { + +bool ToggleMinimized() { + aura::Window* window = wm::GetActiveWindow(); + // Attempt to restore the window that would be cycled through next from + // the launcher when there is no active window. + if (!window) { + ash::Shell::GetInstance()->window_cycle_controller()-> + HandleCycleWindow(WindowCycleController::FORWARD, false); + return true; + } + // Disable the shortcut for minimizing full screen window due to + // crbug.com/131709, which is a crashing issue related to minimizing + // full screen pepper window. + if (wm::IsWindowFullscreen(window) || !wm::CanMinimizeWindow(window)) + return false; + ash::Shell::GetInstance()->delegate()->RecordUserMetricsAction( + ash::UMA_MINIMIZE_PER_KEY); + wm::MinimizeWindow(window); + return true; +} + +} // namespace accelerators +} // namespace ash diff --git a/ash/accelerators/accelerator_commands.h b/ash/accelerators/accelerator_commands.h new file mode 100644 index 00000000000000..5fe2775bdbd6f0 --- /dev/null +++ b/ash/accelerators/accelerator_commands.h @@ -0,0 +1,23 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_ACCELERATORS_ACCELERATOR_COMMANDS_H_ +#define ASH_ACCELERATORS_ACCELERATOR_COMMANDS_H_ + +#include "ash/ash_export.h" + +// This file contains implementations of commands that are bound to keyboard +// shortcuts in Ash or in the embedding application (e.g. Chrome). +namespace ash { +namespace accelerators { + +// Minimizes the active window, if present. If no windows are active, restores +// the first unminimized window. Returns true if a window was minimized or +// restored. +ASH_EXPORT bool ToggleMinimized(); + +} // namespace accelerators +} // namespace ash + +#endif // ASH_ACCELERATORS_ACCELERATOR_COMMANDS_H_ diff --git a/ash/accelerators/accelerator_commands_unittest.cc b/ash/accelerators/accelerator_commands_unittest.cc new file mode 100644 index 00000000000000..7d75cb89aee3b8 --- /dev/null +++ b/ash/accelerators/accelerator_commands_unittest.cc @@ -0,0 +1,31 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/accelerators/accelerator_commands.h" + +#include "ash/test/ash_test_base.h" +#include "ash/wm/window_util.h" +#include "ui/aura/window.h" + +namespace ash { +namespace accelerators { + +typedef test::AshTestBase AcceleratorCommandsTest; + +TEST_F(AcceleratorCommandsTest, ToggleMinimized) { + scoped_ptr window( + CreateTestWindowInShellWithBounds(gfx::Rect(5, 5, 20, 20))); + wm::ActivateWindow(window.get()); + + ToggleMinimized(); + EXPECT_TRUE(wm::IsWindowMinimized(window.get())); + EXPECT_FALSE(wm::IsWindowNormal(window.get())); + + ToggleMinimized(); + EXPECT_FALSE(wm::IsWindowMinimized(window.get())); + EXPECT_TRUE(wm::IsWindowNormal(window.get())); +} + +} // namespace accelerators +} // namespace ash diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index de85b561cb77eb..a9a5f9a9ff2283 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc @@ -9,6 +9,7 @@ #include #include +#include "ash/accelerators/accelerator_commands.h" #include "ash/accelerators/accelerator_table.h" #include "ash/ash_switches.h" #include "ash/caps_lock_delegate.h" @@ -843,23 +844,8 @@ bool AcceleratorController::PerformAction(int action, internal::SnapSizer::RIGHT_EDGE); return true; } - case WINDOW_MINIMIZE: { - aura::Window* window = wm::GetActiveWindow(); - // Attempt to restore the window that would be cycled through next from - // the launcher when there is no active window. - if (!window) - return HandleCycleWindowMRU(WindowCycleController::FORWARD, false); - // Disable the shortcut for minimizing full screen window due to - // crbug.com/131709, which is a crashing issue related to minimizing - // full screen pepper window. - if (!wm::IsWindowFullscreen(window) && wm::CanMinimizeWindow(window)) { - ash::Shell::GetInstance()->delegate()->RecordUserMetricsAction( - ash::UMA_MINIMIZE_PER_KEY); - wm::MinimizeWindow(window); - return true; - } - break; - } + case WINDOW_MINIMIZE: + return accelerators::ToggleMinimized(); case TOGGLE_FULLSCREEN: { if (key_code == ui::VKEY_MEDIA_LAUNCH_APP2) { shell->delegate()->RecordUserMetricsAction( diff --git a/ash/accelerators/accelerator_table.cc b/ash/accelerators/accelerator_table.cc index e3902c792c399a..60b102fd87bb07 100644 --- a/ash/accelerators/accelerator_table.cc +++ b/ash/accelerators/accelerator_table.cc @@ -147,8 +147,6 @@ const AcceleratorData kAcceleratorData[] = { { true, ui::VKEY_OEM_4, ui::EF_ALT_DOWN, WINDOW_SNAP_LEFT }, { true, ui::VKEY_OEM_6, ui::EF_ALT_DOWN, WINDOW_SNAP_RIGHT }, { true, ui::VKEY_OEM_MINUS, ui::EF_ALT_DOWN, WINDOW_MINIMIZE }, - // Convenience for users switching from Mac OS. - { true, ui::VKEY_M, ui::EF_CONTROL_DOWN, WINDOW_MINIMIZE }, { true, ui::VKEY_OEM_PLUS, ui::EF_ALT_DOWN, TOGGLE_MAXIMIZED }, { true, ui::VKEY_OEM_PLUS, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, WINDOW_POSITION_CENTER }, diff --git a/ash/accelerators/accelerator_table.h b/ash/accelerators/accelerator_table.h index 8c400cefc0d7eb..da5acdde7d3123 100644 --- a/ash/accelerators/accelerator_table.h +++ b/ash/accelerators/accelerator_table.h @@ -12,6 +12,32 @@ namespace ash { +// There are four classes of accelerators in Ash: +// +// Ash (OS) reserved: +// * Neither packaged apps nor web pages can cancel. +// * For example, Alt-Tab window cycling. +// * See kReservedActions below. +// +// Ash (OS) non-reserved: +// * Packaged apps can cancel but web pages cannot. +// * For example, volume up and down. +// * See kActionsAllowedInAppMode below. +// +// Browser reserved: +// * Packaged apps can cancel but web pages cannot. +// * For example, browser back and forward from first-row function keys. +// * See IsReservedCommandOrKey() in +// chrome/browser/ui/browser_command_controller.cc. +// +// Browser non-reserved: +// * Both packaged apps and web pages can cancel. +// * For example, selecting tabs by number with Ctrl-1 to Ctrl-9. +// * See kAcceleratorMap in chrome/browser/ui/views/accelerator_table.cc. +// +// In particular, there is not an accelerator processing pass for Ash after +// the browser gets the accelerator. See crbug.com/285308 for details. +// // Please put if/def sections at the end of the bare section and keep the list // within each section in alphabetical order. enum AcceleratorAction { diff --git a/ash/ash.gyp b/ash/ash.gyp index 389bb121bd1767..6f17a00a9de5d7 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -47,6 +47,8 @@ ], 'sources': [ # All .cc, .h under ash, except unittests + 'accelerators/accelerator_commands.cc', + 'accelerators/accelerator_commands.h', 'accelerators/accelerator_controller.cc', 'accelerators/accelerator_controller.h', 'accelerators/accelerator_dispatcher.cc', @@ -535,6 +537,8 @@ 'conditions': [ ['OS=="mac"', { 'sources/': [ + ['exclude', 'accelerators/accelerator_commands.cc'], + ['exclude', 'accelerators/accelerator_commands.h'], ['exclude', 'accelerators/accelerator_controller.cc'], ['exclude', 'accelerators/accelerator_controller.h'], ['exclude', 'accelerators/accelerator_dispatcher.cc'], @@ -679,6 +683,7 @@ '../ui/compositor/test/layer_animator_test_controller.h', '../ui/views/test/test_views_delegate.cc', '../ui/views/test/test_views_delegate.h', + 'accelerators/accelerator_commands_unittest.cc', 'accelerators/accelerator_controller_unittest.cc', 'accelerators/accelerator_filter_unittest.cc', 'accelerators/accelerator_table_unittest.cc', diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 07e1822251d5df..b91d63fa662b45 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc @@ -51,6 +51,7 @@ #endif #if defined(USE_ASH) +#include "ash/accelerators/accelerator_commands.h" #include "chrome/browser/ui/ash/ash_util.h" #endif @@ -444,6 +445,11 @@ void BrowserCommandController::ExecuteCommandWithDisposition( case IDC_TOGGLE_ASH_DESKTOP: chrome::ToggleAshDesktop(); break; + case IDC_MINIMIZE_WINDOW: + ash::accelerators::ToggleMinimized(); + break; + // If Ash needs many more commands here we should implement a general + // mechanism to pass accelerators back into Ash. http://crbug.com/285308 #endif #if defined(OS_WIN) @@ -836,6 +842,9 @@ void BrowserCommandController::InitCommandState() { chrome::HOST_DESKTOP_TYPE_NATIVE != chrome::HOST_DESKTOP_TYPE_ASH) command_updater_.UpdateCommandEnabled(IDC_TOGGLE_ASH_DESKTOP, true); #endif +#if defined(USE_ASH) + command_updater_.UpdateCommandEnabled(IDC_MINIMIZE_WINDOW, true); +#endif // Page-related commands command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true); diff --git a/chrome/browser/ui/views/accelerator_table.cc b/chrome/browser/ui/views/accelerator_table.cc index 9115bd8835e2b8..5b84d1e08d9841 100644 --- a/chrome/browser/ui/views/accelerator_table.cc +++ b/chrome/browser/ui/views/accelerator_table.cc @@ -123,6 +123,8 @@ const AcceleratorMapping kAcceleratorMap[] = { { ui::VKEY_BROWSER_REFRESH, ui::EF_SHIFT_DOWN, IDC_RELOAD_IGNORING_CACHE }, { ui::VKEY_BROWSER_FAVORITES, ui::EF_NONE, IDC_SHOW_BOOKMARK_MANAGER }, { ui::VKEY_BROWSER_STOP, ui::EF_NONE, IDC_STOP }, + // Not implemented inside Ash to allow web pages to capture the key. + { ui::VKEY_M, ui::EF_CONTROL_DOWN, IDC_MINIMIZE_WINDOW }, #else // OS_CHROMEOS { ui::VKEY_DELETE, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLEAR_BROWSING_DATA },