Index: chrome/browser/ui/views/ash/key_rewriter_unittest.cc |
diff --git a/chrome/browser/ui/views/ash/key_rewriter_unittest.cc b/chrome/browser/ui/views/ash/key_rewriter_unittest.cc |
index f32e785fc52de9976a2318160be328c38803e623..94f185735c24f8a83536c87b68267625d1d0bbc4 100644 |
--- a/chrome/browser/ui/views/ash/key_rewriter_unittest.cc |
+++ b/chrome/browser/ui/views/ash/key_rewriter_unittest.cc |
@@ -3,7 +3,10 @@ |
// found in the LICENSE file. |
#include "base/basictypes.h" |
+#include "chrome/browser/prefs/pref_member.h" |
#include "chrome/browser/ui/views/ash/key_rewriter.h" |
+#include "chrome/common/pref_names.h" |
+#include "chrome/test/base/testing_pref_service.h" |
#include "testing/gtest/include/gtest/gtest.h" |
#include "ui/aura/event.h" |
@@ -11,6 +14,8 @@ |
#include <X11/keysym.h> |
#include <X11/Xlib.h> |
+#include "chrome/browser/chromeos/input_method/mock_xkeyboard.h" |
+#include "chrome/browser/chromeos/preferences.h" |
#include "ui/base/x/x11_util.h" |
namespace { |
@@ -99,9 +104,11 @@ TEST(KeyRewriterTest, TestRewriteCommandToControl) { |
XKeysymToKeycode(ui::GetXDisplay(), XK_Control_R); |
// First, test with a PC keyboard. |
+ TestingPrefService prefs; |
KeyRewriter rewriter; |
rewriter.DeviceAddedForTesting(0, "PC Keyboard"); |
rewriter.set_last_device_id_for_testing(0); |
+ rewriter.set_pref_service_for_testing(&prefs); |
{ |
// XK_a, Alt modifier. |
InitXKeyEvent(ui::VKEY_A, ui::EF_ALT_DOWN, kKeycodeA, Mod1Mask, &xev); |
@@ -258,7 +265,9 @@ TEST(KeyRewriterTest, TestRewriteNumPadKeys) { |
const unsigned int kKeycodeNumPadPrior = |
XKeysymToKeycode(display, XK_KP_Prior); |
+ TestingPrefService prefs; |
KeyRewriter rewriter; |
+ rewriter.set_pref_service_for_testing(&prefs); |
{ |
// XK_KP_Insert (= NumPad 0 without Num Lock), no modifier. |
InitXKeyEvent(ui::VKEY_INSERT, 0, kKeycodeNumPadInsert, 0, &xev); |
@@ -534,9 +543,11 @@ TEST(KeyRewriterTest, TestRewriteNumPadKeysOnAppleKeyboard) { |
const unsigned int kKeycodeNumPadEnd = XKeysymToKeycode(display, XK_KP_End); |
const unsigned int kKeycodeNumPad1 = XKeysymToKeycode(display, XK_KP_1); |
+ TestingPrefService prefs; |
KeyRewriter rewriter; |
rewriter.DeviceAddedForTesting(0, "Apple Keyboard"); |
rewriter.set_last_device_id_for_testing(0); |
+ rewriter.set_pref_service_for_testing(&prefs); |
{ |
// XK_KP_End (= NumPad 1 without Num Lock), Win modifier. |
InitXKeyEvent(ui::VKEY_END, 0, kKeycodeNumPadEnd, Mod4Mask, &xev); |
@@ -563,4 +574,656 @@ TEST(KeyRewriterTest, TestRewriteNumPadKeysOnAppleKeyboard) { |
} |
} |
+TEST(KeyRewriterTest, TestRewriteModifiersNoRemap) { |
+ XEvent xev; |
+ Display* display = ui::GetXDisplay(); |
+ |
+ const unsigned int kKeycodeSuperL = XKeysymToKeycode(display, XK_Super_L); |
Daniel Erat
2012/05/23 16:37:32
nit: KeyCode instead of unsigned int for all of th
Yusuke Sato
2012/05/24 08:24:42
Done.
|
+ const unsigned int kKeycodeControlL = XKeysymToKeycode(display, XK_Control_L); |
+ const unsigned int kKeycodeControlR = XKeysymToKeycode(display, XK_Control_R); |
+ const unsigned int kKeycodeAltL = XKeysymToKeycode(display, XK_Alt_L); |
+ const unsigned int kKeycodeAltR = XKeysymToKeycode(display, XK_Alt_R); |
+ CHECK(kKeycodeAltR); |
+ |
+ TestingPrefService prefs; |
+ KeyRewriter rewriter; |
+ rewriter.set_pref_service_for_testing(&prefs); |
+ { |
+ // Press Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, 0, kKeycodeSuperL, 0U, &xev); |
Daniel Erat
2012/05/23 16:37:32
there's a bunch of duplicate code in this file. d
Yusuke Sato
2012/05/24 08:24:42
Thanks for the suggestion! Done.
|
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_LWIN, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ EXPECT_EQ(ui::ET_KEY_PRESSED, keyevent.type()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeSuperL, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ EXPECT_EQ(KeyPress, xkey.type); |
+ } |
+ { |
+ // Press left Control. |
+ InitXKeyEvent(ui::VKEY_CONTROL, 0, kKeycodeControlL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_CONTROL, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeControlL, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ { |
+ // Press right Control. |
+ InitXKeyEvent(ui::VKEY_CONTROL, 0, kKeycodeControlR, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_CONTROL, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeControlR, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ { |
+ // Press left Alt. |
+ InitXKeyEvent(ui::VKEY_MENU, 0, kKeycodeAltL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_MENU, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeAltL, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ { |
+ // Press right Alt. |
+ InitXKeyEvent(ui::VKEY_MENU, 0, kKeycodeAltR, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_MENU, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeAltR, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ |
+ // Test KeyRelease event, just in case. |
+ { |
+ // Release Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, 0, kKeycodeSuperL, Mod4Mask, &xev); |
+ xev.type = KeyRelease; |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the release event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_LWIN, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ EXPECT_EQ(ui::ET_KEY_RELEASED, keyevent.type()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeSuperL, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(Mod4Mask), xkey.state); |
+ EXPECT_EQ(KeyRelease, xkey.type); |
+ } |
+} |
+ |
+TEST(KeyRewriterTest, TestRewriteModifiersNoRemapMultipleKeys) { |
+ XEvent xev; |
+ Display* display = ui::GetXDisplay(); |
+ |
+ const unsigned int kKeycodeSuperL = XKeysymToKeycode(display, XK_Super_L); |
+ const unsigned int kKeycodeMetaL = XKeysymToKeycode(display, XK_Meta_L); |
+ const unsigned int kKeycodeMetaR = XKeysymToKeycode(display, XK_Meta_R); |
+ const unsigned int kKeycodeA = XKeysymToKeycode(display, XK_A); |
+ |
+ TestingPrefService prefs; |
+ KeyRewriter rewriter; |
+ rewriter.set_pref_service_for_testing(&prefs); |
+ { |
+ // Press left Alt with Shift. |
+ InitXKeyEvent(ui::VKEY_MENU, ui::EF_SHIFT_DOWN, |
+ kKeycodeMetaL, ShiftMask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_MENU, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_SHIFT_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeMetaL, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(ShiftMask), xkey.state); |
+ } |
+ { |
+ // Press right Alt with Shift. |
+ InitXKeyEvent(ui::VKEY_MENU, ui::EF_SHIFT_DOWN, |
+ kKeycodeMetaR, ShiftMask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_MENU, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_SHIFT_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeMetaR, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(ShiftMask), xkey.state); |
+ } |
+ { |
+ // Press Search with Caps Lock mask. |
+ InitXKeyEvent(ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN, |
+ kKeycodeSuperL, LockMask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_LWIN, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_CAPS_LOCK_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeSuperL, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(LockMask), xkey.state); |
+ } |
+ { |
+ // Release Search with Caps Lock mask. |
+ InitXKeyEvent(ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN, |
+ kKeycodeSuperL, LockMask | Mod4Mask, &xev); |
+ xev.type = KeyRelease; |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_LWIN, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_CAPS_LOCK_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeSuperL, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(LockMask | Mod4Mask), xkey.state); |
+ } |
+ { |
+ // Press Shift+Ctrl+Alt+Search+A |
+ InitXKeyEvent(ui::VKEY_A, |
+ ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, |
+ kKeycodeA, |
+ ShiftMask | ControlMask | Mod1Mask | Mod4Mask, |
+ &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_A, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, |
+ keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeA, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>( |
+ ShiftMask | ControlMask | Mod1Mask | Mod4Mask), xkey.state); |
+ } |
+} |
+ |
+TEST(KeyRewriterTest, TestRewriteModifiersDisableSome) { |
+ XEvent xev; |
+ Display* display = ui::GetXDisplay(); |
+ |
+ const unsigned int kKeycodeSuperL = XKeysymToKeycode(display, XK_Super_L); |
Daniel Erat
2012/05/23 16:37:32
nit: KeyCode (also for other unsigned ints in this
Yusuke Sato
2012/05/24 08:24:42
Done.
|
+ const unsigned int kKeycodeControlL = XKeysymToKeycode(display, XK_Control_L); |
+ const unsigned int kKeycodeMetaL = XKeysymToKeycode(display, XK_Meta_L); |
+ const unsigned int kKeycodeVoidSymbol = |
+ XKeysymToKeycode(display, XK_VoidSymbol); |
+ const unsigned int kKeycodeA = XKeysymToKeycode(display, XK_a); |
+ |
+ // Disable Search and Control keys. |
+ TestingPrefService prefs; |
+ chromeos::Preferences::RegisterUserPrefs(&prefs); |
+ IntegerPrefMember search; |
+ search.Init(prefs::kLanguageXkbRemapSearchKeyTo, &prefs, NULL); |
+ search.SetValue(chromeos::input_method::kVoidKey); |
+ IntegerPrefMember control; |
+ control.Init(prefs::kLanguageXkbRemapControlKeyTo, &prefs, NULL); |
+ control.SetValue(chromeos::input_method::kVoidKey); |
+ |
+ KeyRewriter rewriter; |
+ rewriter.set_pref_service_for_testing(&prefs); |
+ { |
+ // Press left Alt with Shift. This key press shouldn't be affected by the |
+ // pref. |
+ InitXKeyEvent(ui::VKEY_MENU, ui::EF_SHIFT_DOWN, |
+ kKeycodeMetaL, ShiftMask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is not rewritten. |
+ EXPECT_EQ(ui::VKEY_MENU, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_SHIFT_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeMetaL, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(ShiftMask), xkey.state); |
+ } |
+ { |
+ // Press Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, 0, kKeycodeSuperL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_UNKNOWN + XK_VoidSymbol. |
+ EXPECT_EQ(ui::VKEY_UNKNOWN, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeVoidSymbol, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ { |
+ // Press Control. |
+ InitXKeyEvent(ui::VKEY_CONTROL, 0, kKeycodeControlL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_UNKNOWN + XK_VoidSymbol. |
+ EXPECT_EQ(ui::VKEY_UNKNOWN, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeVoidSymbol, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ { |
+ // Press Control+Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, ui::EF_CONTROL_DOWN, |
+ kKeycodeSuperL, ControlMask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_UNKNOWN + XK_VoidSymbol without any |
+ // modifiers. |
+ EXPECT_EQ(ui::VKEY_UNKNOWN, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeVoidSymbol, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ { |
+ // Press Control+Search+a. |
+ InitXKeyEvent(ui::VKEY_A, ui::EF_CONTROL_DOWN, |
+ kKeycodeA, ControlMask | Mod4Mask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_A without any modifiers. |
+ EXPECT_EQ(ui::VKEY_A, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeA, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ { |
+ // Press Control+Search+Alt+a. |
+ InitXKeyEvent(ui::VKEY_A, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, |
+ kKeycodeA, ControlMask | Mod1Mask | Mod4Mask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_A only with the Alt modifier. |
+ EXPECT_EQ(ui::VKEY_A, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_ALT_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeA, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(Mod1Mask), xkey.state); |
+ } |
+ |
+ |
+ const unsigned int kKeycodeAltL = XKeysymToKeycode(display, XK_Alt_L); |
+ const unsigned int kKeycodeB = XKeysymToKeycode(display, XK_b); |
+ |
+ // Remap Alt to Control. |
+ IntegerPrefMember alt; |
+ alt.Init(prefs::kLanguageXkbRemapAltKeyTo, &prefs, NULL); |
+ alt.SetValue(chromeos::input_method::kControlKey); |
+ { |
+ // Press left Alt. |
+ InitXKeyEvent(ui::VKEY_MENU, 0, kKeycodeAltL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_CONTROL + XK_Control_L even though the |
+ // Control key itself is disabled. |
+ EXPECT_EQ(ui::VKEY_CONTROL, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeControlL, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ { |
+ // Press Alt+b. |
+ InitXKeyEvent(ui::VKEY_B, ui::EF_ALT_DOWN, kKeycodeB, Mod1Mask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now Control+b even though the Control key itself is |
+ // disabled. |
+ EXPECT_EQ(ui::VKEY_B, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_CONTROL_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeB, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(ControlMask), xkey.state); |
+ } |
+} |
+ |
+TEST(KeyRewriterTest, TestRewriteModifiersRemapToControl) { |
+ XEvent xev; |
+ Display* display = ui::GetXDisplay(); |
+ |
+ const unsigned int kKeycodeSuperL = XKeysymToKeycode(display, XK_Super_L); |
+ const unsigned int kKeycodeControlL = XKeysymToKeycode(display, XK_Control_L); |
+ const unsigned int kKeycodeControlR = XKeysymToKeycode(display, XK_Control_R); |
+ const unsigned int kKeycodeAltL = XKeysymToKeycode(display, XK_Alt_L); |
+ const unsigned int kKeycodeAltR = XKeysymToKeycode(display, XK_Alt_R); |
+ const unsigned int kKeycodeA = XKeysymToKeycode(display, XK_A); |
+ |
+ // Remap Search to Control. |
+ TestingPrefService prefs; |
+ chromeos::Preferences::RegisterUserPrefs(&prefs); |
+ IntegerPrefMember search; |
+ search.Init(prefs::kLanguageXkbRemapSearchKeyTo, &prefs, NULL); |
+ search.SetValue(chromeos::input_method::kControlKey); |
+ |
+ KeyRewriter rewriter; |
+ rewriter.set_pref_service_for_testing(&prefs); |
+ { |
+ // Press Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, 0, kKeycodeSuperL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_CONTROL + XK_Control_L. |
+ EXPECT_EQ(ui::VKEY_CONTROL, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeControlL, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ |
+ // Remap Alt to Control too. |
+ IntegerPrefMember alt; |
+ alt.Init(prefs::kLanguageXkbRemapAltKeyTo, &prefs, NULL); |
+ alt.SetValue(chromeos::input_method::kControlKey); |
+ { |
+ // Press left Alt. |
+ InitXKeyEvent(ui::VKEY_MENU, 0, kKeycodeAltL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_CONTROL + XK_Control_L. |
+ EXPECT_EQ(ui::VKEY_CONTROL, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeControlL, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ { |
+ // Press right Alt. |
+ InitXKeyEvent(ui::VKEY_MENU, 0, kKeycodeAltR, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_CONTROL + XK_Control_R. |
+ EXPECT_EQ(ui::VKEY_CONTROL, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeControlR, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ { |
+ // Press Alt+Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, ui::EF_ALT_DOWN, |
+ kKeycodeSuperL, Mod1Mask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_CONTROL + XK_Control_L. |
+ EXPECT_EQ(ui::VKEY_CONTROL, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_CONTROL_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeControlL, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(ControlMask), xkey.state); |
+ } |
+ { |
+ // Press Control+Alt+Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, |
+ kKeycodeSuperL, ControlMask | Mod1Mask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_CONTROL + XK_Control_L. |
+ EXPECT_EQ(ui::VKEY_CONTROL, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_CONTROL_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeControlL, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(ControlMask), xkey.state); |
+ } |
+ { |
+ // Press Shift+Control+Alt+Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, |
+ ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, |
+ kKeycodeSuperL, ShiftMask | ControlMask | Mod1Mask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now Control with Shift and Control modifiers. |
+ EXPECT_EQ(ui::VKEY_CONTROL, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeControlL, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(ShiftMask | ControlMask), xkey.state); |
+ } |
+ { |
+ // Press Shift+Control+Alt+Search+A |
+ InitXKeyEvent(ui::VKEY_A, |
+ ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, |
+ kKeycodeA, ShiftMask | ControlMask | Mod1Mask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now A with Shift and Control modifiers. |
+ EXPECT_EQ(ui::VKEY_A, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeA, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(ShiftMask | ControlMask), xkey.state); |
+ } |
+} |
+ |
+TEST(KeyRewriterTest, TestRewriteModifiersRemapMany) { |
+ XEvent xev; |
+ Display* display = ui::GetXDisplay(); |
+ |
+ const unsigned int kKeycodeSuperL = XKeysymToKeycode(display, XK_Super_L); |
+ const unsigned int kKeycodeControlL = XKeysymToKeycode(display, XK_Control_L); |
+ const unsigned int kKeycodeAltL = XKeysymToKeycode(display, XK_Alt_L); |
+ const unsigned int kKeycodeMetaL = XKeysymToKeycode(display, XK_Meta_L); |
+ const unsigned int kKeycodeA = XKeysymToKeycode(display, XK_A); |
+ |
+ // Remap Search to Alt. |
+ TestingPrefService prefs; |
+ chromeos::Preferences::RegisterUserPrefs(&prefs); |
+ IntegerPrefMember search; |
+ search.Init(prefs::kLanguageXkbRemapSearchKeyTo, &prefs, NULL); |
+ search.SetValue(chromeos::input_method::kAltKey); |
+ |
+ KeyRewriter rewriter; |
+ rewriter.set_pref_service_for_testing(&prefs); |
+ { |
+ // Press Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, 0, kKeycodeSuperL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_MENU + XK_Alt_L. |
+ EXPECT_EQ(ui::VKEY_MENU, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeAltL, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ |
+ // Remap Alt to Control. |
+ IntegerPrefMember alt; |
+ alt.Init(prefs::kLanguageXkbRemapAltKeyTo, &prefs, NULL); |
+ alt.SetValue(chromeos::input_method::kControlKey); |
+ { |
+ // Press left Alt. |
+ InitXKeyEvent(ui::VKEY_MENU, 0, kKeycodeAltL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_CONTROL + XK_Control_L. |
+ EXPECT_EQ(ui::VKEY_CONTROL, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeControlL, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ |
+ // Remap Control to Search. |
+ IntegerPrefMember control; |
+ control.Init(prefs::kLanguageXkbRemapControlKeyTo, &prefs, NULL); |
+ control.SetValue(chromeos::input_method::kSearchKey); |
+ { |
+ // Press left Control. |
+ InitXKeyEvent(ui::VKEY_CONTROL, 0, kKeycodeControlL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is now VKEY_LWIN. |
+ EXPECT_EQ(ui::VKEY_LWIN, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeSuperL, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ } |
+ |
+ // Then, press all of the three. |
+ { |
+ // Press Control+Alt+Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, |
+ kKeycodeSuperL, ControlMask | Mod1Mask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ // Confirm the event is unchanged. |
+ EXPECT_EQ(ui::VKEY_MENU, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_CONTROL_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeAltL, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(ControlMask | Mod4Mask), xkey.state); |
+ } |
+ { |
+ // Press Shift+Control+Alt+Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, |
+ ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, |
+ kKeycodeSuperL, ShiftMask | ControlMask | Mod1Mask, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ EXPECT_EQ(ui::VKEY_MENU, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeMetaL, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(ShiftMask | ControlMask | Mod4Mask), |
+ xkey.state); |
+ } |
+ { |
+ // Press Shift+Control+Alt+Search+A |
+ InitXKeyEvent(ui::VKEY_A, |
+ ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, |
+ kKeycodeA, ShiftMask | ControlMask | Mod1Mask | Mod4Mask, |
+ &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ EXPECT_EQ(ui::VKEY_A, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN, |
+ keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeA, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>( |
+ ShiftMask | ControlMask | Mod1Mask | Mod4Mask), xkey.state); |
+ } |
+} |
+ |
+TEST(KeyRewriterTest, TestRewriteModifiersRemapToCapsLock) { |
+ XEvent xev; |
+ Display* display = ui::GetXDisplay(); |
+ |
+ const unsigned int kKeycodeSuperL = XKeysymToKeycode(display, XK_Super_L); |
+ const unsigned int kKeycodeCapsLock = XKeysymToKeycode(display, XK_Caps_Lock); |
+ |
+ // Remap Search to Caps Lock. |
+ TestingPrefService prefs; |
+ chromeos::Preferences::RegisterUserPrefs(&prefs); |
+ IntegerPrefMember search; |
+ search.Init(prefs::kLanguageXkbRemapSearchKeyTo, &prefs, NULL); |
+ search.SetValue(chromeos::input_method::kCapsLockKey); |
+ |
+ chromeos::input_method::MockXKeyboard xkeyboard; |
+ KeyRewriter rewriter; |
+ rewriter.set_pref_service_for_testing(&prefs); |
+ rewriter.set_xkeyboard_for_testing(&xkeyboard); |
+ EXPECT_FALSE(xkeyboard.caps_lock_is_enabled_); |
+ { |
+ // Press Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, 0, kKeycodeSuperL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ EXPECT_EQ(ui::VKEY_CAPITAL, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeCapsLock, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ // Confirm that the Caps Lock status is changed. |
+ EXPECT_TRUE(xkeyboard.caps_lock_is_enabled_); |
+ } |
+ { |
+ // Release Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN, |
+ kKeycodeSuperL, Mod4Mask | LockMask, &xev); |
+ xev.type = KeyRelease; |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ EXPECT_EQ(ui::VKEY_CAPITAL, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_CAPS_LOCK_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeCapsLock, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(LockMask), xkey.state); |
+ // Confirm that the Caps Lock status is not changed. |
+ EXPECT_TRUE(xkeyboard.caps_lock_is_enabled_); |
+ } |
+ { |
+ // Press Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, 0, kKeycodeSuperL, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ EXPECT_EQ(ui::VKEY_CAPITAL, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeCapsLock, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ // Confirm that the Caps Lock status is changed. |
+ EXPECT_FALSE(xkeyboard.caps_lock_is_enabled_); |
+ } |
+ { |
+ // Release Search. |
+ InitXKeyEvent(ui::VKEY_LWIN, ui::EF_CAPS_LOCK_DOWN, |
+ kKeycodeSuperL, Mod4Mask | LockMask, &xev); |
+ xev.type = KeyRelease; |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ EXPECT_EQ(ui::VKEY_CAPITAL, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_CAPS_LOCK_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeCapsLock, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(LockMask), xkey.state); |
+ // Confirm that the Caps Lock status is not changed. |
+ EXPECT_FALSE(xkeyboard.caps_lock_is_enabled_); |
+ } |
+ { |
+ // Press Caps Lock (on an external keyboard). |
+ InitXKeyEvent(ui::VKEY_CAPITAL, 0, kKeycodeCapsLock, 0U, &xev); |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ EXPECT_EQ(ui::VKEY_CAPITAL, keyevent.key_code()); |
+ EXPECT_EQ(0, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeCapsLock, xkey.keycode); |
+ EXPECT_EQ(0U, xkey.state); |
+ // Confirm that calling RewriteForTesting() does not change the state of |
+ // |xkeyboard|. In this case, X Window system itself should change the |
+ // Caps Lock state, not ash::KeyRewriter. |
+ EXPECT_FALSE(xkeyboard.caps_lock_is_enabled_); |
+ } |
+ { |
+ // Press Caps Lock (on an external keyboard). |
+ InitXKeyEvent(ui::VKEY_CAPITAL, ui::EF_CAPS_LOCK_DOWN, |
+ kKeycodeCapsLock, LockMask, &xev); |
+ xev.type = KeyRelease; |
+ aura::KeyEvent keyevent(&xev, false /* is_char */); |
+ rewriter.RewriteForTesting(&keyevent); |
+ EXPECT_EQ(ui::VKEY_CAPITAL, keyevent.key_code()); |
+ EXPECT_EQ(ui::EF_CAPS_LOCK_DOWN, keyevent.flags()); |
+ const XKeyEvent& xkey = keyevent.native_event()->xkey; |
+ EXPECT_EQ(kKeycodeCapsLock, xkey.keycode); |
+ EXPECT_EQ(static_cast<unsigned int>(LockMask), xkey.state); |
+ EXPECT_FALSE(xkeyboard.caps_lock_is_enabled_); |
+ } |
+} |
#endif // OS_CHROMEOS |