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

Side by Side Diff: chrome/browser/ui/ash/event_rewriter.cc

Issue 11885015: Merge 165503 (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1271/src/
Patch Set: Created 7 years, 11 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/ash/event_rewriter.h" 5 #include "chrome/browser/ui/ash/event_rewriter.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "ash/shell.h" 9 #include "ash/shell.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "chrome/browser/prefs/pref_service.h" 12 #include "chrome/browser/prefs/pref_service.h"
13 #include "chrome/browser/profiles/profile_manager.h" 13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "ui/aura/root_window.h" 14 #include "ui/aura/root_window.h"
15 #include "ui/base/events/event.h" 15 #include "ui/base/events/event.h"
16 #include "ui/base/keycodes/keyboard_code_conversion.h" 16 #include "ui/base/keycodes/keyboard_code_conversion.h"
17 17
18 #if defined(OS_CHROMEOS) 18 #if defined(OS_CHROMEOS)
19 #include <X11/extensions/XInput2.h> 19 #include <X11/extensions/XInput2.h>
20 #include <X11/keysym.h> 20 #include <X11/keysym.h>
21 #include <X11/XF86keysym.h> 21 #include <X11/XF86keysym.h>
22 #include <X11/Xlib.h> 22 #include <X11/Xlib.h>
23 23
24 // Get rid of a macro from Xlib.h that conflicts with OwnershipService class. 24 // Get rid of a macro from Xlib.h that conflicts with OwnershipService class.
25 #undef Status 25 #undef Status
26 26
27 #include "base/chromeos/chromeos_version.h" 27 #include "base/chromeos/chromeos_version.h"
28 #include "base/command_line.h"
28 #include "chrome/browser/chromeos/input_method/input_method_manager.h" 29 #include "chrome/browser/chromeos/input_method/input_method_manager.h"
29 #include "chrome/browser/chromeos/input_method/xkeyboard.h" 30 #include "chrome/browser/chromeos/input_method/xkeyboard.h"
30 #include "chrome/browser/chromeos/login/base_login_display_host.h" 31 #include "chrome/browser/chromeos/login/base_login_display_host.h"
31 #include "chrome/browser/chromeos/login/user_manager.h" 32 #include "chrome/browser/chromeos/login/user_manager.h"
32 #include "chrome/browser/chromeos/xinput_hierarchy_changed_event_listener.h" 33 #include "chrome/browser/chromeos/xinput_hierarchy_changed_event_listener.h"
34 #include "chrome/common/chrome_switches.h"
33 #include "chrome/common/pref_names.h" 35 #include "chrome/common/pref_names.h"
34 #include "ui/base/keycodes/keyboard_code_conversion_x.h" 36 #include "ui/base/keycodes/keyboard_code_conversion_x.h"
35 #include "ui/base/x/x11_util.h" 37 #include "ui/base/x/x11_util.h"
36 38
37 using chromeos::input_method::InputMethodManager; 39 using chromeos::input_method::InputMethodManager;
38 #endif 40 #endif
39 41
40 namespace { 42 namespace {
41 43
42 const int kBadDeviceId = -1; 44 const int kBadDeviceId = -1;
(...skipping 16 matching lines...) Expand all
59 { XK_Control_L, XK_Control_R, XK_Control_L, XK_Control_R }}, 61 { XK_Control_L, XK_Control_R, XK_Control_L, XK_Control_R }},
60 { chromeos::input_method::kAltKey, ui::EF_ALT_DOWN, Mod1Mask, 62 { chromeos::input_method::kAltKey, ui::EF_ALT_DOWN, Mod1Mask,
61 ui::VKEY_MENU, { XK_Alt_L, XK_Alt_R, XK_Meta_L, XK_Meta_R }}, 63 ui::VKEY_MENU, { XK_Alt_L, XK_Alt_R, XK_Meta_L, XK_Meta_R }},
62 { chromeos::input_method::kVoidKey, 0, 0U, ui::VKEY_UNKNOWN, 64 { chromeos::input_method::kVoidKey, 0, 0U, ui::VKEY_UNKNOWN,
63 { XK_VoidSymbol, XK_VoidSymbol, XK_VoidSymbol, XK_VoidSymbol }}, 65 { XK_VoidSymbol, XK_VoidSymbol, XK_VoidSymbol, XK_VoidSymbol }},
64 { chromeos::input_method::kCapsLockKey, 0, 0U, ui::VKEY_CAPITAL, 66 { chromeos::input_method::kCapsLockKey, 0, 0U, ui::VKEY_CAPITAL,
65 { XK_Caps_Lock, XK_Caps_Lock, XK_Caps_Lock, XK_Caps_Lock }}, 67 { XK_Caps_Lock, XK_Caps_Lock, XK_Caps_Lock, XK_Caps_Lock }},
66 }; 68 };
67 69
68 const ModifierRemapping* kModifierRemappingCtrl = &kModifierRemappings[1]; 70 const ModifierRemapping* kModifierRemappingCtrl = &kModifierRemappings[1];
71 const ModifierRemapping* kModifierRemappingCapsLock = &kModifierRemappings[4];
69 72
70 // A structure for converting |native_modifier| to a pair of |flag| and 73 // A structure for converting |native_modifier| to a pair of |flag| and
71 // |pref_name|. 74 // |pref_name|.
72 const struct ModifierFlagToPrefName { 75 const struct ModifierFlagToPrefName {
73 unsigned int native_modifier; 76 unsigned int native_modifier;
74 int flag; 77 int flag;
75 const char* pref_name; 78 const char* pref_name;
76 } kModifierFlagToPrefName[] = { 79 } kModifierFlagToPrefName[] = {
77 // TODO(yusukes): When the device has a Chrome keyboard (i.e. the one without 80 // TODO(yusukes): When the device has a Chrome keyboard (i.e. the one without
78 // Caps Lock), we should not check kLanguageRemapCapsLockKeyTo. 81 // Caps Lock), we should not check kLanguageRemapCapsLockKeyTo.
(...skipping 26 matching lines...) Expand all
105 case XK_Meta_R: 108 case XK_Meta_R:
106 case XK_Shift_R: 109 case XK_Shift_R:
107 case XK_Super_R: 110 case XK_Super_R:
108 return true; 111 return true;
109 default: 112 default:
110 break; 113 break;
111 } 114 }
112 return false; 115 return false;
113 } 116 }
114 117
115 bool ShouldRemapCapsLock() { 118 bool HasChromeOSKeyboard() {
116 // Since both German Neo2 XKB layout and Caps Lock depend on Mod3Mask, it's 119 return CommandLine::ForCurrentProcess()->HasSwitch(
117 // not possible to make both features work. For now, we don't remap Mod3Mask 120 switches::kHasChromeOSKeyboard);
118 // when Neo2 is in use. 121 }
122
123 bool IsMod3UsedByCurrentInputMethod() {
124 // Since both German Neo2 XKB layout and Caps Lock depend on Mod3Mask,
125 // it's not possible to make both features work. For now, we don't remap
126 // Mod3Mask when Neo2 is in use.
119 // TODO(yusukes): Remove the restriction. 127 // TODO(yusukes): Remove the restriction.
120 return InputMethodManager::GetInstance()->GetCurrentInputMethod().id() != 128 return InputMethodManager::GetInstance()->GetCurrentInputMethod().id() ==
121 kNeo2LayoutId; 129 kNeo2LayoutId;
122 } 130 }
123 #endif 131 #endif
124 132
125 const PrefService* GetPrefService() { 133 const PrefService* GetPrefService() {
126 Profile* profile = ProfileManager::GetDefaultProfile(); 134 Profile* profile = ProfileManager::GetDefaultProfile();
127 if (profile) 135 if (profile)
128 return profile->GetPrefs(); 136 return profile->GetPrefs();
129 return NULL; 137 return NULL;
130 } 138 }
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 if (chromeos::UserManager::Get()->IsLoggedInAsGuest() && 395 if (chromeos::UserManager::Get()->IsLoggedInAsGuest() &&
388 chromeos::BaseLoginDisplayHost::default_host()) { 396 chromeos::BaseLoginDisplayHost::default_host()) {
389 return; 397 return;
390 } 398 }
391 399
392 const PrefService* pref_service = 400 const PrefService* pref_service =
393 pref_service_ ? pref_service_ : GetPrefService(); 401 pref_service_ ? pref_service_ : GetPrefService();
394 if (!pref_service) 402 if (!pref_service)
395 return; 403 return;
396 404
397 const bool skip_mod3 = !ShouldRemapCapsLock(); 405 // When a Chrome OS keyboard is available, the configuration UI for Caps Lock
406 // is not shown. Therefore, ignore the kLanguageRemapCapsLockKeyTo syncable
407 // pref. If Mod3 is in use, don't check the pref either.
408 const bool skip_mod3 =
409 HasChromeOSKeyboard() || IsMod3UsedByCurrentInputMethod();
410
398 for (size_t i = 0; i < arraysize(kModifierFlagToPrefName); ++i) { 411 for (size_t i = 0; i < arraysize(kModifierFlagToPrefName); ++i) {
399 if (skip_mod3 && 412 if (skip_mod3 &&
400 (kModifierFlagToPrefName[i].native_modifier == Mod3Mask)) { 413 (kModifierFlagToPrefName[i].native_modifier == Mod3Mask)) {
401 continue; 414 continue;
402 } 415 }
403 if (original_native_modifiers & 416 if (original_native_modifiers &
404 kModifierFlagToPrefName[i].native_modifier) { 417 kModifierFlagToPrefName[i].native_modifier) {
405 const ModifierRemapping* remapped_key = 418 const ModifierRemapping* remapped_key =
406 GetRemappedKey(kModifierFlagToPrefName[i].pref_name, *pref_service); 419 GetRemappedKey(kModifierFlagToPrefName[i].pref_name, *pref_service);
407 // Rewrite Command-L/R key presses on an Apple keyboard to Control-L/R. 420 // Rewrite Command-L/R key presses on an Apple keyboard to Control-L/R.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 DCHECK_EQ(chromeos::input_method::kControlKey, 468 DCHECK_EQ(chromeos::input_method::kControlKey,
456 kModifierRemappingCtrl->remap_to); 469 kModifierRemappingCtrl->remap_to);
457 470
458 XEvent* xev = event->native_event(); 471 XEvent* xev = event->native_event();
459 XKeyEvent* xkey = &(xev->xkey); 472 XKeyEvent* xkey = &(xev->xkey);
460 KeySym keysym = XLookupKeysym(xkey, 0); 473 KeySym keysym = XLookupKeysym(xkey, 0);
461 474
462 ui::KeyboardCode remapped_keycode = event->key_code(); 475 ui::KeyboardCode remapped_keycode = event->key_code();
463 KeyCode remapped_native_keycode = xkey->keycode; 476 KeyCode remapped_native_keycode = xkey->keycode;
464 477
465 const bool skip_mod3 = !ShouldRemapCapsLock();
466
467 // First, remap |keysym|. 478 // First, remap |keysym|.
468 const char* pref_name = NULL; 479 const ModifierRemapping* remapped_key = NULL;
469 switch (keysym) { 480 switch (keysym) {
470 // XF86XK_Launch7 (F16) with Mod3Mask is sent when Caps Lock is pressed. 481 // On Chrome OS, XF86XK_Launch7 (F16) with Mod3Mask is sent when Caps Lock
482 // is pressed (with one exception: when IsMod3UsedByCurrentInputMethod() is
483 // true, the key generates XK_ISO_Level3_Shift with Mod3Mask, not
484 // XF86XK_Launch7).
471 case XF86XK_Launch7: 485 case XF86XK_Launch7:
472 pref_name = skip_mod3 ? NULL : prefs::kLanguageRemapCapsLockKeyTo; 486 // When a Chrome OS keyboard is available, the configuration UI for Caps
487 // Lock is not shown. Therefore, ignore the kLanguageRemapCapsLockKeyTo
488 // syncable pref.
489 if (HasChromeOSKeyboard())
490 remapped_key = kModifierRemappingCapsLock;
491 else
492 remapped_key =
493 GetRemappedKey(prefs::kLanguageRemapCapsLockKeyTo, *pref_service);
473 break; 494 break;
474 case XK_Super_L: 495 case XK_Super_L:
475 case XK_Super_R: 496 case XK_Super_R:
476 pref_name = prefs::kLanguageRemapSearchKeyTo; 497 // Rewrite Command-L/R key presses on an Apple keyboard to Control-L/R.
498 if (IsAppleKeyboard())
499 remapped_key = kModifierRemappingCtrl;
500 else
501 remapped_key =
502 GetRemappedKey(prefs::kLanguageRemapSearchKeyTo, *pref_service);
477 break; 503 break;
478 case XK_Control_L: 504 case XK_Control_L:
479 case XK_Control_R: 505 case XK_Control_R:
480 pref_name = prefs::kLanguageRemapControlKeyTo; 506 remapped_key =
507 GetRemappedKey(prefs::kLanguageRemapControlKeyTo, *pref_service);
481 break; 508 break;
482 case XK_Alt_L: 509 case XK_Alt_L:
483 case XK_Alt_R: 510 case XK_Alt_R:
484 case XK_Meta_L: 511 case XK_Meta_L:
485 case XK_Meta_R: 512 case XK_Meta_R:
486 pref_name = prefs::kLanguageRemapAltKeyTo; 513 remapped_key =
514 GetRemappedKey(prefs::kLanguageRemapAltKeyTo, *pref_service);
487 break; 515 break;
488 default: 516 default:
489 break; 517 break;
490 } 518 }
491 if (pref_name) { 519
492 const ModifierRemapping* remapped_key = 520 if (remapped_key) {
493 GetRemappedKey(pref_name, *pref_service); 521 remapped_keycode = remapped_key->keycode;
494 // Rewrite Command-L/R key presses on an Apple keyboard to Control-L/R. 522 const size_t level = (event->IsShiftDown() ? (1 << 1) : 0) +
495 if (IsAppleKeyboard() && (keysym == XK_Super_L || keysym == XK_Super_R)) 523 (IsRight(keysym) ? (1 << 0) : 0);
496 remapped_key = kModifierRemappingCtrl; 524 const KeySym native_keysym = remapped_key->native_keysyms[level];
497 if (remapped_key) { 525 remapped_native_keycode = NativeKeySymToNativeKeycode(native_keysym);
498 remapped_keycode = remapped_key->keycode;
499 const size_t level = (event->IsShiftDown() ? (1 << 1) : 0) +
500 (IsRight(keysym) ? (1 << 0) : 0);
501 const KeySym native_keysym = remapped_key->native_keysyms[level];
502 remapped_native_keycode = NativeKeySymToNativeKeycode(native_keysym);
503 }
504 } 526 }
505 527
506 // Next, remap modifier bits. 528 // Next, remap modifier bits.
507 int remapped_flags = 0; 529 int remapped_flags = 0;
508 unsigned int remapped_native_modifiers = 0U; 530 unsigned int remapped_native_modifiers = 0U;
509 GetRemappedModifierMasks(event->flags(), xkey->state, 531 GetRemappedModifierMasks(event->flags(), xkey->state,
510 &remapped_flags, &remapped_native_modifiers); 532 &remapped_flags, &remapped_native_modifiers);
511 533
512 // Toggle Caps Lock if the remapped key is ui::VKEY_CAPITAL, but do nothing if 534 // Toggle Caps Lock if the remapped key is ui::VKEY_CAPITAL, but do nothing if
513 // the original key is ui::VKEY_CAPITAL (i.e. a Caps Lock key on an external 535 // the original key is ui::VKEY_CAPITAL (i.e. a Caps Lock key on an external
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 const DeviceType type = EventRewriter::GetDeviceType(device_name); 749 const DeviceType type = EventRewriter::GetDeviceType(device_name);
728 if (type == kDeviceAppleKeyboard) { 750 if (type == kDeviceAppleKeyboard) {
729 VLOG(1) << "Apple keyboard '" << device_name << "' connected: " 751 VLOG(1) << "Apple keyboard '" << device_name << "' connected: "
730 << "id=" << device_id; 752 << "id=" << device_id;
731 } 753 }
732 // Always overwrite the existing device_id since the X server may reuse a 754 // Always overwrite the existing device_id since the X server may reuse a
733 // device id for an unattached device. 755 // device id for an unattached device.
734 device_id_to_type_[device_id] = type; 756 device_id_to_type_[device_id] = type;
735 return type; 757 return type;
736 } 758 }
OLDNEW
« no previous file with comments | « chrome/browser/resources/options/chromeos/keyboard_overlay.js ('k') | chrome/browser/ui/ash/event_rewriter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698