Chromium Code Reviews| 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..3dbd302f5fe154e69c1356343120f3e4a3243ea8 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)); |
| // 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) { |
|
sadrul
2014/07/10 16:03:06
We are duping some amount of code and comment here
kpschoedel
2014/07/10 17:22:40
Done.
|
| + 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) |
|
sadrul
2014/07/10 16:03:06
native_event->type is going to be GenericEvent her
kpschoedel
2014/07/10 17:22:40
Done.
|
| + 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 |
| @@ -358,6 +388,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: |
| @@ -370,7 +404,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: |
| @@ -406,7 +441,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 +454,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); |
| + } |
| } |
| } |
| } |
| @@ -599,14 +640,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; |
|
sadrul
2014/07/10 16:03:06
We should not make a copy of a XI2 event here. Wha
kpschoedel
2014/07/10 17:22:40
Evidently none that's covered by unit_tests ash_un
|
| } |
| void ReleaseCopiedNativeEvent(const base::NativeEvent& event) { |
| + if (event && event->type == GenericEvent) |
| + delete static_cast<XIDeviceEvent*>(event->xcookie.data); |
| delete event; |
| } |