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

Unified Diff: chrome/browser/ui/ash/event_rewriter.cc

Issue 11421055: Add power-user keyboard mode for ChromeOS with Search key acting as a typical Fn key. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix unittest Created 8 years, 1 month 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
« no previous file with comments | « chrome/browser/ui/ash/event_rewriter.h ('k') | chrome/browser/ui/ash/event_rewriter_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..edc4d3e5dd307a50435a470fe36bf09f83bcbc6d 100644
--- a/chrome/browser/ui/ash/event_rewriter.cc
+++ b/chrome/browser/ui/ash/event_rewriter.cc
@@ -121,6 +121,12 @@ bool HasChromeOSKeyboard() {
switches::kHasChromeOSKeyboard);
}
+bool EventSourceIsChromebookKeyboard(ui::KeyEvent* /* event */) {
+ // TODO(danakj): Determine if the event came from a Chromebook internal
+ // keyboard.
+ return true;
+}
+
bool IsMod3UsedByCurrentInputMethod() {
// Since both German Neo2 XKB layout and Caps Lock depend on Mod3Mask,
// it's not possible to make both features work. For now, we don't remap
@@ -143,6 +149,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 +211,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;
}
@@ -356,17 +363,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 +648,90 @@ bool EventRewriter::RewriteNumPadKeys(ui::KeyEvent* event) {
bool EventRewriter::RewriteBackspaceAndArrowKeys(ui::KeyEvent* event) {
bool rewritten = false;
#if defined(OS_CHROMEOS)
+ // On a Chromebook keyboard, modifier keys can be used to access extended
+ // keyboard shortcuts. On other keyboards, keys such as delete and page up are
+ // already available, so we do not need to rewrite anything here.
+ if (!EventSourceIsChromebookKeyboard(event))
+ return rewritten;
+
+ const PrefService* pref_service =
+ pref_service_ ? pref_service_ : GetPrefService();
+ bool chromebook_function_key = CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableChromebookFunctionKey);
+
+ bool search_as_function_key = chromebook_function_key && pref_service &&
+ 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 (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 (keysym == XK_Down &&
+ } 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 +739,50 @@ bool EventRewriter::RewriteBackspaceAndArrowKeys(ui::KeyEvent* event) {
return rewritten;
}
+#if defined(OS_CHROMEOS)
+bool EventRewriter::DropSearchKey(ui::KeyEvent* event) {
+ const PrefService* pref_service =
+ pref_service_ ? pref_service_ : GetPrefService();
+ bool chromebook_function_key = CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableChromebookFunctionKey);
+ bool search_as_function_key = chromebook_function_key && pref_service &&
+ 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;
+ unsigned int nonsearch_modifiers = Mod1Mask | ControlMask | ShiftMask;
+
+ // If the Search key acts like a modifier for another key, then drop the
+ // 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 &&
+ // Only drop the Search key press if no other modifier was present.
+ !(xkey->state & nonsearch_modifiers)) {
+ // When Search key is acting as Function key, then drop Search key presses
+ // that don't include other modifiers.
+ drop_key = true;
Yusuke Sato 2012/11/26 21:15:05 I'm wondering if this is still necessary. If it is
danakj 2012/11/26 21:17:59 Actually, it was just to make sure future shortcut
Yusuke Sato 2012/11/26 21:26:34 I see. Then I'd prefer to add a test to accelerato
danakj 2012/11/26 21:47:50 Ah, okay. By solving this in accelerator_controlle
+ } 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;
Yusuke Sato 2012/11/26 21:15:05 As I wrote above, please do that kind of suppressi
danakj 2012/11/26 21:17:59 Ah, okay will do!
+ }
+
+ return drop_key;
+}
+#endif
+
void EventRewriter::RewriteLocatedEvent(ui::LocatedEvent* event) {
#if defined(OS_CHROMEOS)
if (event->flags() & ui::EF_IS_SYNTHESIZED)
« no previous file with comments | « chrome/browser/ui/ash/event_rewriter.h ('k') | chrome/browser/ui/ash/event_rewriter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698