Chromium Code Reviews| Index: chrome/browser/ui/ash/event_rewriter.cc |
| diff --git a/chrome/browser/ui/ash/event_rewriter.cc b/chrome/browser/ui/ash/event_rewriter.cc |
| index 7c567a126d7d2796a9ba885f4cf0cd76f43e3f96..759bc0c51b44ae4d45a4e8bf00334affa42fc1e3 100644 |
| --- a/chrome/browser/ui/ash/event_rewriter.cc |
| +++ b/chrome/browser/ui/ash/event_rewriter.cc |
| @@ -143,6 +143,7 @@ const PrefService* GetPrefService() { |
| EventRewriter::EventRewriter() |
| : last_device_id_(kBadDeviceId), |
| #if defined(OS_CHROMEOS) |
| + drop_search_key_release_(false), |
| xkeyboard_(NULL), |
| #endif |
| pref_service_(NULL) { |
| @@ -204,7 +205,7 @@ void EventRewriter::RewriteForTesting(ui::KeyEvent* event) { |
| ash::EventRewriterDelegate::Action EventRewriter::RewriteOrFilterKeyEvent( |
| ui::KeyEvent* event) { |
| if (event->HasNativeEvent()) |
| - Rewrite(event); |
| + return Rewrite(event); |
| return ash::EventRewriterDelegate::ACTION_REWRITE_EVENT; |
| } |
| @@ -295,6 +296,18 @@ void EventRewriter::RefreshKeycodes() { |
| kp_8_xkeycode_ = XKeysymToKeycode(display, XK_KP_8); |
| kp_9_xkeycode_ = XKeysymToKeycode(display, XK_KP_9); |
| kp_decimal_xkeycode_ = XKeysymToKeycode(display, XK_KP_Decimal); |
| + f1_xkeycode_ = XKeysymToKeycode(display, XK_F1); |
| + f2_xkeycode_ = XKeysymToKeycode(display, XK_F2); |
| + f3_xkeycode_ = XKeysymToKeycode(display, XK_F3); |
| + f4_xkeycode_ = XKeysymToKeycode(display, XK_F4); |
| + f5_xkeycode_ = XKeysymToKeycode(display, XK_F5); |
| + f6_xkeycode_ = XKeysymToKeycode(display, XK_F6); |
| + f7_xkeycode_ = XKeysymToKeycode(display, XK_F7); |
| + f8_xkeycode_ = XKeysymToKeycode(display, XK_F8); |
| + f9_xkeycode_ = XKeysymToKeycode(display, XK_F9); |
| + f10_xkeycode_ = XKeysymToKeycode(display, XK_F10); |
| + f11_xkeycode_ = XKeysymToKeycode(display, XK_F11); |
| + f12_xkeycode_ = XKeysymToKeycode(display, XK_F12); |
| } |
| KeyCode EventRewriter::NativeKeySymToNativeKeycode(KeySym keysym) { |
| @@ -356,17 +369,20 @@ KeyCode EventRewriter::NativeKeySymToNativeKeycode(KeySym keysym) { |
| } |
| #endif |
| -void EventRewriter::Rewrite(ui::KeyEvent* event) { |
| +ash::EventRewriterDelegate::Action EventRewriter::Rewrite(ui::KeyEvent* event) { |
| #if defined(OS_CHROMEOS) |
| // Do not rewrite an event sent by ui_controls::SendKeyPress(). See |
| // crbug.com/136465. |
| if (event->native_event()->xkey.send_event) |
| - return; |
| + return ash::EventRewriterDelegate::ACTION_REWRITE_EVENT; |
| + |
| + if (DropSearchKey(event)) |
| + return ash::EventRewriterDelegate::ACTION_DROP_EVENT; |
| #endif |
| RewriteModifiers(event); |
| RewriteNumPadKeys(event); |
| RewriteBackspaceAndArrowKeys(event); |
| - // TODO(yusukes): Implement crosbug.com/27167 (allow sending function keys). |
| + return ash::EventRewriterDelegate::ACTION_REWRITE_EVENT; |
| } |
| bool EventRewriter::IsAppleKeyboard() const { |
| @@ -638,43 +654,82 @@ bool EventRewriter::RewriteNumPadKeys(ui::KeyEvent* event) { |
| bool EventRewriter::RewriteBackspaceAndArrowKeys(ui::KeyEvent* event) { |
| bool rewritten = false; |
| #if defined(OS_CHROMEOS) |
| + const PrefService* pref_service = |
| + pref_service_ ? pref_service_ : GetPrefService(); |
| + |
| + const bool search_as_function_key = pref_service && |
|
Yusuke Sato
2012/11/26 07:58:12
please do either of the following: 1) check the co
danakj
2012/11/26 17:20:16
I'll check for ChromeOS keyboard flag here, thanks
danakj
2012/11/26 19:36:26
Okay, after the explanation of HasChromeOSKeyboard
|
| + pref_service->GetBoolean(prefs::kLanguageSearchKeyActsAsFunctionKey); |
| + |
| XEvent* xev = event->native_event(); |
| XKeyEvent* xkey = &(xev->xkey); |
| - |
| const KeySym keysym = XLookupKeysym(xkey, 0); |
| - if (keysym == XK_BackSpace && (xkey->state & Mod1Mask)) { |
| - // Remap Alt+Backspace to Delete. |
| + |
| + if (!search_as_function_key && |
| + keysym == XK_BackSpace && (xkey->state & Mod1Mask)) { |
| + // Without Search as Function key: Remap Alt+Backspace to Delete. |
| OverwriteEvent(event, delete_xkeycode_, xkey->state & ~Mod1Mask, |
| ui::VKEY_DELETE, event->flags() & ~ui::EF_ALT_DOWN); |
| rewritten = true; |
| - } else if (keysym == XK_Up && |
| + } else if (search_as_function_key && |
| + keysym == XK_BackSpace && (xkey->state & Mod4Mask)) { |
| + // With Search as Function key: Remap Search+Backspace to Delete. |
| + OverwriteEvent(event, delete_xkeycode_, xkey->state & ~Mod4Mask, |
| + ui::VKEY_DELETE, event->flags()); |
| + rewritten = true; |
| + } else if (!search_as_function_key && keysym == XK_Up && |
| (xkey->state & ControlMask) && (xkey->state & Mod1Mask)) { |
| - // Remap Ctrl+Alt+Up to Home. |
| + // Without Search as Function key: Remap Ctrl+Alt+Up to Home. |
| OverwriteEvent(event, |
| home_xkeycode_, |
| xkey->state & ~(Mod1Mask | ControlMask), |
| ui::VKEY_HOME, |
| event->flags() & ~(ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN)); |
| rewritten = true; |
| - } else if (keysym == XK_Up && (xkey->state & Mod1Mask)) { |
| - // Remap Alt+Up to Prior (aka PageUp). |
| + } else if (search_as_function_key && |
| + keysym == XK_Left && (xkey->state & Mod4Mask)) { |
| + // With Search as Function key: Remap Search+Left to Home. |
| + OverwriteEvent(event, home_xkeycode_, xkey->state & ~Mod4Mask, |
| + ui::VKEY_HOME, event->flags()); |
| + rewritten = true; |
| + } else if (!search_as_function_key && |
| + keysym == XK_Up && (xkey->state & Mod1Mask)) { |
| + // Without Search as Function key: Remap Alt+Up to Prior (aka PageUp). |
| OverwriteEvent(event, prior_xkeycode_, xkey->state & ~Mod1Mask, |
| - ui::VKEY_PRIOR, event->flags() & ~ui::EF_ALT_DOWN); |
| + ui::VKEY_PRIOR, event->flags() & ~ui::EF_ALT_DOWN); |
| rewritten = true; |
| - } else if (keysym == XK_Down && |
| + } else if (search_as_function_key && |
| + keysym == XK_Up && (xkey->state & Mod4Mask)) { |
| + // With Search as Function key: Remap Search+Up to Prior (aka PageUp). |
| + OverwriteEvent(event, prior_xkeycode_, xkey->state & ~Mod4Mask, |
| + ui::VKEY_PRIOR, event->flags()); |
| + rewritten = true; |
| + } else if (!search_as_function_key && keysym == XK_Down && |
| (xkey->state & ControlMask) && (xkey->state & Mod1Mask)) { |
| - // Remap Ctrl+Alt+Down to End. |
| + // Without Search as Function key: Remap Ctrl+Alt+Down to End. |
| OverwriteEvent(event, |
| end_xkeycode_, |
| xkey->state & ~(Mod1Mask | ControlMask), |
| ui::VKEY_END, |
| event->flags() & ~(ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN)); |
| rewritten = true; |
| - } else if (keysym == XK_Down && (xkey->state & Mod1Mask)) { |
| - // Remap Alt+Down to Next (aka PageDown). |
| + } else if (search_as_function_key && |
| + keysym == XK_Right && (xkey->state & Mod4Mask)) { |
| + // With Search as Function key: Remap Search+Right to End. |
| + OverwriteEvent(event, end_xkeycode_, xkey->state & ~Mod4Mask, |
| + ui::VKEY_END, event->flags()); |
| + rewritten = true; |
| + } else if (!search_as_function_key && |
| + keysym == XK_Down && (xkey->state & Mod1Mask)) { |
| + // Without Search as Function key: Remap Alt+Down to Next (aka PageDown). |
| OverwriteEvent(event, next_xkeycode_, xkey->state & ~Mod1Mask, |
| ui::VKEY_NEXT, event->flags() & ~ui::EF_ALT_DOWN); |
| rewritten = true; |
| + } else if (search_as_function_key && |
| + keysym == XK_Down && (xkey->state & Mod4Mask)) { |
| + // With Search as Function key: Remap Search+Down to Next (aka PageDown). |
| + OverwriteEvent(event, next_xkeycode_, xkey->state & ~Mod4Mask, |
| + ui::VKEY_NEXT, event->flags()); |
| + rewritten = true; |
| } |
| #else |
| // TODO(yusukes): Support Ash on other platforms if needed. |
| @@ -682,6 +737,47 @@ bool EventRewriter::RewriteBackspaceAndArrowKeys(ui::KeyEvent* event) { |
| return rewritten; |
| } |
| +#if defined(OS_CHROMEOS) |
| +bool EventRewriter::DropSearchKey(ui::KeyEvent* event) { |
|
Yusuke Sato
2012/11/26 06:09:38
I guess we can remove this function if we stop usi
danakj
2012/11/26 17:20:16
We still have to drop the press or you get an apps
|
| + const PrefService* pref_service = |
| + pref_service_ ? pref_service_ : GetPrefService(); |
| + if (!pref_service) |
| + return false; |
| + const bool search_as_function_key = |
| + pref_service->GetBoolean(prefs::kLanguageSearchKeyActsAsFunctionKey); |
| + |
| + if (!search_as_function_key) |
| + return false; |
| + |
| + XEvent* xev = event->native_event(); |
| + XKeyEvent* xkey = &(xev->xkey); |
| + |
| + const KeySym keysym = XLookupKeysym(xkey, 0); |
| + |
| + bool drop_key = false; |
| + |
| + // If we the Search key acts like a modifier for another key, then drop the |
|
Yusuke Sato
2012/11/26 06:09:38
nit: s/we//
danakj
2012/11/26 19:36:26
Done.
|
| + // release of the Search key when it happens. |
| + if ((xkey->state & Mod4Mask) && keysym != XK_Super_L) |
| + drop_search_key_release_ = true; |
| + |
| + if (event->type() == ui::ET_KEY_PRESSED && keysym == XK_Super_L) { |
| + // When Search key is acting as Function key, then drop Search key presses |
| + // that don't include other modifiers. |
| + drop_key = true; |
| + } else if (event->type() == ui::ET_KEY_RELEASED && keysym == XK_Super_L) { |
| + if (drop_search_key_release_) { |
| + // If we ate the Search key press, then also drop the release if another |
| + // key used Search as a modifier. |
| + drop_key = true; |
| + } |
| + drop_search_key_release_ = false; |
| + } |
| + |
| + return drop_key; |
| +} |
| +#endif |
| + |
| void EventRewriter::RewriteLocatedEvent(ui::LocatedEvent* event) { |
| #if defined(OS_CHROMEOS) |
| if (event->flags() & ui::EF_IS_SYNTHESIZED) |