Chromium Code Reviews| Index: chrome/browser/ui/views/ash/key_rewriter.cc |
| diff --git a/chrome/browser/ui/views/ash/key_rewriter.cc b/chrome/browser/ui/views/ash/key_rewriter.cc |
| index 737e6099cb2fc3c5f099a817843279794d679228..c5e8340245d885f20930882409744966397a4504 100644 |
| --- a/chrome/browser/ui/views/ash/key_rewriter.cc |
| +++ b/chrome/browser/ui/views/ash/key_rewriter.cc |
| @@ -189,6 +189,18 @@ ash::KeyRewriterDelegate::Action KeyRewriter::RewriteOrFilterKeyEvent( |
| return kActionRewrite; // Do not drop the event. |
| } |
| +ash::KeyRewriterDelegate::Action KeyRewriter::RewriteOrFilterLocatedEvent( |
| + aura::LocatedEvent* event) { |
| + const ash::KeyRewriterDelegate::Action kActionRewrite = |
| + ash::KeyRewriterDelegate::ACTION_REWRITE_EVENT; |
| + if (!event->HasNativeEvent()) { |
| + // Do not handle a fabricated event generated by tests. |
| + return kActionRewrite; |
| + } |
| + RewriteLocatedEvent(event); |
| + return kActionRewrite; |
|
Daniel Erat
2012/07/09 18:18:28
nit: just simplify this to three lines?
... KeyRe
Yusuke Sato
2012/07/09 20:36:50
Done.
|
| +} |
| + |
| void KeyRewriter::OnKeyboardMappingChanged(const aura::RootWindow* root) { |
| #if defined(OS_CHROMEOS) |
| RefreshKeycodes(); |
| @@ -353,6 +365,54 @@ bool KeyRewriter::IsAppleKeyboard() const { |
| return type == kDeviceAppleKeyboard; |
| } |
| +void KeyRewriter::GetRemappedModifierMasks( |
| + int original_flags, |
| + unsigned int original_native_modifiers, |
| + int* remapped_flags, |
| + unsigned int* remapped_native_modifiers) const { |
| +#if defined(OS_CHROMEOS) |
| + // TODO(glotov): remove the following condition when we do not restart chrome |
| + // when user logs in as guest. See Rewrite() for details. |
| + if (chromeos::UserManager::Get()->IsLoggedInAsGuest() && |
| + chromeos::BaseLoginDisplayHost::default_host()) { |
| + return; |
| + } |
| + |
| + const PrefService* pref_service = |
| + pref_service_ ? pref_service_ : GetPrefService(); |
| + if (!pref_service) |
| + return; |
| + |
| + for (size_t i = 0; i < arraysize(kModifierFlagToPrefName); ++i) { |
| + if (original_native_modifiers & |
| + kModifierFlagToPrefName[i].native_modifier) { |
| + const ModifierRemapping* remapped_key = |
| + GetRemappedKey(kModifierFlagToPrefName[i].pref_name, *pref_service); |
| + // Rewrite Command-L/R key presses on an Apple keyboard to Control-L/R. |
| + if (IsAppleKeyboard() && |
| + (kModifierFlagToPrefName[i].native_modifier == Mod4Mask)) { |
| + remapped_key = kModifierRemappingCtrl; |
| + } |
| + if (remapped_key) { |
| + *remapped_flags |= remapped_key->flag; |
| + *remapped_native_modifiers |= remapped_key->native_modifier; |
| + } else { |
| + *remapped_flags |= kModifierFlagToPrefName[i].flag; |
| + *remapped_native_modifiers |= |
| + kModifierFlagToPrefName[i].native_modifier; |
| + } |
| + } |
| + } |
| + |
| + *remapped_flags = |
| + (original_flags & ~(ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)) | |
| + *remapped_flags; |
| + *remapped_native_modifiers = |
| + (original_native_modifiers & ~(Mod4Mask | ControlMask | Mod1Mask)) | |
| + *remapped_native_modifiers; |
| +#endif |
| +} |
| + |
| bool KeyRewriter::RewriteModifiers(aura::KeyEvent* event) { |
| // Do nothing if we have just logged in as guest but have not restarted chrome |
| // process yet (so we are still on the login screen). In this situations we |
| @@ -381,8 +441,6 @@ bool KeyRewriter::RewriteModifiers(aura::KeyEvent* event) { |
| ui::KeyboardCode remapped_keycode = event->key_code(); |
| KeyCode remapped_native_keycode = xkey->keycode; |
| - int remapped_flags = 0; |
| - unsigned int remapped_native_modifiers = 0U; |
| // First, remap |keysym|. |
| const char* pref_name = NULL; |
| @@ -420,30 +478,10 @@ bool KeyRewriter::RewriteModifiers(aura::KeyEvent* event) { |
| } |
| // Next, remap modifier bits. |
| - for (size_t i = 0; i < arraysize(kModifierFlagToPrefName); ++i) { |
| - if (xkey->state & kModifierFlagToPrefName[i].native_modifier) { |
| - const ModifierRemapping* remapped_key = |
| - GetRemappedKey(kModifierFlagToPrefName[i].pref_name, *pref_service); |
| - // Rewrite Command-L/R key presses on an Apple keyboard to Control-L/R. |
| - if (IsAppleKeyboard() && |
| - (kModifierFlagToPrefName[i].native_modifier == Mod4Mask)) { |
| - remapped_key = kModifierRemappingCtrl; |
| - } |
| - if (remapped_key) { |
| - remapped_flags |= remapped_key->flag; |
| - remapped_native_modifiers |= remapped_key->native_modifier; |
| - } else { |
| - remapped_flags |= kModifierFlagToPrefName[i].flag; |
| - remapped_native_modifiers |= kModifierFlagToPrefName[i].native_modifier; |
| - } |
| - } |
| - } |
| - |
| - remapped_flags = (event->flags() & ~(ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN)) | |
| - remapped_flags; |
| - remapped_native_modifiers = |
| - (xkey->state & ~(Mod4Mask | ControlMask | Mod1Mask)) | |
| - remapped_native_modifiers; |
| + int remapped_flags = 0; |
| + unsigned int remapped_native_modifiers = 0U; |
| + GetRemappedModifierMasks(event->flags(), xkey->state, |
| + &remapped_flags, &remapped_native_modifiers); |
| // Toggle Caps Lock if the remapped key is ui::VKEY_CAPITAL, but do nothing if |
| // the original key is ui::VKEY_CAPITAL (i.e. a Caps Lock key on an external |
| @@ -595,6 +633,42 @@ bool KeyRewriter::RewriteBackspaceAndArrowKeys(aura::KeyEvent* event) { |
| return rewritten; |
| } |
| +void KeyRewriter::RewriteLocatedEvent(aura::LocatedEvent* event) { |
| +#if defined(OS_CHROMEOS) |
| + XEvent* xevent = event->native_event(); |
| + if (!xevent || xevent->type != GenericEvent) |
| + return; |
| + |
| + XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data); |
| + if (xievent->evtype != XI_ButtonPress && xievent->evtype != XI_ButtonRelease) |
| + return; |
| + |
| + // First, remap modifier masks. |
| + int remapped_flags = 0; |
| + unsigned int remapped_native_modifiers = 0U; |
| + GetRemappedModifierMasks(event->flags(), xievent->mods.effective, |
| + &remapped_flags, &remapped_native_modifiers); |
| + xievent->mods.effective = remapped_native_modifiers; |
| + |
| + // Then, remap Alt+Button1 to Button3. |
| + if ((xievent->mods.effective & Mod1Mask) && xievent->detail == 1) { |
| + xievent->mods.effective &= ~Mod1Mask; |
| + xievent->detail = 3; |
| + if (xievent->evtype == XI_ButtonRelease) { |
| + // On the release clear the left button from the existing state and the |
| + // mods, and set the right button. |
| + XISetMask(xievent->buttons.mask, 3); |
| + XIClearMask(xievent->buttons.mask, 1); |
| + xievent->mods.effective &= ~Button1Mask; |
| + } |
| + } |
| + |
| + event->set_flags(ui::EventFlagsFromNative(xevent)); |
| +#else |
| + // TODO(yusukes): Support Ash on other platforms if needed. |
| +#endif |
| +} |
| + |
| void KeyRewriter::OverwriteEvent(aura::KeyEvent* event, |
| unsigned int new_native_keycode, |
| unsigned int new_native_state, |