summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/accelerators/accelerator_controller.cc3
-rw-r--r--ash/accelerators/accelerator_controller_unittest.cc66
-rw-r--r--ash/accelerators/accelerator_filter.cc4
-rw-r--r--ui/base/accelerators/accelerator_manager.cc31
-rw-r--r--ui/base/accelerators/accelerator_manager.h8
-rw-r--r--ui/base/keycodes/keyboard_code_conversion_x.cc2
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;