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

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

Issue 11417144: Use rewriting to make ChromeOS keyboard F<number> keys produce extended keycodes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: chromeboxkeyboard 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
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 42b1b8e6d928b410dc41ab1c72bb1c6bf1488542..f92d16ff6c01f377402be6bb42175de4f0878fb3 100644
--- a/chrome/browser/ui/ash/event_rewriter.cc
+++ b/chrome/browser/ui/ash/event_rewriter.cc
@@ -121,12 +121,6 @@ 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
@@ -149,6 +143,7 @@ const PrefService* GetPrefService() {
EventRewriter::EventRewriter()
: last_device_id_(kBadDeviceId),
#if defined(OS_CHROMEOS)
+ force_external_keyboard_for_testing_(false),
xkeyboard_(NULL),
#endif
pref_service_(NULL) {
@@ -200,6 +195,15 @@ EventRewriter::DeviceType EventRewriter::GetDeviceType(
return kDeviceAppleKeyboard;
}
+ // TODO(danakj): This could also impact laptops other than Chromebooks, and
+ // might belong behind a command-line flag to be used only on Chromebooks.
+ // The chromebook internal keyboard's name.
+ if (LowerCaseEqualsASCII(device_name, "at translated set 2 keyboard"))
+ return kDeviceChromebookKeyboard;
+ // The chromebox chrome-specific keyboard's name.
+ if (LowerCaseEqualsASCII(device_name, "samsung usb keyboard"))
+ return kDeviceChromebookKeyboard;
Daniel Erat 2012/11/28 22:23:03 it's possible that i misunderstood the conversatio
danakj 2012/11/29 01:50:54 Hm.. It should refer to ChromeOS keyboards that ha
+
return kDeviceUnknown;
}
@@ -301,6 +305,42 @@ 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);
+ number1_xkeycode_ = XKeysymToKeycode(display, XK_1);
+ number2_xkeycode_ = XKeysymToKeycode(display, XK_2);
+ number3_xkeycode_ = XKeysymToKeycode(display, XK_3);
+ number4_xkeycode_ = XKeysymToKeycode(display, XK_4);
+ number5_xkeycode_ = XKeysymToKeycode(display, XK_5);
+ number6_xkeycode_ = XKeysymToKeycode(display, XK_6);
+ number7_xkeycode_ = XKeysymToKeycode(display, XK_7);
+ number8_xkeycode_ = XKeysymToKeycode(display, XK_8);
+ number9_xkeycode_ = XKeysymToKeycode(display, XK_9);
+ number0_xkeycode_ = XKeysymToKeycode(display, XK_0);
+ minus_xkeycode_ = XKeysymToKeycode(display, XK_minus);
+ equal_xkeycode_ = XKeysymToKeycode(display, XK_equal);
+ browser_back_xkeycode_ = XKeysymToKeycode(display, XF86XK_Back);
+ browser_forward_xkeycode_ = XKeysymToKeycode(display, XF86XK_Forward);
+ browser_refresh_xkeycode_ = XKeysymToKeycode(display, XF86XK_Reload);
+ media_launch_app1_xkeycode_ = XKeysymToKeycode(display, XF86XK_LaunchA);
+ media_launch_app2_xkeycode_ = XKeysymToKeycode(display, XF86XK_LaunchB);
+ brightness_down_xkeycode_ =
+ XKeysymToKeycode(display, XF86XK_MonBrightnessDown);
+ brightness_up_xkeycode_ = XKeysymToKeycode(display, XF86XK_MonBrightnessUp);
+ volume_mute_xkeycode_ = XKeysymToKeycode(display, XF86XK_AudioMute);
+ volume_down_xkeycode_ = XKeysymToKeycode(display, XF86XK_AudioLowerVolume);
+ volume_up_xkeycode_ = XKeysymToKeycode(display, XF86XK_AudioRaiseVolume);
+ power_xkeycode_ = XKeysymToKeycode(display, XF86XK_PowerOff);
}
KeyCode EventRewriter::NativeKeySymToNativeKeycode(KeySym keysym) {
@@ -360,6 +400,25 @@ KeyCode EventRewriter::NativeKeySymToNativeKeycode(KeySym keysym) {
}
return 0U;
}
+
+bool EventRewriter::EventSourceIsChromebookKeyboard(ui::KeyEvent* /* event */) {
+ if (force_external_keyboard_for_testing_)
+ return false;
+
+ if (last_device_id_ == kBadDeviceId)
+ return false;
+
+ // Check which device generated |event|.
+ std::map<int, DeviceType>::const_iterator iter =
+ device_id_to_type_.find(last_device_id_);
+ if (iter == device_id_to_type_.end()) {
+ LOG(ERROR) << "Device ID " << last_device_id_ << " is unknown.";
+ return false;
+ }
+
+ const DeviceType type = iter->second;
+ return type == kDeviceChromebookKeyboard;
+}
#endif
void EventRewriter::Rewrite(ui::KeyEvent* event) {
@@ -372,7 +431,7 @@ void EventRewriter::Rewrite(ui::KeyEvent* event) {
RewriteModifiers(event);
RewriteNumPadKeys(event);
RewriteBackspaceAndArrowKeys(event);
- // TODO(yusukes): Implement crosbug.com/27167 (allow sending function keys).
+ RewriteFunctionKeys(event);
}
bool EventRewriter::IsAppleKeyboard() const {
@@ -731,6 +790,175 @@ bool EventRewriter::RewriteBackspaceAndArrowKeys(ui::KeyEvent* event) {
return rewritten;
}
+bool EventRewriter::RewriteFunctionKeys(ui::KeyEvent* event) {
+#if defined(OS_CHROMEOS)
+ XEvent* xev = event->native_event();
+ XKeyEvent* xkey = &(xev->xkey);
+ const KeySym keysym = XLookupKeysym(xkey, 0);
+
+ KeyCode remapped_native_keycode = 0;
+ ui::KeyboardCode remapped_keycode = ui::VKEY_UNKNOWN;
+ unsigned int remapped_native_state = xkey->state;
+ int remapped_flags = event->flags();
+
+ // On a Chromebook keyboard, F<number> keys have special purposes. On other
+ // keyboards, they should act as usual.
+ if (!EventSourceIsChromebookKeyboard(event))
+ return false;
+
+ // Rewrite the actual F1-F12 keys on a Chromebook keyboard to special keys.
+ switch (keysym) {
+ case XK_F1:
+ // Remap F1 to BROWSER_BACK
+ remapped_native_keycode = browser_back_xkeycode_;
+ remapped_keycode = ui::VKEY_BROWSER_BACK;
+ break;
+ case XK_F2:
+ // Remap F2 to BROWSER_FORWARD
+ remapped_native_keycode = browser_forward_xkeycode_;
+ remapped_keycode = ui::VKEY_BROWSER_FORWARD;
+ break;
+ case XK_F3:
+ // Remap F3 to BROWSER_REFRESH
+ remapped_native_keycode = browser_refresh_xkeycode_;
+ remapped_keycode = ui::VKEY_BROWSER_REFRESH;
+ break;
+ case XK_F4:
+ // Remap F4 to MEDIA_LAUNCH_APP2
+ remapped_native_keycode = media_launch_app2_xkeycode_;
+ remapped_keycode = ui::VKEY_MEDIA_LAUNCH_APP2;
+ break;
+ case XK_F5:
+ // Remap F5 to MEDIA_LAUNCH_APP1
+ remapped_native_keycode = media_launch_app1_xkeycode_;
+ remapped_keycode = ui::VKEY_MEDIA_LAUNCH_APP1;
+ break;
+ case XK_F6:
+ // Remap F6 to BRIGHTNESS_DOWN
+ remapped_native_keycode = brightness_down_xkeycode_;
+ remapped_keycode = ui::VKEY_BRIGHTNESS_DOWN;
+ break;
+ case XK_F7:
+ // Remap F7 to BRIGHTNESS_UP
+ remapped_native_keycode = brightness_up_xkeycode_;
+ remapped_keycode = ui::VKEY_BRIGHTNESS_UP;
+ break;
+ case XK_F8:
+ // Remap F8 to VOLUME_MUTE
+ remapped_native_keycode = volume_mute_xkeycode_;
+ remapped_keycode = ui::VKEY_VOLUME_MUTE;
+ break;
+ case XK_F9:
+ // Remap F9 to VOLUME_DOWN
+ remapped_native_keycode = volume_down_xkeycode_;
+ remapped_keycode = ui::VKEY_VOLUME_DOWN;
+ break;
+ case XK_F10:
+ // Remap F10 to VOLUME_UP
+ remapped_native_keycode = volume_up_xkeycode_;
+ remapped_keycode = ui::VKEY_VOLUME_UP;
+ break;
+ case XK_F11:
+ // Remap F11 to POWER
+ remapped_native_keycode = power_xkeycode_;
+ remapped_keycode = ui::VKEY_POWER;
+ break;
+ default:
+ break;
+ }
+
+ 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);
+
+ // When using Search as a Function key, remap Search+<number> to F<number>.
+ if (search_as_function_key && xkey->state & Mod4Mask) {
+ // We check the keycode here instead of the keysym, as these keys have
+ // different keysyms when modifiers are pressed, such as shift.
+
+ // TODO(danakj): On some i18n keyboards, these choices will be bad and we
+ // should make layout-specific choices here. For eg. on a french keyboard
+ // "-" and "6" are the same key, so F11 will not be accessible.
+ KeyCode xkeycode = xkey->keycode;
+ if (xkeycode == number1_xkeycode_) {
+ // Remap Search+1 to F1.
+ remapped_native_keycode = f1_xkeycode_;
+ remapped_keycode = ui::VKEY_F1;
+ remapped_native_state &= ~Mod4Mask;
+ } else if (xkeycode == number2_xkeycode_) {
+ // Remap Search+2 to F2.
Daniel Erat 2012/11/28 22:23:03 i'd probably remove these repetitive comments in f
danakj 2012/11/29 01:50:54 Done.
+ remapped_native_keycode = f2_xkeycode_;
+ remapped_keycode = ui::VKEY_F2;
+ remapped_native_state &= ~Mod4Mask;
+ } else if (xkeycode == number3_xkeycode_) {
+ // Remap Search+3 to F3.
+ remapped_native_keycode = f3_xkeycode_;
+ remapped_keycode = ui::VKEY_F3;
+ remapped_native_state &= ~Mod4Mask;
+ } else if (xkeycode == number4_xkeycode_) {
+ // Remap Search+4 to F4.
+ remapped_native_keycode = f4_xkeycode_;
+ remapped_keycode = ui::VKEY_F4;
+ remapped_native_state &= ~Mod4Mask;
+ } else if (xkeycode == number5_xkeycode_) {
+ // Remap Search+5 to F5.
+ remapped_native_keycode = f5_xkeycode_;
+ remapped_keycode = ui::VKEY_F5;
+ remapped_native_state &= ~Mod4Mask;
+ } else if (xkeycode == number6_xkeycode_) {
+ // Remap Search+6 to F6.
+ remapped_native_keycode = f6_xkeycode_;
+ remapped_keycode = ui::VKEY_F6;
+ remapped_native_state &= ~Mod4Mask;
+ } else if (xkeycode == number7_xkeycode_) {
+ // Remap Search+7 to F7.
+ remapped_native_keycode = f7_xkeycode_;
+ remapped_keycode = ui::VKEY_F7;
+ remapped_native_state &= ~Mod4Mask;
+ } else if (xkeycode == number8_xkeycode_) {
+ // Remap Search+8 to F8.
+ remapped_native_keycode = f8_xkeycode_;
+ remapped_keycode = ui::VKEY_F8;
+ remapped_native_state &= ~Mod4Mask;
+ } else if (xkeycode == number9_xkeycode_) {
+ // Remap Search+9 to F9.
+ remapped_native_keycode = f9_xkeycode_;
+ remapped_keycode = ui::VKEY_F9;
+ remapped_native_state &= ~Mod4Mask;
+ } else if (xkeycode == number0_xkeycode_) {
+ // Remap Search+0 to F10.
+ remapped_native_keycode = f10_xkeycode_;
+ remapped_keycode = ui::VKEY_F10;
+ remapped_native_state &= ~Mod4Mask;
+ } else if (xkeycode == minus_xkeycode_) {
+ // Remap Search+- to F11.
+ remapped_native_keycode = f11_xkeycode_;
+ remapped_keycode = ui::VKEY_F11;
+ remapped_native_state &= ~Mod4Mask;
+ } else if (xkeycode == equal_xkeycode_) {
+ // Remap Search+= to F12.
+ remapped_native_keycode = f12_xkeycode_;
+ remapped_keycode = ui::VKEY_F12;
+ remapped_native_state &= ~Mod4Mask;
+ }
+ }
+
+ if (!remapped_native_keycode || remapped_keycode == ui::VKEY_UNKNOWN)
+ return false;
+
+ OverwriteEvent(event, remapped_native_keycode, remapped_native_state,
+ remapped_keycode, remapped_flags);
+ return true;
+#else
+ // TODO(danakj): Support Ash on other platforms if needed.
+ return false;
+#endif
+}
+
void EventRewriter::RewriteLocatedEvent(ui::LocatedEvent* event) {
#if defined(OS_CHROMEOS)
if (event->flags() & ui::EF_IS_SYNTHESIZED)
@@ -800,6 +1028,9 @@ EventRewriter::DeviceType EventRewriter::DeviceAddedInternal(
if (type == kDeviceAppleKeyboard) {
VLOG(1) << "Apple keyboard '" << device_name << "' connected: "
<< "id=" << device_id;
+ } else if (type == kDeviceChromebookKeyboard) {
+ VLOG(1) << "Chromebook keyboard '" << device_name << "' connected: "
+ << "id=" << device_id;
}
// Always overwrite the existing device_id since the X server may reuse a
// device id for an unattached device.

Powered by Google App Engine
This is Rietveld 408576698