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

Side by Side Diff: content/browser/renderer_host/web_input_event_aurax11.cc

Issue 8353005: aura: Make keyevents for renderers work correctly in X11. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 9 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // Portions based heavily on: 5 // Portions based heavily on:
6 // third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFactory.cpp 6 // third_party/WebKit/Source/WebKit/chromium/public/gtk/WebInputEventFactory.cpp
7 // 7 //
8 /* 8 /*
9 * Copyright (C) 2006-2011 Google Inc. All rights reserved. 9 * Copyright (C) 2006-2011 Google Inc. All rights reserved.
10 * 10 *
(...skipping 24 matching lines...) Expand all
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */ 36 */
37 37
38 #include "content/browser/renderer_host/web_input_event_aura.h" 38 #include "content/browser/renderer_host/web_input_event_aura.h"
39 39
40 #include <cstdlib> 40 #include <cstdlib>
41 #include <X11/Xlib.h> 41 #include <X11/Xlib.h>
42 42
43 #include "base/event_types.h" 43 #include "base/event_types.h"
44 #include "base/logging.h" 44 #include "base/logging.h"
45 #include "ui/aura/event.h"
46 #include "ui/base/events.h"
45 #include "ui/base/keycodes/keyboard_codes.h" 47 #include "ui/base/keycodes/keyboard_codes.h"
48 #include "ui/base/keycodes/keyboard_code_conversion_x.h"
46 49
47 namespace content { 50 namespace content {
48 51
49 // chromium WebKit does not provide a WebInputEventFactory for X11, so we have 52 // chromium WebKit does not provide a WebInputEventFactory for X11, so we have
50 // to do the work here ourselves. 53 // to do the work here ourselves.
51 54
52 namespace { 55 namespace {
53 56
54 double XEventTimeToWebEventTime(Time time) { 57 double XEventTimeToWebEventTime(Time time) {
55 // Convert from time in ms to time in s. 58 // Convert from time in ms to time in s.
56 return time / 1000.0; 59 return time / 1000.0;
57 } 60 }
58 61
62 int EventFlagsToWebEventModifiers(int flags) {
63 int modifiers = 0;
64 if (flags & ui::EF_SHIFT_DOWN)
65 modifiers |= WebKit::WebInputEvent::ShiftKey;
66 if (flags & ui::EF_CONTROL_DOWN)
67 modifiers |= WebKit::WebInputEvent::ControlKey;
68 if (flags & ui::EF_ALT_DOWN)
69 modifiers |= WebKit::WebInputEvent::AltKey;
70 // TODO(beng): MetaKey/META_MASK
71 if (flags & ui::EF_LEFT_BUTTON_DOWN)
72 modifiers |= WebKit::WebInputEvent::LeftButtonDown;
73 if (flags & ui::EF_MIDDLE_BUTTON_DOWN)
74 modifiers |= WebKit::WebInputEvent::MiddleButtonDown;
75 if (flags & ui::EF_RIGHT_BUTTON_DOWN)
76 modifiers |= WebKit::WebInputEvent::RightButtonDown;
77 if (flags & ui::EF_CAPS_LOCK_DOWN)
78 modifiers |= WebKit::WebInputEvent::CapsLockOn;
79 return modifiers;
80 }
81
59 int XStateToWebEventModifiers(unsigned int state) { 82 int XStateToWebEventModifiers(unsigned int state) {
60 int modifiers = 0; 83 int modifiers = 0;
61 if (state & ShiftMask) 84 if (state & ShiftMask)
62 modifiers |= WebKit::WebInputEvent::ShiftKey; 85 modifiers |= WebKit::WebInputEvent::ShiftKey;
63 if (state & ControlMask) 86 if (state & ControlMask)
64 modifiers |= WebKit::WebInputEvent::ControlKey; 87 modifiers |= WebKit::WebInputEvent::ControlKey;
65 if (state & Mod1Mask) 88 if (state & Mod1Mask)
66 modifiers |= WebKit::WebInputEvent::AltKey; 89 modifiers |= WebKit::WebInputEvent::AltKey;
67 // TODO(beng): MetaKey/META_MASK 90 // TODO(beng): MetaKey/META_MASK
68 if (state & Button1Mask) 91 if (state & Button1Mask)
69 modifiers |= WebKit::WebInputEvent::LeftButtonDown; 92 modifiers |= WebKit::WebInputEvent::LeftButtonDown;
70 if (state & Button2Mask) 93 if (state & Button2Mask)
71 modifiers |= WebKit::WebInputEvent::MiddleButtonDown; 94 modifiers |= WebKit::WebInputEvent::MiddleButtonDown;
72 if (state & Button3Mask) 95 if (state & Button3Mask)
73 modifiers |= WebKit::WebInputEvent::RightButtonDown; 96 modifiers |= WebKit::WebInputEvent::RightButtonDown;
74 if (state & LockMask) 97 if (state & LockMask)
75 modifiers |= WebKit::WebInputEvent::CapsLockOn; 98 modifiers |= WebKit::WebInputEvent::CapsLockOn;
76 if (state & Mod2Mask) 99 if (state & Mod2Mask)
77 modifiers |= WebKit::WebInputEvent::NumLockOn; 100 modifiers |= WebKit::WebInputEvent::NumLockOn;
78 return modifiers; 101 return modifiers;
79 } 102 }
80 103
81 int XKeyEventToWindowsKeyCode(XKeyEvent* event) { 104 int XKeyEventToWindowsKeyCode(XKeyEvent* event) {
82 // TODO(beng): 105 return ui::KeyboardCodeFromXKeyEvent((XEvent*)event);
83 return 0;
84 } 106 }
85 107
86 // From 108 // From
87 // third_party/WebKit/Source/WebKit/chromium/src/gtk/WebInputEventFactory.cpp: 109 // third_party/WebKit/Source/WebKit/chromium/src/gtk/WebInputEventFactory.cpp:
88 WebKit::WebUChar GetControlCharacter(int windows_key_code, bool shift) { 110 WebKit::WebUChar GetControlCharacter(int windows_key_code, bool shift) {
89 if (windows_key_code >= ui::VKEY_A && 111 if (windows_key_code >= ui::VKEY_A &&
90 windows_key_code <= ui::VKEY_Z) { 112 windows_key_code <= ui::VKEY_Z) {
91 // ctrl-A ~ ctrl-Z map to \x01 ~ \x1A 113 // ctrl-A ~ ctrl-Z map to \x01 ~ \x1A
92 return windows_key_code - ui::VKEY_A + 1; 114 return windows_key_code - ui::VKEY_A + 1;
93 } 115 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 return WebKit::WebMouseEvent::ButtonLeft; 170 return WebKit::WebMouseEvent::ButtonLeft;
149 if (state & Button2MotionMask) 171 if (state & Button2MotionMask)
150 return WebKit::WebMouseEvent::ButtonMiddle; 172 return WebKit::WebMouseEvent::ButtonMiddle;
151 if (state & Button3MotionMask) 173 if (state & Button3MotionMask)
152 return WebKit::WebMouseEvent::ButtonRight; 174 return WebKit::WebMouseEvent::ButtonRight;
153 return WebKit::WebMouseEvent::ButtonNone; 175 return WebKit::WebMouseEvent::ButtonNone;
154 } 176 }
155 177
156 // We have to count clicks (for double-clicks) manually. 178 // We have to count clicks (for double-clicks) manually.
157 unsigned int g_num_clicks = 0; 179 unsigned int g_num_clicks = 0;
158 ::Window* g_last_click_window = NULL; 180 double g_last_click_time = 0.0;
159 Time g_last_click_time = 0;
160 int g_last_click_x = 0; 181 int g_last_click_x = 0;
161 int g_last_click_y = 0; 182 int g_last_click_y = 0;
162 WebKit::WebMouseEvent::Button g_last_click_button = 183 WebKit::WebMouseEvent::Button g_last_click_button =
163 WebKit::WebMouseEvent::ButtonNone; 184 WebKit::WebMouseEvent::ButtonNone;
164 185
165 bool ShouldForgetPreviousClick(::Window* window, Time time, int x, int y) { 186 bool ShouldForgetPreviousClick(double time, int x, int y) {
166 if (window != g_last_click_window) 187 const double double_click_time = 0.250; // in seconds
167 return true;
168
169 const Time double_click_time = 250;
170 const int double_click_distance = 5; 188 const int double_click_distance = 5;
171 return (time - g_last_click_time) > double_click_time 189 return (time - g_last_click_time) > double_click_time ||
172 || std::abs(x - g_last_click_x) > double_click_distance 190 std::abs(x - g_last_click_x) > double_click_distance ||
173 || std::abs(y - g_last_click_y) > double_click_distance; 191 std::abs(y - g_last_click_y) > double_click_distance;
174 } 192 }
175 193
176 void ResetClickCountState() { 194 void ResetClickCountState() {
177 g_num_clicks = 0; 195 g_num_clicks = 0;
178 g_last_click_window = NULL; 196 g_last_click_time = 0.0;
179 g_last_click_time = 0;
180 g_last_click_x = 0; 197 g_last_click_x = 0;
181 g_last_click_y = 0; 198 g_last_click_y = 0;
182 g_last_click_button = WebKit::WebMouseEvent::ButtonNone; 199 g_last_click_button = WebKit::WebMouseEvent::ButtonNone;
183 } 200 }
184 201
185 void InitWebKitEventFromButtonEvent(WebKit::WebMouseEvent* webkit_event, 202 } // namespace
186 XButtonEvent* native_event) {
187 webkit_event->modifiers = XStateToWebEventModifiers(native_event->state);
188 webkit_event->timeStampSeconds = XEventTimeToWebEventTime(native_event->time);
189 203
190 webkit_event->x = native_event->x; 204 WebKit::WebMouseEvent MakeWebMouseEventFromAuraEvent(aura::MouseEvent* event) {
191 webkit_event->y = native_event->y; 205 WebKit::WebMouseEvent webkit_event;
192 webkit_event->windowX = webkit_event->x;
193 webkit_event->windowY = webkit_event->y;
194 webkit_event->globalX = native_event->x_root;
195 webkit_event->globalY = native_event->y_root;
196 206
197 switch (native_event->type) { 207 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
198 case ButtonPress: 208 webkit_event.timeStampSeconds = event->time_stamp().ToDoubleT();
199 webkit_event->type = WebKit::WebInputEvent::MouseDown; 209
200 webkit_event->button = ButtonFromXButton(native_event->button); 210 webkit_event.button = WebKit::WebMouseEvent::ButtonNone;
201 if (!ShouldForgetPreviousClick(&native_event->window, 211 if (event->flags() & ui::EF_LEFT_BUTTON_DOWN)
202 native_event->time, 212 webkit_event.button = WebKit::WebMouseEvent::ButtonLeft;
203 native_event->x, 213 if (event->flags() & ui::EF_MIDDLE_BUTTON_DOWN)
204 native_event->y) && 214 webkit_event.button = WebKit::WebMouseEvent::ButtonMiddle;
205 webkit_event->button == g_last_click_button) { 215 if (event->flags() & ui::EF_RIGHT_BUTTON_DOWN)
216 webkit_event.button = WebKit::WebMouseEvent::ButtonRight;
217
218 switch (event->type()) {
219 case ui::ET_MOUSE_PRESSED:
220 webkit_event.type = WebKit::WebInputEvent::MouseDown;
221 if (!ShouldForgetPreviousClick(event->time_stamp().ToDoubleT(),
222 event->location().x(), event->location().y()) &&
223 webkit_event.button == g_last_click_button) {
206 ++g_num_clicks; 224 ++g_num_clicks;
207 } else { 225 } else {
208 g_num_clicks = 1; 226 g_num_clicks = 1;
209 g_last_click_window = &native_event->window; 227 g_last_click_time = event->time_stamp().ToDoubleT();
210 g_last_click_x = native_event->x; 228 g_last_click_x = event->location().x();
211 g_last_click_y = native_event->y; 229 g_last_click_y = event->location().y();
212 g_last_click_button = webkit_event->button; 230 g_last_click_button = webkit_event.button;
213 } 231 }
232 webkit_event.clickCount = g_num_clicks;
214 break; 233 break;
215 case ButtonRelease: 234 case ui::ET_MOUSE_RELEASED:
216 webkit_event->type = WebKit::WebInputEvent::MouseUp; 235 webkit_event.type = WebKit::WebInputEvent::MouseUp;
217 webkit_event->button = ButtonFromXButton(native_event->button); 236 break;
237 case ui::ET_MOUSE_ENTERED:
238 case ui::ET_MOUSE_EXITED:
239 case ui::ET_MOUSE_MOVED:
240 case ui::ET_MOUSE_DRAGGED:
241 webkit_event.type = WebKit::WebInputEvent::MouseMove;
242 if (ShouldForgetPreviousClick(event->time_stamp().ToDoubleT(),
243 event->location().x(), event->location().y()))
244 ResetClickCountState();
218 break; 245 break;
219 default: 246 default:
220 NOTREACHED(); 247 NOTIMPLEMENTED() << "Received unexpected event: " << event->type();
221 break; 248 break;
222 } 249 }
223 webkit_event->clickCount = g_num_clicks;
224 }
225 250
226 void InitWebKitEventFromMotionEvent(WebKit::WebMouseEvent* webkit_event,
227 XMotionEvent* native_event) {
228 webkit_event->modifiers = XStateToWebEventModifiers(native_event->state);
229 webkit_event->timeStampSeconds = XEventTimeToWebEventTime(native_event->time);
230
231 webkit_event->x = native_event->x;
232 webkit_event->y = native_event->y;
233 webkit_event->windowX = webkit_event->x;
234 webkit_event->windowY = webkit_event->y;
235 webkit_event->globalX = native_event->x_root;
236 webkit_event->globalY = native_event->y_root;
237
238 webkit_event->type = WebKit::WebInputEvent::MouseMove;
239 webkit_event->button = ButtonFromXState(native_event->state);
240 if (ShouldForgetPreviousClick(&native_event->window,
241 native_event->time,
242 native_event->x,
243 native_event->y)) {
244 ResetClickCountState();
245 }
246 }
247
248 } // namespace
249
250 WebKit::WebMouseEvent MakeUntranslatedWebMouseEventFromNativeEvent(
251 base::NativeEvent native_event) {
252 WebKit::WebMouseEvent webkit_event;
253
254 // In X, button and mouse movement events are different event types that
255 // require different handling.
256 // TODO(sadrul): Add support for XInput2 events.
257 switch (native_event->type) {
258 case ButtonPress:
259 case ButtonRelease:
260 InitWebKitEventFromButtonEvent(&webkit_event, &native_event->xbutton);
261 break;
262 case MotionNotify:
263 InitWebKitEventFromMotionEvent(&webkit_event, &native_event->xmotion);
264 break;
265 default:
266 NOTREACHED();
267 break;
268 }
269 return webkit_event; 251 return webkit_event;
270 } 252 }
271 253
272 WebKit::WebKeyboardEvent MakeWebKeyboardEventFromNativeEvent( 254 WebKit::WebKeyboardEvent MakeWebKeyboardEventFromNativeEvent(
273 base::NativeEvent native_event) { 255 base::NativeEvent native_event) {
274 WebKit::WebKeyboardEvent webkit_event; 256 WebKit::WebKeyboardEvent webkit_event;
275 XKeyEvent* native_key_event = &native_event->xkey; 257 XKeyEvent* native_key_event = &native_event->xkey;
276 258
277 webkit_event.timeStampSeconds = 259 webkit_event.timeStampSeconds =
278 XEventTimeToWebEventTime(native_key_event->time); 260 XEventTimeToWebEventTime(native_key_event->time);
(...skipping 13 matching lines...) Expand all
292 if (webkit_event.modifiers & WebKit::WebInputEvent::AltKey) 274 if (webkit_event.modifiers & WebKit::WebInputEvent::AltKey)
293 webkit_event.isSystemKey = true; 275 webkit_event.isSystemKey = true;
294 276
295 webkit_event.windowsKeyCode = XKeyEventToWindowsKeyCode(native_key_event); 277 webkit_event.windowsKeyCode = XKeyEventToWindowsKeyCode(native_key_event);
296 webkit_event.nativeKeyCode = native_key_event->keycode; 278 webkit_event.nativeKeyCode = native_key_event->keycode;
297 279
298 if (webkit_event.windowsKeyCode == ui::VKEY_RETURN) { 280 if (webkit_event.windowsKeyCode == ui::VKEY_RETURN) {
299 webkit_event.unmodifiedText[0] = '\r'; 281 webkit_event.unmodifiedText[0] = '\r';
300 } else { 282 } else {
301 webkit_event.unmodifiedText[0] = 283 webkit_event.unmodifiedText[0] =
302 static_cast<WebKit::WebUChar>(native_key_event->keycode); 284 ui::DefaultXKeysymFromHardwareKeycode(native_key_event->keycode);
303 } 285 }
304 286
305 if (webkit_event.modifiers & WebKit::WebInputEvent::ControlKey) { 287 if (webkit_event.modifiers & WebKit::WebInputEvent::ControlKey) {
306 webkit_event.text[0] = 288 webkit_event.text[0] =
307 GetControlCharacter( 289 GetControlCharacter(
308 webkit_event.windowsKeyCode, 290 webkit_event.windowsKeyCode,
309 webkit_event.modifiers & WebKit::WebInputEvent::ShiftKey); 291 webkit_event.modifiers & WebKit::WebInputEvent::ShiftKey);
310 } else { 292 } else {
311 webkit_event.text[0] = webkit_event.unmodifiedText[0]; 293 webkit_event.text[0] = webkit_event.unmodifiedText[0];
312 } 294 }
313 295
314 webkit_event.setKeyIdentifierFromWindowsKeyCode(); 296 webkit_event.setKeyIdentifierFromWindowsKeyCode();
315 297
316 // TODO: IsAutoRepeat/IsKeyPad? 298 // TODO: IsAutoRepeat/IsKeyPad?
317 299
318 return webkit_event; 300 return webkit_event;
319 } 301 }
320 302
321 } // namespace content 303 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/web_input_event_aura.cc ('k') | ui/base/keycodes/keyboard_code_conversion_x.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698