| 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..6c5720fce7589a39e5f08c590c005681834708d2 100644
|
| --- a/chrome/browser/ui/views/ash/key_rewriter.cc
|
| +++ b/chrome/browser/ui/views/ash/key_rewriter.cc
|
| @@ -179,14 +179,16 @@ void KeyRewriter::RewriteForTesting(aura::KeyEvent* event) {
|
|
|
| ash::KeyRewriterDelegate::Action KeyRewriter::RewriteOrFilterKeyEvent(
|
| aura::KeyEvent* 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;
|
| - }
|
| - Rewrite(event);
|
| - return kActionRewrite; // Do not drop the event.
|
| + if (event->HasNativeEvent())
|
| + Rewrite(event);
|
| + return ash::KeyRewriterDelegate::ACTION_REWRITE_EVENT;
|
| +}
|
| +
|
| +ash::KeyRewriterDelegate::Action KeyRewriter::RewriteOrFilterLocatedEvent(
|
| + aura::LocatedEvent* event) {
|
| + if (event->HasNativeEvent())
|
| + RewriteLocatedEvent(event);
|
| + return ash::KeyRewriterDelegate::ACTION_REWRITE_EVENT;
|
| }
|
|
|
| void KeyRewriter::OnKeyboardMappingChanged(const aura::RootWindow* root) {
|
| @@ -353,6 +355,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 +431,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 +468,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 +623,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,
|
|
|