Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / renderer_host / web_input_event_aura.cc
bloba4cf12b0e51041a305be9a491011f1d83cef90e9
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
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/web_input_event_aura.h"
7 #include "content/browser/renderer_host/ui_events_helper.h"
8 #include "ui/aura/window.h"
9 #include "ui/events/event.h"
10 #include "ui/events/event_utils.h"
12 #if defined(USE_OZONE)
13 #include "ui/events/keycodes/keyboard_code_conversion.h"
14 #endif
16 namespace content {
18 #if defined(OS_WIN)
19 blink::WebMouseEvent MakeUntranslatedWebMouseEventFromNativeEvent(
20 const base::NativeEvent& native_event);
21 blink::WebMouseWheelEvent MakeUntranslatedWebMouseWheelEventFromNativeEvent(
22 const base::NativeEvent& native_event);
23 blink::WebKeyboardEvent MakeWebKeyboardEventFromNativeEvent(
24 const base::NativeEvent& native_event);
25 blink::WebGestureEvent MakeWebGestureEventFromNativeEvent(
26 const base::NativeEvent& native_event);
27 #elif defined(USE_X11)
28 blink::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent(
29 ui::KeyEvent* event);
30 #elif defined(USE_OZONE)
31 blink::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent(
32 ui::KeyEvent* event) {
33 const base::NativeEvent& native_event = event->native_event();
34 ui::EventType type = ui::EventTypeFromNative(native_event);
35 blink::WebKeyboardEvent webkit_event;
37 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF();
38 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
40 switch (type) {
41 case ui::ET_KEY_PRESSED:
42 webkit_event.type = event->is_char() ? blink::WebInputEvent::Char :
43 blink::WebInputEvent::RawKeyDown;
44 break;
45 case ui::ET_KEY_RELEASED:
46 webkit_event.type = blink::WebInputEvent::KeyUp;
47 break;
48 default:
49 NOTREACHED();
52 if (webkit_event.modifiers & blink::WebInputEvent::AltKey)
53 webkit_event.isSystemKey = true;
55 wchar_t character = ui::KeyboardCodeFromNative(native_event);
56 webkit_event.windowsKeyCode = character;
57 webkit_event.nativeKeyCode = character;
59 if (webkit_event.windowsKeyCode == ui::VKEY_RETURN)
60 webkit_event.unmodifiedText[0] = '\r';
61 else
62 webkit_event.unmodifiedText[0] = ui::GetCharacterFromKeyCode(
63 ui::KeyboardCodeFromNative(native_event),
64 ui::EventFlagsFromNative(native_event));
66 if (webkit_event.modifiers & blink::WebInputEvent::ControlKey) {
67 webkit_event.text[0] = ui::GetControlCharacterForKeycode(
68 webkit_event.windowsKeyCode,
69 webkit_event.modifiers & blink::WebInputEvent::ShiftKey);
70 } else {
71 webkit_event.text[0] = webkit_event.unmodifiedText[0];
74 webkit_event.setKeyIdentifierFromWindowsKeyCode();
76 return webkit_event;
78 #endif
79 #if defined(USE_X11) || defined(USE_OZONE)
80 blink::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent(
81 ui::ScrollEvent* event) {
82 blink::WebMouseWheelEvent webkit_event;
84 webkit_event.type = blink::WebInputEvent::MouseWheel;
85 webkit_event.button = blink::WebMouseEvent::ButtonNone;
86 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
87 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF();
88 webkit_event.hasPreciseScrollingDeltas = true;
90 float offset_ordinal_x = 0.f;
91 float offset_ordinal_y = 0.f;
92 if ((event->flags() & ui::EF_SHIFT_DOWN) != 0 && event->x_offset() == 0) {
93 webkit_event.deltaX = event->y_offset();
94 webkit_event.deltaY = 0;
95 offset_ordinal_x = event->y_offset_ordinal();
96 offset_ordinal_y = event->x_offset_ordinal();
97 } else {
98 webkit_event.deltaX = event->x_offset();
99 webkit_event.deltaY = event->y_offset();
100 offset_ordinal_x = event->x_offset_ordinal();
101 offset_ordinal_y = event->y_offset_ordinal();
104 if (offset_ordinal_x != 0.f && webkit_event.deltaX != 0.f)
105 webkit_event.accelerationRatioX = offset_ordinal_x / webkit_event.deltaX;
106 webkit_event.wheelTicksX = webkit_event.deltaX / kPixelsPerTick;
107 webkit_event.wheelTicksY = webkit_event.deltaY / kPixelsPerTick;
108 if (offset_ordinal_y != 0.f && webkit_event.deltaY != 0.f)
109 webkit_event.accelerationRatioY = offset_ordinal_y / webkit_event.deltaY;
110 return webkit_event;
113 blink::WebGestureEvent MakeWebGestureEventFromAuraEvent(
114 ui::ScrollEvent* event) {
115 blink::WebGestureEvent webkit_event;
117 switch (event->type()) {
118 case ui::ET_SCROLL_FLING_START:
119 webkit_event.type = blink::WebInputEvent::GestureFlingStart;
120 webkit_event.data.flingStart.velocityX = event->x_offset();
121 webkit_event.data.flingStart.velocityY = event->y_offset();
122 break;
123 case ui::ET_SCROLL_FLING_CANCEL:
124 webkit_event.type = blink::WebInputEvent::GestureFlingCancel;
125 break;
126 case ui::ET_SCROLL:
127 NOTREACHED() << "Invalid gesture type: " << event->type();
128 break;
129 default:
130 NOTREACHED() << "Unknown gesture type: " << event->type();
133 webkit_event.sourceDevice = blink::WebGestureDeviceTouchpad;
134 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
135 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF();
136 return webkit_event;
139 #endif
141 blink::WebMouseEvent MakeWebMouseEventFromAuraEvent(
142 ui::MouseEvent* event);
143 blink::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent(
144 ui::MouseWheelEvent* event);
146 // General approach:
148 // ui::Event only carries a subset of possible event data provided to Aura by
149 // the host platform. WebKit utilizes a larger subset of that information than
150 // Aura itself. WebKit includes some built in cracking functionality that we
151 // rely on to obtain this information cleanly and consistently.
153 // The only place where an ui::Event's data differs from what the underlying
154 // base::NativeEvent would provide is position data, since we would like to
155 // provide coordinates relative to the aura::Window that is hosting the
156 // renderer, not the top level platform window.
158 // The approach is to fully construct a blink::WebInputEvent from the
159 // ui::Event's base::NativeEvent, and then replace the coordinate fields with
160 // the translated values from the ui::Event.
162 // The exception is mouse events on linux. The ui::MouseEvent contains enough
163 // necessary information to construct a WebMouseEvent. So instead of extracting
164 // the information from the XEvent, which can be tricky when supporting both
165 // XInput2 and XInput, the WebMouseEvent is constructed from the
166 // ui::MouseEvent. This will not be necessary once only XInput2 is supported.
169 blink::WebMouseEvent MakeWebMouseEvent(ui::MouseEvent* event) {
170 // Construct an untranslated event from the platform event data.
171 blink::WebMouseEvent webkit_event =
172 #if defined(OS_WIN)
173 // On Windows we have WM_ events comming from desktop and pure aura
174 // events comming from metro mode.
175 event->native_event().message ?
176 MakeUntranslatedWebMouseEventFromNativeEvent(event->native_event()) :
177 MakeWebMouseEventFromAuraEvent(event);
178 #else
179 MakeWebMouseEventFromAuraEvent(event);
180 #endif
181 // Replace the event's coordinate fields with translated position data from
182 // |event|.
183 webkit_event.windowX = webkit_event.x = event->x();
184 webkit_event.windowY = webkit_event.y = event->y();
186 #if defined(OS_WIN)
187 if (event->native_event().message)
188 return webkit_event;
189 #endif
190 const gfx::Point root_point = event->root_location();
191 webkit_event.globalX = root_point.x();
192 webkit_event.globalY = root_point.y();
194 return webkit_event;
197 blink::WebMouseWheelEvent MakeWebMouseWheelEvent(ui::MouseWheelEvent* event) {
198 #if defined(OS_WIN)
199 // Construct an untranslated event from the platform event data.
200 blink::WebMouseWheelEvent webkit_event = event->native_event().message ?
201 MakeUntranslatedWebMouseWheelEventFromNativeEvent(event->native_event()) :
202 MakeWebMouseWheelEventFromAuraEvent(event);
203 #else
204 blink::WebMouseWheelEvent webkit_event =
205 MakeWebMouseWheelEventFromAuraEvent(event);
206 #endif
208 // Replace the event's coordinate fields with translated position data from
209 // |event|.
210 webkit_event.windowX = webkit_event.x = event->x();
211 webkit_event.windowY = webkit_event.y = event->y();
213 const gfx::Point root_point = event->root_location();
214 webkit_event.globalX = root_point.x();
215 webkit_event.globalY = root_point.y();
217 return webkit_event;
220 blink::WebMouseWheelEvent MakeWebMouseWheelEvent(ui::ScrollEvent* event) {
221 #if defined(OS_WIN)
222 // Construct an untranslated event from the platform event data.
223 blink::WebMouseWheelEvent webkit_event =
224 MakeUntranslatedWebMouseWheelEventFromNativeEvent(event->native_event());
225 #else
226 blink::WebMouseWheelEvent webkit_event =
227 MakeWebMouseWheelEventFromAuraEvent(event);
228 #endif
230 // Replace the event's coordinate fields with translated position data from
231 // |event|.
232 webkit_event.windowX = webkit_event.x = event->x();
233 webkit_event.windowY = webkit_event.y = event->y();
235 const gfx::Point root_point = event->root_location();
236 webkit_event.globalX = root_point.x();
237 webkit_event.globalY = root_point.y();
239 return webkit_event;
242 blink::WebKeyboardEvent MakeWebKeyboardEvent(ui::KeyEvent* event) {
243 if (!event->HasNativeEvent())
244 return blink::WebKeyboardEvent();
246 // Windows can figure out whether or not to construct a RawKeyDown or a Char
247 // WebInputEvent based on the type of message carried in
248 // event->native_event(). X11 is not so fortunate, there is no separate
249 // translated event type, so DesktopHostLinux sends an extra KeyEvent with
250 // is_char() == true. We need to pass the ui::KeyEvent to the X11 function
251 // to detect this case so the right event type can be constructed.
252 #if defined(OS_WIN)
253 // Key events require no translation by the aura system.
254 return MakeWebKeyboardEventFromNativeEvent(event->native_event());
255 #else
256 return MakeWebKeyboardEventFromAuraEvent(event);
257 #endif
260 blink::WebGestureEvent MakeWebGestureEvent(ui::GestureEvent* event) {
261 blink::WebGestureEvent gesture_event;
262 #if defined(OS_WIN)
263 if (event->HasNativeEvent())
264 gesture_event = MakeWebGestureEventFromNativeEvent(event->native_event());
265 else
266 gesture_event = MakeWebGestureEventFromUIEvent(*event);
267 #else
268 gesture_event = MakeWebGestureEventFromUIEvent(*event);
269 #endif
271 gesture_event.x = event->x();
272 gesture_event.y = event->y();
274 const gfx::Point root_point = event->root_location();
275 gesture_event.globalX = root_point.x();
276 gesture_event.globalY = root_point.y();
278 return gesture_event;
281 blink::WebGestureEvent MakeWebGestureEvent(ui::ScrollEvent* event) {
282 blink::WebGestureEvent gesture_event;
284 #if defined(OS_WIN)
285 gesture_event = MakeWebGestureEventFromNativeEvent(event->native_event());
286 #else
287 gesture_event = MakeWebGestureEventFromAuraEvent(event);
288 #endif
290 gesture_event.x = event->x();
291 gesture_event.y = event->y();
293 const gfx::Point root_point = event->root_location();
294 gesture_event.globalX = root_point.x();
295 gesture_event.globalY = root_point.y();
297 return gesture_event;
300 blink::WebGestureEvent MakeWebGestureEventFlingCancel() {
301 blink::WebGestureEvent gesture_event;
303 // All other fields are ignored on a GestureFlingCancel event.
304 gesture_event.type = blink::WebInputEvent::GestureFlingCancel;
305 gesture_event.sourceDevice = blink::WebGestureDeviceTouchpad;
306 return gesture_event;
309 blink::WebMouseEvent MakeWebMouseEventFromAuraEvent(ui::MouseEvent* event) {
310 blink::WebMouseEvent webkit_event;
312 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
313 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF();
315 webkit_event.button = blink::WebMouseEvent::ButtonNone;
316 if (event->flags() & ui::EF_LEFT_MOUSE_BUTTON)
317 webkit_event.button = blink::WebMouseEvent::ButtonLeft;
318 if (event->flags() & ui::EF_MIDDLE_MOUSE_BUTTON)
319 webkit_event.button = blink::WebMouseEvent::ButtonMiddle;
320 if (event->flags() & ui::EF_RIGHT_MOUSE_BUTTON)
321 webkit_event.button = blink::WebMouseEvent::ButtonRight;
323 switch (event->type()) {
324 case ui::ET_MOUSE_PRESSED:
325 webkit_event.type = blink::WebInputEvent::MouseDown;
326 webkit_event.clickCount = event->GetClickCount();
327 break;
328 case ui::ET_MOUSE_RELEASED:
329 webkit_event.type = blink::WebInputEvent::MouseUp;
330 webkit_event.clickCount = event->GetClickCount();
331 break;
332 case ui::ET_MOUSE_ENTERED:
333 case ui::ET_MOUSE_EXITED:
334 case ui::ET_MOUSE_MOVED:
335 case ui::ET_MOUSE_DRAGGED:
336 webkit_event.type = blink::WebInputEvent::MouseMove;
337 break;
338 default:
339 NOTIMPLEMENTED() << "Received unexpected event: " << event->type();
340 break;
343 return webkit_event;
346 blink::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent(
347 ui::MouseWheelEvent* event) {
348 blink::WebMouseWheelEvent webkit_event;
350 webkit_event.type = blink::WebInputEvent::MouseWheel;
351 webkit_event.button = blink::WebMouseEvent::ButtonNone;
352 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags());
353 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF();
355 if ((event->flags() & ui::EF_SHIFT_DOWN) != 0 && event->x_offset() == 0) {
356 webkit_event.deltaX = event->y_offset();
357 webkit_event.deltaY = 0;
358 } else {
359 webkit_event.deltaX = event->x_offset();
360 webkit_event.deltaY = event->y_offset();
363 webkit_event.wheelTicksX = webkit_event.deltaX / kPixelsPerTick;
364 webkit_event.wheelTicksY = webkit_event.deltaY / kPixelsPerTick;
366 return webkit_event;
369 } // namespace content