Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2991)

Unified Diff: chrome/browser/ui/views/ash/key_rewriter_unittest.cc

Issue 10383301: Move modifier remapping code from X to Ash (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698