diff options
-rw-r--r-- | ash/accelerators/accelerator_controller.cc | 3 | ||||
-rw-r--r-- | ash/accelerators/accelerator_controller_unittest.cc | 66 | ||||
-rw-r--r-- | ash/accelerators/accelerator_filter.cc | 4 | ||||
-rw-r--r-- | ui/base/accelerators/accelerator_manager.cc | 31 | ||||
-rw-r--r-- | ui/base/accelerators/accelerator_manager.h | 8 | ||||
-rw-r--r-- | ui/base/keycodes/keyboard_code_conversion_x.cc | 2 |
6 files changed, 104 insertions, 10 deletions
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index 271165b..cb26296 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc @@ -64,7 +64,8 @@ const struct AcceleratorData { AcceleratorAction action; } kAcceleratorData[] = { // Accelerators that should be processed before a key is sent to an IME. - // TODO(yusukes): Handle the NEXT_IME shortcut (Alt+Shift+Release) here. + { ui::ET_KEY_RELEASED, ui::VKEY_MENU, true, false, true, NEXT_IME }, + { ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, true, false, true, NEXT_IME }, { ui::ET_KEY_PRESSED, ui::VKEY_SPACE, false, true, false, PREVIOUS_IME }, // Shortcuts for Japanese IME. { ui::ET_KEY_PRESSED, ui::VKEY_CONVERT, false, false, false, SWITCH_IME }, diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc index 06d733e..10bbf5a 100644 --- a/ash/accelerators/accelerator_controller_unittest.cc +++ b/ash/accelerators/accelerator_controller_unittest.cc @@ -62,6 +62,27 @@ class PostImeAccelerator : public ui::Accelerator { }; typedef ui::Accelerator PreImeAccelerator; +class PostImeReleaseAccelerator : public ui::Accelerator { + public: + PostImeReleaseAccelerator(ui::KeyboardCode keycode, + bool shift_pressed, + bool ctrl_pressed, + bool alt_pressed) + : ui::Accelerator(keycode, shift_pressed, ctrl_pressed, alt_pressed) { + set_type(ui::ET_TRANSLATED_KEY_RELEASE); + } +}; +class PreImeReleaseAccelerator : public ui::Accelerator { + public: + PreImeReleaseAccelerator(ui::KeyboardCode keycode, + bool shift_pressed, + bool ctrl_pressed, + bool alt_pressed) + : ui::Accelerator(keycode, shift_pressed, ctrl_pressed, alt_pressed) { + set_type(ui::ET_KEY_RELEASED); + } +}; + class DummyScreenshotDelegate : public ScreenshotDelegate { public: DummyScreenshotDelegate() @@ -650,7 +671,6 @@ TEST_F(AcceleratorControllerTest, GlobalAcceleratorsPreIme) { // Test IME shortcuts. { - // TODO(yusukes): Add a test for Alt+Shift+Release. const ui::Accelerator control_space(ui::VKEY_SPACE, false, true, false); const ui::Accelerator convert(ui::VKEY_CONVERT, false, false, false); const ui::Accelerator non_convert(ui::VKEY_NONCONVERT, false, false, false); @@ -718,6 +738,50 @@ TEST_F(AcceleratorControllerTest, GlobalAcceleratorsPreIme) { EXPECT_FALSE(GetController()->Process(shift_space_post)); EXPECT_EQ(6, delegate->handle_switch_ime_count()); } + + // Test IME shortcuts that are triggered on key release. + { + const PreImeAccelerator shift_alt_press(ui::VKEY_MENU, true, false, true); + const PostImeAccelerator shift_alt_press_post( + ui::VKEY_MENU, true, false, true); + const PreImeReleaseAccelerator shift_alt(ui::VKEY_MENU, true, false, true); + + const PreImeAccelerator alt_shift_press(ui::VKEY_SHIFT, true, false, true); + const PostImeAccelerator alt_shift_press_post( + ui::VKEY_SHIFT, true, false, true); + const PreImeReleaseAccelerator alt_shift(ui::VKEY_SHIFT, true, false, true); + + DummyImeControlDelegate* delegate = new DummyImeControlDelegate(true); + GetController()->SetImeControlDelegate( + scoped_ptr<ImeControlDelegate>(delegate).Pass()); + EXPECT_EQ(0, delegate->handle_next_ime_count()); + EXPECT_FALSE(GetController()->Process(shift_alt_press)); + EXPECT_FALSE(GetController()->Process(shift_alt_press_post)); + EXPECT_TRUE(GetController()->Process(shift_alt)); + EXPECT_EQ(1, delegate->handle_next_ime_count()); + EXPECT_FALSE(GetController()->Process(alt_shift_press)); + EXPECT_FALSE(GetController()->Process(alt_shift_press_post)); + EXPECT_TRUE(GetController()->Process(alt_shift)); + EXPECT_EQ(2, delegate->handle_next_ime_count()); + + // We should NOT switch IME when e.g. Shift+Alt+X is pressed and X is + // released. + const PreImeAccelerator shift_alt_x_press(ui::VKEY_X, true, false, true); + const PostImeAccelerator shift_alt_x_press_post( + ui::VKEY_X, true, false, true); + const PreImeReleaseAccelerator shift_alt_x(ui::VKEY_X, true, false, true); + const PostImeReleaseAccelerator shift_alt_x_post( + ui::VKEY_X, true, false, true); + + EXPECT_FALSE(GetController()->Process(shift_alt_press)); + EXPECT_FALSE(GetController()->Process(shift_alt_press_post)); + EXPECT_FALSE(GetController()->Process(shift_alt_x_press)); + EXPECT_FALSE(GetController()->Process(shift_alt_x_press_post)); + EXPECT_FALSE(GetController()->Process(shift_alt_x)); + EXPECT_FALSE(GetController()->Process(shift_alt_x_post)); + EXPECT_FALSE(GetController()->Process(shift_alt)); + EXPECT_EQ(2, delegate->handle_next_ime_count()); + } } } // namespace test diff --git a/ash/accelerators/accelerator_filter.cc b/ash/accelerators/accelerator_filter.cc index 957efaa..049f94c 100644 --- a/ash/accelerators/accelerator_filter.cc +++ b/ash/accelerators/accelerator_filter.cc @@ -35,8 +35,10 @@ AcceleratorFilter::~AcceleratorFilter() { bool AcceleratorFilter::PreHandleKeyEvent(aura::Window* target, aura::KeyEvent* event) { const ui::EventType type = event->type(); - if (type != ui::ET_KEY_PRESSED && type != ui::ET_TRANSLATED_KEY_PRESS) + if (type != ui::ET_KEY_PRESSED && type != ui::ET_TRANSLATED_KEY_PRESS && + type != ui::ET_KEY_RELEASED && type != ui::ET_TRANSLATED_KEY_RELEASE) { return false; + } if (event->is_char()) return false; diff --git a/ui/base/accelerators/accelerator_manager.cc b/ui/base/accelerators/accelerator_manager.cc index 86d44ea..d2d70c9 100644 --- a/ui/base/accelerators/accelerator_manager.cc +++ b/ui/base/accelerators/accelerator_manager.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -10,7 +10,7 @@ namespace ui { -AcceleratorManager::AcceleratorManager() { +AcceleratorManager::AcceleratorManager() : last_event_type_(ET_KEY_PRESSED) { } AcceleratorManager::~AcceleratorManager() { @@ -52,19 +52,23 @@ void AcceleratorManager::UnregisterAll(AcceleratorTarget* target) { } bool AcceleratorManager::Process(const Accelerator& accelerator) { + bool result = false; AcceleratorMap::iterator map_iter = accelerators_.find(accelerator); - if (map_iter != accelerators_.end()) { + if (map_iter != accelerators_.end() && ShouldHandle(accelerator)) { // We have to copy the target list here, because an AcceleratorPressed // event handler may modify the list. AcceleratorTargetList targets(map_iter->second); for (AcceleratorTargetList::iterator iter = targets.begin(); iter != targets.end(); ++iter) { if ((*iter)->CanHandleAccelerators() && - (*iter)->AcceleratorPressed(accelerator)) - return true; + (*iter)->AcceleratorPressed(accelerator)) { + result = true; + break; + } } } - return false; + last_event_type_ = accelerator.type(); + return result; } AcceleratorTarget* AcceleratorManager::GetCurrentTarget( @@ -75,4 +79,19 @@ AcceleratorTarget* AcceleratorManager::GetCurrentTarget( return map_iter->second.front(); } +bool AcceleratorManager::ShouldHandle(const Accelerator& accelerator) const { + if (accelerator.type() != ET_KEY_RELEASED && + accelerator.type() != ET_TRANSLATED_KEY_RELEASE) { + return true; + } + // This check is necessary e.g. not to process the Shift+Alt+ET_KEY_RELEASED + // Accelerator for Chrome OS (see ash/accelerators/accelerator_controller.cc) + // when Shift+Alt+Tab is pressed and then Tab is released. + if (last_event_type_ == ET_KEY_PRESSED || + last_event_type_ == ET_TRANSLATED_KEY_PRESS) { + return true; + } + return false; +} + } // namespace ui diff --git a/ui/base/accelerators/accelerator_manager.h b/ui/base/accelerators/accelerator_manager.h index 50c73c0..c54ea1d 100644 --- a/ui/base/accelerators/accelerator_manager.h +++ b/ui/base/accelerators/accelerator_manager.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -11,6 +11,7 @@ #include "base/basictypes.h" #include "ui/base/accelerators/accelerator.h" +#include "ui/base/events.h" #include "ui/base/ui_export.h" namespace ui { @@ -52,11 +53,16 @@ class UI_EXPORT AcceleratorManager { AcceleratorTarget* GetCurrentTarget(const Accelerator& accelertor) const; private: + bool ShouldHandle(const Accelerator& accelerator) const; + // The accelerators and associated targets. typedef std::list<AcceleratorTarget*> AcceleratorTargetList; typedef std::map<Accelerator, AcceleratorTargetList> AcceleratorMap; AcceleratorMap accelerators_; + // An event passed to Process() last time. + EventType last_event_type_; + DISALLOW_COPY_AND_ASSIGN(AcceleratorManager); }; diff --git a/ui/base/keycodes/keyboard_code_conversion_x.cc b/ui/base/keycodes/keyboard_code_conversion_x.cc index a1bb6ec..ecb27a4 100644 --- a/ui/base/keycodes/keyboard_code_conversion_x.cc +++ b/ui/base/keycodes/keyboard_code_conversion_x.cc @@ -273,6 +273,8 @@ KeyboardCode KeyboardCodeFromXKeysym(unsigned int keysym) { case XK_Control_L: case XK_Control_R: return VKEY_CONTROL; + case XK_Meta_L: + case XK_Meta_R: case XK_Alt_L: case XK_Alt_R: return VKEY_MENU; |