[Session restore] Rename group name Enabled to Restore.
[chromium-blink-merge.git] / content / browser / renderer_host / web_input_event_aura.cc
blobce015d6691a9922ab8ec8383f13069922d600fb3
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/input/web_input_event_util.h"
8 #include "content/browser/renderer_host/ui_events_helper.h"
9 #include "ui/aura/client/screen_position_client.h"
10 #include "ui/aura/window.h"
11 #include "ui/events/blink/blink_event_util.h"
12 #include "ui/events/event.h"
13 #include "ui/events/event_utils.h"
14 #include "ui/events/keycodes/dom4/keycode_converter.h"
16 namespace content {
18 namespace {
20 gfx::Point GetScreenLocationFromEvent(const ui::LocatedEvent& event) {
21 if (!event.target())
22 return event.root_location();
24 aura::Window* root =
25 static_cast<aura::Window*>(event.target())->GetRootWindow();
26 aura::client::ScreenPositionClient* spc =
27 aura::client::GetScreenPositionClient(root);
28 if (!spc)
29 return event.root_location();
31 gfx::Point screen_location(event.root_location());
32 spc->ConvertPointToScreen(root, &screen_location);
33 return screen_location;
36 } // namespace
38 #if defined(OS_WIN)
39 blink::WebMouseEvent MakeUntranslatedWebMouseEventFromNativeEvent(
40 const base::NativeEvent& native_event);
41 blink::WebMouseWheelEvent MakeUntranslatedWebMouseWheelEventFromNativeEvent(
42 const base::NativeEvent& native_event);
43 blink::WebKeyboardEvent MakeWebKeyboardEventFromNativeEvent(
44 const base::NativeEvent& native_event);
45 blink::WebGestureEvent MakeWebGestureEventFromNativeEvent(
46 const base::NativeEvent& native_event);
47 #endif
49 blink::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent(
50 const ui::KeyEvent& event) {
51 blink::WebKeyboardEvent webkit_event;
53 webkit_event.timeStampSeconds = event.time_stamp().InSecondsF();
54 webkit_event.modifiers = ui::EventFlagsToWebEventModifiers(event.flags());
56 switch (event.type()) {
57 case ui::ET_KEY_PRESSED:
58 webkit_event.type = event.is_char() ? blink::WebInputEvent::Char :
59 blink::WebInputEvent::RawKeyDown;
60 break;
61 case ui::ET_KEY_RELEASED:
62 webkit_event.type = blink::WebInputEvent::KeyUp;
63 break;
64 default:
65 NOTREACHED();
68 if (webkit_event.modifiers & blink::WebInputEvent::AltKey)
69 webkit_event.isSystemKey = true;
71 webkit_event.windowsKeyCode = event.GetLocatedWindowsKeyboardCode();
72 webkit_event.nativeKeyCode =
73 ui::KeycodeConverter::DomCodeToNativeKeycode(event.code());
74 webkit_event.domCode = static_cast<int>(event.code());
75 webkit_event.unmodifiedText[0] = event.GetUnmodifiedText();
76 webkit_event.text[0] = event.GetText();
78 webkit_event.setKeyIdentifierFromWindowsKeyCode();
80 return webkit_event;
83 blink::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent(
84 const ui::ScrollEvent& event) {
85 blink::WebMouseWheelEvent webkit_event;
87 webkit_event.type = blink::WebInputEvent::MouseWheel;
88 webkit_event.button = blink::WebMouseEvent::ButtonNone;
89 webkit_event.modifiers = ui::EventFlagsToWebEventModifiers(event.flags());
90 webkit_event.timeStampSeconds = event.time_stamp().InSecondsF();
91 webkit_event.hasPreciseScrollingDeltas = true;
93 float offset_ordinal_x = 0.f;
94 float offset_ordinal_y = 0.f;
95 if ((event.flags() & ui::EF_SHIFT_DOWN) != 0 && event.x_offset() == 0) {
96 webkit_event.deltaX = event.y_offset();
97 webkit_event.deltaY = 0;
98 offset_ordinal_x = event.y_offset_ordinal();
99 offset_ordinal_y = event.x_offset_ordinal();
100 } else {
101 webkit_event.deltaX = event.x_offset();
102 webkit_event.deltaY = event.y_offset();
103 offset_ordinal_x = event.x_offset_ordinal();
104 offset_ordinal_y = event.y_offset_ordinal();
107 if (offset_ordinal_x != 0.f && webkit_event.deltaX != 0.f)
108 webkit_event.accelerationRatioX = offset_ordinal_x / webkit_event.deltaX;
109 webkit_event.wheelTicksX = webkit_event.deltaX / kPixelsPerTick;
110 webkit_event.wheelTicksY = webkit_event.deltaY / kPixelsPerTick;
111 if (offset_ordinal_y != 0.f && webkit_event.deltaY != 0.f)
112 webkit_event.accelerationRatioY = offset_ordinal_y / webkit_event.deltaY;
113 return webkit_event;
116 blink::WebGestureEvent MakeWebGestureEventFromAuraEvent(
117 const ui::ScrollEvent& event) {
118 blink::WebGestureEvent webkit_event;
120 switch (event.type()) {
121 case ui::ET_SCROLL_FLING_START:
122 webkit_event.type = blink::WebInputEvent::GestureFlingStart;
123 webkit_event.data.flingStart.velocityX = event.x_offset();
124 webkit_event.data.flingStart.velocityY = event.y_offset();
125 break;
126 case ui::ET_SCROLL_FLING_CANCEL:
127 webkit_event.type = blink::WebInputEvent::GestureFlingCancel;
128 break;
129 case ui::ET_SCROLL:
130 NOTREACHED() << "Invalid gesture type: " << event.type();
131 break;
132 default:
133 NOTREACHED() << "Unknown gesture type: " << event.type();
136 webkit_event.sourceDevice = blink::WebGestureDeviceTouchpad;
137 webkit_event.modifiers = ui::EventFlagsToWebEventModifiers(event.flags());
138 webkit_event.timeStampSeconds = event.time_stamp().InSecondsF();
139 return webkit_event;
142 blink::WebMouseEvent MakeWebMouseEventFromAuraEvent(
143 const ui::MouseEvent& event);
144 blink::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent(
145 const ui::MouseWheelEvent& event);
147 // General approach:
149 // ui::Event only carries a subset of possible event data provided to Aura by
150 // the host platform. WebKit utilizes a larger subset of that information than
151 // Aura itself. WebKit includes some built in cracking functionality that we
152 // rely on to obtain this information cleanly and consistently.
154 // The only place where an ui::Event's data differs from what the underlying
155 // base::NativeEvent would provide is position data, since we would like to
156 // provide coordinates relative to the aura::Window that is hosting the
157 // renderer, not the top level platform window.
159 // The approach is to fully construct a blink::WebInputEvent from the
160 // ui::Event's base::NativeEvent, and then replace the coordinate fields with
161 // the translated values from the ui::Event.
163 // The exception is mouse events on linux. The ui::MouseEvent contains enough
164 // necessary information to construct a WebMouseEvent. So instead of extracting
165 // the information from the XEvent, which can be tricky when supporting both
166 // XInput2 and XInput, the WebMouseEvent is constructed from the
167 // ui::MouseEvent. This will not be necessary once only XInput2 is supported.
170 blink::WebMouseEvent MakeWebMouseEvent(const ui::MouseEvent& event) {
171 // Construct an untranslated event from the platform event data.
172 blink::WebMouseEvent webkit_event =
173 #if defined(OS_WIN)
174 // On Windows we have WM_ events comming from desktop and pure aura
175 // events comming from metro mode.
176 event.native_event().message ?
177 MakeUntranslatedWebMouseEventFromNativeEvent(event.native_event()) :
178 MakeWebMouseEventFromAuraEvent(event);
179 #else
180 MakeWebMouseEventFromAuraEvent(event);
181 #endif
182 // Replace the event's coordinate fields with translated position data from
183 // |event|.
184 webkit_event.windowX = webkit_event.x = event.x();
185 webkit_event.windowY = webkit_event.y = event.y();
187 #if defined(OS_WIN)
188 if (event.native_event().message)
189 return webkit_event;
190 #endif
191 const gfx::Point screen_point = GetScreenLocationFromEvent(event);
192 webkit_event.globalX = screen_point.x();
193 webkit_event.globalY = screen_point.y();
195 return webkit_event;
198 blink::WebMouseWheelEvent MakeWebMouseWheelEvent(
199 const ui::MouseWheelEvent& event) {
200 #if defined(OS_WIN)
201 // Construct an untranslated event from the platform event data.
202 blink::WebMouseWheelEvent webkit_event = event.native_event().message ?
203 MakeUntranslatedWebMouseWheelEventFromNativeEvent(event.native_event()) :
204 MakeWebMouseWheelEventFromAuraEvent(event);
205 #else
206 blink::WebMouseWheelEvent webkit_event =
207 MakeWebMouseWheelEventFromAuraEvent(event);
208 #endif
210 // Replace the event's coordinate fields with translated position data from
211 // |event|.
212 webkit_event.windowX = webkit_event.x = event.x();
213 webkit_event.windowY = webkit_event.y = event.y();
215 const gfx::Point screen_point = GetScreenLocationFromEvent(event);
216 webkit_event.globalX = screen_point.x();
217 webkit_event.globalY = screen_point.y();
219 // Scroll events generated from the mouse wheel when the control key is held
220 // don't trigger scrolling. Instead, they may cause zooming.
221 bool from_mouse_wheel = !webkit_event.hasPreciseScrollingDeltas;
222 if ((webkit_event.modifiers & blink::WebInputEvent::ControlKey) &&
223 from_mouse_wheel) {
224 webkit_event.canScroll = false;
227 return webkit_event;
230 blink::WebMouseWheelEvent MakeWebMouseWheelEvent(const ui::ScrollEvent& event) {
231 #if defined(OS_WIN)
232 // Construct an untranslated event from the platform event data.
233 blink::WebMouseWheelEvent webkit_event = event.native_event().message ?
234 MakeUntranslatedWebMouseWheelEventFromNativeEvent(event.native_event()) :
235 MakeWebMouseWheelEventFromAuraEvent(event);
236 #else
237 blink::WebMouseWheelEvent webkit_event =
238 MakeWebMouseWheelEventFromAuraEvent(event);
239 #endif
241 // Replace the event's coordinate fields with translated position data from
242 // |event|.
243 webkit_event.windowX = webkit_event.x = event.x();
244 webkit_event.windowY = webkit_event.y = event.y();
246 const gfx::Point screen_point = GetScreenLocationFromEvent(event);
247 webkit_event.globalX = screen_point.x();
248 webkit_event.globalY = screen_point.y();
250 return webkit_event;
253 blink::WebKeyboardEvent MakeWebKeyboardEvent(const ui::KeyEvent& event) {
254 // Windows can figure out whether or not to construct a RawKeyDown or a Char
255 // WebInputEvent based on the type of message carried in
256 // event.native_event(). X11 is not so fortunate, there is no separate
257 // translated event type, so DesktopHostLinux sends an extra KeyEvent with
258 // is_char() == true. We need to pass the ui::KeyEvent to the X11 function
259 // to detect this case so the right event type can be constructed.
260 #if defined(OS_WIN)
261 if (event.HasNativeEvent()) {
262 // Key events require no translation by the aura system.
263 return MakeWebKeyboardEventFromNativeEvent(event.native_event());
265 #endif
266 return MakeWebKeyboardEventFromAuraEvent(event);
269 blink::WebGestureEvent MakeWebGestureEvent(const ui::GestureEvent& event) {
270 blink::WebGestureEvent gesture_event;
271 #if defined(OS_WIN)
272 if (event.HasNativeEvent())
273 gesture_event = MakeWebGestureEventFromNativeEvent(event.native_event());
274 else
275 gesture_event = MakeWebGestureEventFromUIEvent(event);
276 #else
277 gesture_event = MakeWebGestureEventFromUIEvent(event);
278 #endif
280 gesture_event.x = event.x();
281 gesture_event.y = event.y();
283 const gfx::Point screen_point = GetScreenLocationFromEvent(event);
284 gesture_event.globalX = screen_point.x();
285 gesture_event.globalY = screen_point.y();
287 return gesture_event;
290 blink::WebGestureEvent MakeWebGestureEvent(const ui::ScrollEvent& event) {
291 blink::WebGestureEvent gesture_event;
293 #if defined(OS_WIN)
294 gesture_event = MakeWebGestureEventFromNativeEvent(event.native_event());
295 #else
296 gesture_event = MakeWebGestureEventFromAuraEvent(event);
297 #endif
299 gesture_event.x = event.x();
300 gesture_event.y = event.y();
302 const gfx::Point screen_point = GetScreenLocationFromEvent(event);
303 gesture_event.globalX = screen_point.x();
304 gesture_event.globalY = screen_point.y();
306 return gesture_event;
309 blink::WebGestureEvent MakeWebGestureEventFlingCancel() {
310 blink::WebGestureEvent gesture_event;
312 // All other fields are ignored on a GestureFlingCancel event.
313 gesture_event.type = blink::WebInputEvent::GestureFlingCancel;
314 gesture_event.sourceDevice = blink::WebGestureDeviceTouchpad;
315 return gesture_event;
318 blink::WebMouseEvent MakeWebMouseEventFromAuraEvent(
319 const ui::MouseEvent& event) {
320 blink::WebMouseEvent webkit_event;
322 webkit_event.modifiers = ui::EventFlagsToWebEventModifiers(event.flags());
323 webkit_event.timeStampSeconds = event.time_stamp().InSecondsF();
325 webkit_event.button = blink::WebMouseEvent::ButtonNone;
326 int button_flags = event.flags();
327 if (event.type() == ui::ET_MOUSE_PRESSED ||
328 event.type() == ui::ET_MOUSE_RELEASED) {
329 // We want to use changed_button_flags() for mouse pressed & released.
330 // These flags can be used only if they are set which is not always the case
331 // (see e.g. GetChangedMouseButtonFlagsFromNative() in events_win.cc).
332 if (event.changed_button_flags())
333 button_flags = event.changed_button_flags();
335 if (button_flags & ui::EF_LEFT_MOUSE_BUTTON)
336 webkit_event.button = blink::WebMouseEvent::ButtonLeft;
337 if (button_flags & ui::EF_MIDDLE_MOUSE_BUTTON)
338 webkit_event.button = blink::WebMouseEvent::ButtonMiddle;
339 if (button_flags & ui::EF_RIGHT_MOUSE_BUTTON)
340 webkit_event.button = blink::WebMouseEvent::ButtonRight;
342 switch (event.type()) {
343 case ui::ET_MOUSE_PRESSED:
344 webkit_event.type = blink::WebInputEvent::MouseDown;
345 webkit_event.clickCount = event.GetClickCount();
346 break;
347 case ui::ET_MOUSE_RELEASED:
348 webkit_event.type = blink::WebInputEvent::MouseUp;
349 webkit_event.clickCount = event.GetClickCount();
350 break;
351 case ui::ET_MOUSE_ENTERED:
352 case ui::ET_MOUSE_EXITED:
353 case ui::ET_MOUSE_MOVED:
354 case ui::ET_MOUSE_DRAGGED:
355 webkit_event.type = blink::WebInputEvent::MouseMove;
356 break;
357 default:
358 NOTIMPLEMENTED() << "Received unexpected event: " << event.type();
359 break;
362 return webkit_event;
365 blink::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent(
366 const ui::MouseWheelEvent& event) {
367 blink::WebMouseWheelEvent webkit_event;
369 webkit_event.type = blink::WebInputEvent::MouseWheel;
370 webkit_event.button = blink::WebMouseEvent::ButtonNone;
371 webkit_event.modifiers = ui::EventFlagsToWebEventModifiers(event.flags());
372 webkit_event.timeStampSeconds = event.time_stamp().InSecondsF();
374 if ((event.flags() & ui::EF_SHIFT_DOWN) != 0 && event.x_offset() == 0) {
375 webkit_event.deltaX = event.y_offset();
376 webkit_event.deltaY = 0;
377 } else {
378 webkit_event.deltaX = event.x_offset();
379 webkit_event.deltaY = event.y_offset();
382 webkit_event.wheelTicksX = webkit_event.deltaX / kPixelsPerTick;
383 webkit_event.wheelTicksY = webkit_event.deltaY / kPixelsPerTick;
385 return webkit_event;
388 } // namespace content