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

Side by Side Diff: ui/events/x/events_x.cc

Issue 336403005: Use XInput2 events for keyboard events. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address review comments (sadrul) 3 Created 6 years, 5 months 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 unified diff | Download patch
« no previous file with comments | « ui/events/test/events_test_utils_x11.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/events/event_constants.h" 5 #include "ui/events/event_constants.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <string.h> 8 #include <string.h>
9 #include <X11/extensions/XInput.h> 9 #include <X11/extensions/XInput.h>
10 #include <X11/extensions/XInput2.h> 10 #include <X11/extensions/XInput2.h>
11 #include <X11/Xlib.h> 11 #include <X11/Xlib.h>
12 #include <X11/Xutil.h> 12 #include <X11/Xutil.h>
13 #include <X11/XKBlib.h>
13 14
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/memory/singleton.h" 16 #include "base/memory/singleton.h"
16 #include "ui/events/event_utils.h" 17 #include "ui/events/event_utils.h"
17 #include "ui/events/keycodes/keyboard_code_conversion_x.h" 18 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
18 #include "ui/events/x/device_data_manager_x11.h" 19 #include "ui/events/x/device_data_manager_x11.h"
19 #include "ui/events/x/device_list_cache_x.h" 20 #include "ui/events/x/device_list_cache_x.h"
20 #include "ui/events/x/touch_factory_x11.h" 21 #include "ui/events/x/touch_factory_x11.h"
21 #include "ui/gfx/display.h" 22 #include "ui/gfx/display.h"
22 #include "ui/gfx/point.h" 23 #include "ui/gfx/point.h"
(...skipping 12 matching lines...) Expand all
35 36
36 // A class to track current modifier state on master device. Only track ctrl, 37 // A class to track current modifier state on master device. Only track ctrl,
37 // alt, shift and caps lock keys currently. The tracked state can then be used 38 // alt, shift and caps lock keys currently. The tracked state can then be used
38 // by floating device. 39 // by floating device.
39 class XModifierStateWatcher{ 40 class XModifierStateWatcher{
40 public: 41 public:
41 static XModifierStateWatcher* GetInstance() { 42 static XModifierStateWatcher* GetInstance() {
42 return Singleton<XModifierStateWatcher>::get(); 43 return Singleton<XModifierStateWatcher>::get();
43 } 44 }
44 45
45 void UpdateStateFromEvent(const base::NativeEvent& native_event) { 46 int StateFromKeyboardCode(ui::KeyboardCode keyboard_code) {
47 switch (keyboard_code) {
48 case ui::VKEY_CONTROL:
49 return ControlMask;
50 case ui::VKEY_SHIFT:
51 return ShiftMask;
52 case ui::VKEY_MENU:
53 return Mod1Mask;
54 case ui::VKEY_CAPITAL:
55 return LockMask;
56 default:
57 return 0;
58 }
59 }
60
61 void UpdateStateFromXEvent(const base::NativeEvent& native_event) {
62 ui::KeyboardCode keyboard_code = ui::KeyboardCodeFromNative(native_event);
63 unsigned int mask = StateFromKeyboardCode(keyboard_code);
46 // Floating device can't access the modifer state from master device. 64 // Floating device can't access the modifer state from master device.
47 // We need to track the states of modifier keys in a singleton for 65 // We need to track the states of modifier keys in a singleton for
48 // floating devices such as touch screen. Issue 106426 is one example 66 // floating devices such as touch screen. Issue 106426 is one example
49 // of why we need the modifier states for floating device. 67 // of why we need the modifier states for floating device.
50 state_ = native_event->xkey.state; 68 switch (native_event->type) {
51 // master_state is the state before key press. We need to track the 69 case KeyPress:
52 // state after key press for floating device. Currently only ctrl, 70 state_ = native_event->xkey.state | mask;
53 // shift, alt and caps lock keys are tracked.
54 ui::KeyboardCode keyboard_code = ui::KeyboardCodeFromNative(native_event);
55 unsigned int mask = 0;
56
57 switch (keyboard_code) {
58 case ui::VKEY_CONTROL: {
59 mask = ControlMask;
60 break; 71 break;
61 } 72 case KeyRelease:
62 case ui::VKEY_SHIFT: { 73 state_ = native_event->xkey.state & ~mask;
63 mask = ShiftMask;
64 break; 74 break;
65 } 75 case GenericEvent: {
66 case ui::VKEY_MENU: { 76 XIDeviceEvent* xievent =
67 mask = Mod1Mask; 77 static_cast<XIDeviceEvent*>(native_event->xcookie.data);
68 break; 78 switch (xievent->evtype) {
69 } 79 case XI_KeyPress:
70 case ui::VKEY_CAPITAL: { 80 state_ = xievent->mods.effective |= mask;
71 mask = LockMask; 81 break;
82 case XI_KeyRelease:
83 state_ = xievent->mods.effective &= ~mask;
84 break;
85 default:
86 NOTREACHED();
87 break;
88 }
72 break; 89 break;
73 } 90 }
74 default: 91 default:
92 NOTREACHED();
75 break; 93 break;
76 } 94 }
77
78 if (native_event->type == KeyPress)
79 state_ |= mask;
80 else
81 state_ &= ~mask;
82 } 95 }
83 96
84 // Returns the current modifer state in master device. It only contains the 97 // Returns the current modifer state in master device. It only contains the
85 // state of ctrl, shift, alt and caps lock keys. 98 // state of ctrl, shift, alt and caps lock keys.
86 unsigned int state() { return state_; } 99 unsigned int state() { return state_; }
87 100
88 private: 101 private:
89 friend struct DefaultSingletonTraits<XModifierStateWatcher>; 102 friend struct DefaultSingletonTraits<XModifierStateWatcher>;
90 103
91 XModifierStateWatcher() : state_(0) { } 104 XModifierStateWatcher() : state_(0) { }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 fabricated_by_xim ? ui::EF_IME_FABRICATED_KEY : 0; 188 fabricated_by_xim ? ui::EF_IME_FABRICATED_KEY : 0;
176 #endif 189 #endif
177 190
178 return GetEventFlagsFromXState(xevent->xkey.state) | 191 return GetEventFlagsFromXState(xevent->xkey.state) |
179 (IsKeypadKey(XLookupKeysym(&xevent->xkey, 0)) ? ui::EF_NUMPAD_KEY : 0) | 192 (IsKeypadKey(XLookupKeysym(&xevent->xkey, 0)) ? ui::EF_NUMPAD_KEY : 0) |
180 (IsFunctionKey(XLookupKeysym(&xevent->xkey, 0)) ? 193 (IsFunctionKey(XLookupKeysym(&xevent->xkey, 0)) ?
181 ui::EF_FUNCTION_KEY : 0) | 194 ui::EF_FUNCTION_KEY : 0) |
182 ime_fabricated_flag; 195 ime_fabricated_flag;
183 } 196 }
184 197
198 int GetEventFlagsFromXGenericEvent(XEvent* xevent) {
199 DCHECK(xevent->type == GenericEvent);
200 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xevent->xcookie.data);
201 DCHECK((xievent->evtype == XI_KeyPress) ||
202 (xievent->evtype == XI_KeyRelease));
203 return GetEventFlagsFromXState(xievent->mods.effective) |
204 (IsKeypadKey(
205 XkbKeycodeToKeysym(xievent->display, xievent->detail, 0, 0))
206 ? ui::EF_NUMPAD_KEY
207 : 0);
208 }
209
185 // Get the event flag for the button in XButtonEvent. During a ButtonPress 210 // Get the event flag for the button in XButtonEvent. During a ButtonPress
186 // event, |state| in XButtonEvent does not include the button that has just been 211 // event, |state| in XButtonEvent does not include the button that has just been
187 // pressed. Instead |state| contains flags for the buttons (if any) that had 212 // pressed. Instead |state| contains flags for the buttons (if any) that had
188 // already been pressed before the current button, and |button| stores the most 213 // already been pressed before the current button, and |button| stores the most
189 // current pressed button. So, if you press down left mouse button, and while 214 // current pressed button. So, if you press down left mouse button, and while
190 // pressing it down, press down the right mouse button, then for the latter 215 // pressing it down, press down the right mouse button, then for the latter
191 // event, |state| would have Button1Mask set but not Button3Mask, and |button| 216 // event, |state| would have Button1Mask set but not Button3Mask, and |button|
192 // would be 3. 217 // would be 3.
193 int GetEventFlagsForButton(int button) { 218 int GetEventFlagsForButton(int button) {
194 switch (button) { 219 switch (button) {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 if (GetFlingData(native_event, NULL, NULL, NULL, NULL, &is_cancel)) { 372 if (GetFlingData(native_event, NULL, NULL, NULL, NULL, &is_cancel)) {
348 return is_cancel ? ET_SCROLL_FLING_CANCEL : ET_SCROLL_FLING_START; 373 return is_cancel ? ET_SCROLL_FLING_CANCEL : ET_SCROLL_FLING_START;
349 } else if (DeviceDataManagerX11::GetInstance()->IsScrollEvent( 374 } else if (DeviceDataManagerX11::GetInstance()->IsScrollEvent(
350 native_event)) { 375 native_event)) {
351 return IsTouchpadEvent(native_event) ? ET_SCROLL : ET_MOUSEWHEEL; 376 return IsTouchpadEvent(native_event) ? ET_SCROLL : ET_MOUSEWHEEL;
352 } else if (DeviceDataManagerX11::GetInstance()->IsCMTMetricsEvent( 377 } else if (DeviceDataManagerX11::GetInstance()->IsCMTMetricsEvent(
353 native_event)) { 378 native_event)) {
354 return ET_UMA_DATA; 379 return ET_UMA_DATA;
355 } else if (GetButtonMaskForX2Event(xievent)) { 380 } else if (GetButtonMaskForX2Event(xievent)) {
356 return ET_MOUSE_DRAGGED; 381 return ET_MOUSE_DRAGGED;
357 } else {
358 return ET_MOUSE_MOVED;
359 } 382 }
383 return ET_MOUSE_MOVED;
360 } 384 }
385 case XI_KeyPress:
386 return ET_KEY_PRESSED;
387 case XI_KeyRelease:
388 return ET_KEY_RELEASED;
361 } 389 }
362 } 390 }
363 default: 391 default:
364 break; 392 break;
365 } 393 }
366 return ET_UNKNOWN; 394 return ET_UNKNOWN;
367 } 395 }
368 396
369 int EventFlagsFromNative(const base::NativeEvent& native_event) { 397 int EventFlagsFromNative(const base::NativeEvent& native_event) {
370 switch (native_event->type) { 398 switch (native_event->type) {
371 case KeyPress: 399 case KeyPress:
372 case KeyRelease: { 400 case KeyRelease: {
373 XModifierStateWatcher::GetInstance()->UpdateStateFromEvent(native_event); 401 XModifierStateWatcher::GetInstance()->UpdateStateFromXEvent(native_event);
374 return GetEventFlagsFromXKeyEvent(native_event); 402 return GetEventFlagsFromXKeyEvent(native_event);
375 } 403 }
376 case ButtonPress: 404 case ButtonPress:
377 case ButtonRelease: { 405 case ButtonRelease: {
378 int flags = GetEventFlagsFromXState(native_event->xbutton.state); 406 int flags = GetEventFlagsFromXState(native_event->xbutton.state);
379 const EventType type = EventTypeFromNative(native_event); 407 const EventType type = EventTypeFromNative(native_event);
380 if (type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED) 408 if (type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED)
381 flags |= GetEventFlagsForButton(native_event->xbutton.button); 409 flags |= GetEventFlagsForButton(native_event->xbutton.button);
382 return flags; 410 return flags;
383 } 411 }
(...skipping 15 matching lines...) Expand all
399 GetEventFlagsFromXState(xievent->mods.effective) | 427 GetEventFlagsFromXState(xievent->mods.effective) |
400 GetEventFlagsFromXState( 428 GetEventFlagsFromXState(
401 XModifierStateWatcher::GetInstance()->state()); 429 XModifierStateWatcher::GetInstance()->state());
402 break; 430 break;
403 #endif 431 #endif
404 case XI_ButtonPress: 432 case XI_ButtonPress:
405 case XI_ButtonRelease: { 433 case XI_ButtonRelease: {
406 const bool touch = 434 const bool touch =
407 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid); 435 TouchFactory::GetInstance()->IsTouchDevice(xievent->sourceid);
408 int flags = GetButtonMaskForX2Event(xievent) | 436 int flags = GetButtonMaskForX2Event(xievent) |
409 GetEventFlagsFromXState(xievent->mods.effective); 437 GetEventFlagsFromXState(xievent->mods.effective);
410 if (touch) { 438 if (touch) {
411 flags |= GetEventFlagsFromXState( 439 flags |= GetEventFlagsFromXState(
412 XModifierStateWatcher::GetInstance()->state()); 440 XModifierStateWatcher::GetInstance()->state());
413 } 441 }
414 442
415 const EventType type = EventTypeFromNative(native_event); 443 const EventType type = EventTypeFromNative(native_event);
416 int button = EventButtonFromNative(native_event); 444 int button = EventButtonFromNative(native_event);
417 if ((type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED) && !touch) 445 if ((type == ET_MOUSE_PRESSED || type == ET_MOUSE_RELEASED) && !touch)
418 flags |= GetEventFlagsForButton(button); 446 flags |= GetEventFlagsForButton(button);
419 return flags; 447 return flags;
420 } 448 }
421 case XI_Motion: 449 case XI_Motion:
422 return GetButtonMaskForX2Event(xievent) | 450 return GetButtonMaskForX2Event(xievent) |
423 GetEventFlagsFromXState(xievent->mods.effective); 451 GetEventFlagsFromXState(xievent->mods.effective);
452 case XI_KeyPress:
453 case XI_KeyRelease: {
454 XModifierStateWatcher::GetInstance()->UpdateStateFromXEvent(
455 native_event);
456 return GetEventFlagsFromXGenericEvent(native_event);
457 }
424 } 458 }
425 } 459 }
426 } 460 }
427 return 0; 461 return 0;
428 } 462 }
429 463
430 base::TimeDelta EventTimeFromNative(const base::NativeEvent& native_event) { 464 base::TimeDelta EventTimeFromNative(const base::NativeEvent& native_event) {
431 switch(native_event->type) { 465 switch(native_event->type) {
432 case KeyPress: 466 case KeyPress:
433 case KeyRelease: 467 case KeyRelease:
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 DeviceDataManagerX11::GetInstance()->GetGestureTimes( 775 DeviceDataManagerX11::GetInstance()->GetGestureTimes(
742 native_event, start_time, end_time); 776 native_event, start_time, end_time);
743 return true; 777 return true;
744 } 778 }
745 779
746 bool IsTouchpadEvent(const base::NativeEvent& event) { 780 bool IsTouchpadEvent(const base::NativeEvent& event) {
747 return DeviceDataManagerX11::GetInstance()->IsTouchpadXInputEvent(event); 781 return DeviceDataManagerX11::GetInstance()->IsTouchpadXInputEvent(event);
748 } 782 }
749 783
750 } // namespace ui 784 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/test/events_test_utils_x11.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698