Index: ui/events/x/events_x.cc |
diff --git a/ui/events/x/events_x.cc b/ui/events/x/events_x.cc |
index 69cf733e003a987b795a572aa65d6b81b891b9d5..f2e59c5ec7c94e7b86a27a07a9e0f62b3f1df6e4 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,7 +43,24 @@ 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 UpdateStateFromXKeyEvent(const base::NativeEvent& native_event) { |
+ DCHECK((native_event->type == KeyPress) || |
+ (native_event->type == KeyRelease)); |
sadrul
2014/06/26 12:34:20
I suspect this will need to change once you make t
kpschoedel
2014/06/26 17:24:10
XI2 handling uses UpdateStateFromXGenericEvent; th
|
// 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 |
@@ -52,35 +70,35 @@ class XModifierStateWatcher{ |
// 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; |
- break; |
- } |
- case ui::VKEY_MENU: { |
- mask = Mod1Mask; |
- break; |
- } |
- case ui::VKEY_CAPITAL: { |
- mask = LockMask; |
- break; |
- } |
- default: |
- break; |
- } |
- |
+ unsigned int mask = StateFromKeyboardCode(keyboard_code); |
if (native_event->type == KeyPress) |
state_ |= mask; |
else |
state_ &= ~mask; |
} |
+ void UpdateStateFromXGenericEvent(const base::NativeEvent& native_event) { |
+ DCHECK(native_event->type == GenericEvent); |
+ XIDeviceEvent* xievent = |
+ static_cast<XIDeviceEvent*>(native_event->xcookie.data); |
+ DCHECK((xievent->evtype == XI_KeyPress) || |
+ (xievent->evtype == XI_KeyRelease)); |
+ // 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_ = xievent->mods.effective; |
+ // 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 = StateFromKeyboardCode(keyboard_code); |
+ if (native_event->type == XI_KeyPress) |
+ state_ |= mask; |
+ else |
+ state_ &= ~mask; |
+ } |
+ |
// Returns the current modifer state in master device. It only contains the |
// state of ctrl, shift, alt and caps lock keys. |
unsigned int state() { return state_; } |
@@ -182,6 +200,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 |
@@ -349,6 +379,10 @@ EventType EventTypeFromNative(const base::NativeEvent& native_event) { |
return ET_MOUSE_MOVED; |
} |
} |
+ case XI_KeyPress: |
+ return ET_KEY_PRESSED; |
+ case XI_KeyRelease: |
+ return ET_KEY_RELEASED; |
} |
} |
default: |
@@ -361,7 +395,8 @@ int EventFlagsFromNative(const base::NativeEvent& native_event) { |
switch (native_event->type) { |
case KeyPress: |
case KeyRelease: { |
- XModifierStateWatcher::GetInstance()->UpdateStateFromEvent(native_event); |
+ XModifierStateWatcher::GetInstance()->UpdateStateFromXKeyEvent( |
+ native_event); |
return GetEventFlagsFromXKeyEvent(native_event); |
} |
case ButtonPress: |
@@ -397,7 +432,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()); |
@@ -410,8 +445,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()->UpdateStateFromXGenericEvent( |
+ native_event); |
+ return GetEventFlagsFromXGenericEvent(native_event); |
+ } |
} |
} |
} |
@@ -590,14 +631,21 @@ gfx::Vector2d GetMouseWheelOffset(const base::NativeEvent& native_event) { |
} |
base::NativeEvent CopyNativeEvent(const base::NativeEvent& event) { |
- if (!event || event->type == GenericEvent) |
+ if (!event) |
return NULL; |
XEvent* copy = new XEvent; |
*copy = *event; |
+ if (event->type == GenericEvent) { |
+ XIDeviceEvent* xievent_copy = new XIDeviceEvent; |
+ *xievent_copy = *static_cast<XIDeviceEvent*>(event->xcookie.data); |
+ copy->xcookie.data = xievent_copy; |
+ } |
return copy; |
} |
void ReleaseCopiedNativeEvent(const base::NativeEvent& event) { |
+ if (event && event->type == GenericEvent) |
+ delete static_cast<XIDeviceEvent*>(event->xcookie.data); |
delete event; |
} |