Index: ui/events/x/events_x.cc |
diff --git a/ui/events/x/events_x.cc b/ui/events/x/events_x.cc |
index 5216f31effff845645644084a7ece86526a2f78f..03b7e28d8de9704453e90d7dde5a6e126667863b 100644 |
--- a/ui/events/x/events_x.cc |
+++ b/ui/events/x/events_x.cc |
@@ -10,6 +10,7 @@ |
#include <X11/extensions/XInput2.h> |
#include <X11/Xlib.h> |
#include <X11/Xutil.h> |
+#include <X11/XKBlib.h> |
#include "base/logging.h" |
#include "base/memory/singleton.h" |
@@ -42,43 +43,55 @@ class XModifierStateWatcher{ |
return Singleton<XModifierStateWatcher>::get(); |
} |
- void UpdateStateFromEvent(const base::NativeEvent& native_event) { |
+ int StateFromKeyboardCode(ui::KeyboardCode keyboard_code) { |
+ switch (keyboard_code) { |
+ case ui::VKEY_CONTROL: |
+ return ControlMask; |
+ case ui::VKEY_SHIFT: |
+ return ShiftMask; |
+ case ui::VKEY_MENU: |
+ return Mod1Mask; |
+ case ui::VKEY_CAPITAL: |
+ return LockMask; |
+ default: |
+ return 0; |
+ } |
+ } |
+ |
+ void UpdateStateFromXEvent(const base::NativeEvent& native_event) { |
+ ui::KeyboardCode keyboard_code = ui::KeyboardCodeFromNative(native_event); |
+ unsigned int mask = StateFromKeyboardCode(keyboard_code); |
// Floating device can't access the modifer state from master device. |
// We need to track the states of modifier keys in a singleton for |
// floating devices such as touch screen. Issue 106426 is one example |
// of why we need the modifier states for floating device. |
- state_ = native_event->xkey.state; |
- // master_state is the state before key press. We need to track the |
- // state after key press for floating device. Currently only ctrl, |
- // shift, alt and caps lock keys are tracked. |
- ui::KeyboardCode keyboard_code = ui::KeyboardCodeFromNative(native_event); |
- unsigned int mask = 0; |
- |
- switch (keyboard_code) { |
- case ui::VKEY_CONTROL: { |
- mask = ControlMask; |
- break; |
- } |
- case ui::VKEY_SHIFT: { |
- mask = ShiftMask; |
+ switch (native_event->type) { |
+ case KeyPress: |
+ state_ = native_event->xkey.state | mask; |
break; |
- } |
- case ui::VKEY_MENU: { |
- mask = Mod1Mask; |
+ case KeyRelease: |
+ state_ = native_event->xkey.state & ~mask; |
break; |
- } |
- case ui::VKEY_CAPITAL: { |
- mask = LockMask; |
+ case GenericEvent: { |
+ XIDeviceEvent* xievent = |
+ static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
+ switch (xievent->evtype) { |
+ case XI_KeyPress: |
+ state_ = xievent->mods.effective |= mask; |
+ break; |
+ case XI_KeyRelease: |
+ state_ = xievent->mods.effective &= ~mask; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
break; |
} |
default: |
+ NOTREACHED(); |
break; |
} |
- |
- if (native_event->type == KeyPress) |
- state_ |= mask; |
- else |
- state_ &= ~mask; |
} |
// Returns the current modifer state in master device. It only contains the |
@@ -182,6 +195,18 @@ int GetEventFlagsFromXKeyEvent(XEvent* xevent) { |
ime_fabricated_flag; |
} |
+int GetEventFlagsFromXGenericEvent(XEvent* xevent) { |
+ DCHECK(xevent->type == GenericEvent); |
+ XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data); |
+ DCHECK((xievent->evtype == XI_KeyPress) || |
+ (xievent->evtype == XI_KeyRelease)); |
+ return GetEventFlagsFromXState(xievent->mods.effective) | |
+ (IsKeypadKey( |
+ XkbKeycodeToKeysym(xievent->display, xievent->detail, 0, 0)) |
+ ? ui::EF_NUMPAD_KEY |
+ : 0); |
+} |
+ |
// Get the event flag for the button in XButtonEvent. During a ButtonPress |
// event, |state| in XButtonEvent does not include the button that has just been |
// pressed. Instead |state| contains flags for the buttons (if any) that had |
@@ -354,10 +379,13 @@ EventType EventTypeFromNative(const base::NativeEvent& native_event) { |
return ET_UMA_DATA; |
} else if (GetButtonMaskForX2Event(xievent)) { |
return ET_MOUSE_DRAGGED; |
- } else { |
- return ET_MOUSE_MOVED; |
} |
+ return ET_MOUSE_MOVED; |
} |
+ case XI_KeyPress: |
+ return ET_KEY_PRESSED; |
+ case XI_KeyRelease: |
+ return ET_KEY_RELEASED; |
} |
} |
default: |
@@ -370,7 +398,7 @@ int EventFlagsFromNative(const base::NativeEvent& native_event) { |
switch (native_event->type) { |
case KeyPress: |
case KeyRelease: { |
- XModifierStateWatcher::GetInstance()->UpdateStateFromEvent(native_event); |
+ XModifierStateWatcher::GetInstance()->UpdateStateFromXEvent(native_event); |
return GetEventFlagsFromXKeyEvent(native_event); |
} |
case ButtonPress: |
@@ -406,7 +434,7 @@ int EventFlagsFromNative(const base::NativeEvent& native_event) { |
const bool touch = |
TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); |
int flags = GetButtonMaskForX2Event(xievent) | |
- GetEventFlagsFromXState(xievent->mods.effective); |
+ GetEventFlagsFromXState(xievent->mods.effective); |
if (touch) { |
flags |= GetEventFlagsFromXState( |
XModifierStateWatcher::GetInstance()->state()); |
@@ -419,8 +447,14 @@ int EventFlagsFromNative(const base::NativeEvent& native_event) { |
return flags; |
} |
case XI_Motion: |
- return GetButtonMaskForX2Event(xievent) | |
- GetEventFlagsFromXState(xievent->mods.effective); |
+ return GetButtonMaskForX2Event(xievent) | |
+ GetEventFlagsFromXState(xievent->mods.effective); |
+ case XI_KeyPress: |
+ case XI_KeyRelease: { |
+ XModifierStateWatcher::GetInstance()->UpdateStateFromXEvent( |
+ native_event); |
+ return GetEventFlagsFromXGenericEvent(native_event); |
+ } |
} |
} |
} |