Index: chrome/browser/chromeos/system_key_event_listener.cc |
diff --git a/chrome/browser/chromeos/system_key_event_listener.cc b/chrome/browser/chromeos/system_key_event_listener.cc |
index 00991b819494c2590276f0539953536063883d2d..5b5477eba36b1095c41ceb5e1e50369c25e25942 100644 |
--- a/chrome/browser/chromeos/system_key_event_listener.cc |
+++ b/chrome/browser/chromeos/system_key_event_listener.cc |
@@ -12,6 +12,7 @@ |
#include "chrome/browser/chromeos/volume_bubble.h" |
#include "content/browser/user_metrics.h" |
#include "third_party/cros/chromeos_wm_ipc_enums.h" |
+#include "ui/base/x/x11_util.h" |
#if defined(TOUCH_UI) |
#include "base/message_pump_glib_x_dispatch.h" |
@@ -31,27 +32,16 @@ SystemKeyEventListener* SystemKeyEventListener::GetInstance() { |
} |
SystemKeyEventListener::SystemKeyEventListener() |
- : stopped_(false), |
+ : key_volume_mute_(0), |
+ key_volume_down_(0), |
+ key_volume_up_(0), |
+ key_f8_(0), |
+ key_f9_(0), |
+ key_f10_(0), |
+ stopped_(false), |
audio_handler_(AudioHandler::GetInstance()) { |
WmMessageListener::GetInstance()->AddObserver(this); |
- |
- key_volume_mute_ = XKeysymToKeycode(GDK_DISPLAY(), XF86XK_AudioMute); |
- key_volume_down_ = XKeysymToKeycode(GDK_DISPLAY(), XF86XK_AudioLowerVolume); |
- key_volume_up_ = XKeysymToKeycode(GDK_DISPLAY(), XF86XK_AudioRaiseVolume); |
- key_f8_ = XKeysymToKeycode(GDK_DISPLAY(), XK_F8); |
- key_f9_ = XKeysymToKeycode(GDK_DISPLAY(), XK_F9); |
- key_f10_ = XKeysymToKeycode(GDK_DISPLAY(), XK_F10); |
- |
- if (key_volume_mute_) |
- GrabKey(key_volume_mute_, 0); |
- if (key_volume_down_) |
- GrabKey(key_volume_down_, 0); |
- if (key_volume_up_) |
- GrabKey(key_volume_up_, 0); |
- GrabKey(key_f8_, 0); |
- GrabKey(key_f9_, 0); |
- GrabKey(key_f10_, 0); |
- |
+ SetupKeycodes(); |
#if defined(TOUCH_UI) |
MessageLoopForUI::current()->AddObserver(this); |
#else |
@@ -110,6 +100,41 @@ GdkFilterReturn SystemKeyEventListener::GdkEventFilter(GdkXEvent* gxevent, |
: GDK_FILTER_CONTINUE; |
} |
+bool SystemKeyEventListener::SetupKeycodes() { |
+ Display* display = ui::GetXDisplay(); |
+ Window root = DefaultRootWindow(display); |
+ |
+ struct { |
+ int32* keycode; |
+ KeySym keysym; |
+ } *key, keys[] = { |
+ { &key_f8_, XK_F8 }, |
+ { &key_f9_, XK_F9 }, |
+ { &key_f10_, XK_F10 }, |
+ { &key_volume_mute_, XF86XK_AudioMute }, |
+ { &key_volume_down_, XF86XK_AudioLowerVolume }, |
+ { &key_volume_up_, XF86XK_AudioRaiseVolume }, |
+ { NULL, NoSymbol } |
+ }; |
+ |
+ // Ungrab any existing grabs on the keys first. |
+ for (key = keys; key->keycode; key++) { |
+ if (*key->keycode) |
+ XUngrabKey(display, *key->keycode, AnyModifier, root); |
+ } |
+ |
+ bool handled = false; |
+ for (key = keys; key->keycode; key++) { |
+ int32 old_keycode = *key->keycode; |
+ *key->keycode = XKeysymToKeycode(display, key->keysym); |
+ if (*key->keycode) |
+ GrabKey(*key->keycode, 0); |
+ handled = (old_keycode != *key->keycode) || handled; |
+ } |
+ |
+ return handled; |
+} |
+ |
void SystemKeyEventListener::GrabKey(int32 key, uint32 mask) { |
uint32 num_lock_mask = Mod2Mask; |
uint32 caps_lock_mask = LockMask; |
@@ -187,6 +212,12 @@ bool SystemKeyEventListener::WillProcessXEvent(XEvent* xevent) { |
} |
} |
} |
+ } else if (xevent->type == MappingNotify) { |
+ XMappingEvent* xmap = &xevent->xmapping; |
+ if (xmap->request == MappingKeyboard) { |
+ XRefreshKeyboardMapping(xmap); |
+ return SetupKeycodes(); |
+ } |
} |
return false; |
} |