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. 4 5 #include "content/browser/renderer_host/web_input_event_aura.h" 6 7 #include "content/browser/renderer_host/ui_events_helper.h" 8 #include "ui/aura/window.h" 9 #include "ui/base/events/event.h" 10 #include "ui/base/events/event_utils.h" 11 12 namespace content { 13 14 #if defined(OS_WIN) 15 WebKit::WebMouseEvent MakeUntranslatedWebMouseEventFromNativeEvent( 16 base::NativeEvent native_event); 17 WebKit::WebMouseWheelEvent MakeUntranslatedWebMouseWheelEventFromNativeEvent( 18 base::NativeEvent native_event); 19 WebKit::WebKeyboardEvent MakeWebKeyboardEventFromNativeEvent( 20 base::NativeEvent native_event); 21 WebKit::WebGestureEvent MakeWebGestureEventFromNativeEvent( 22 base::NativeEvent native_event); 23 #elif defined(USE_X11) 24 WebKit::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent( 25 ui::ScrollEvent* event); 26 WebKit::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent( 27 ui::KeyEvent* event); 28 WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent( 29 ui::ScrollEvent* event); 30 #else 31 WebKit::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent( 32 ui::ScrollEvent* event) { 33 WebKit::WebMouseWheelEvent webkit_event; 34 return webkit_event; 35 } 36 37 WebKit::WebKeyboardEvent MakeWebKeyboardEventFromAuraEvent( 38 ui::KeyEvent* event) { 39 WebKit::WebKeyboardEvent webkit_event; 40 return webkit_event; 41 } 42 43 WebKit::WebGestureEvent MakeWebGestureEventFromAuraEvent( 44 ui::ScrollEvent* event) { 45 WebKit::WebGestureEvent webkit_event; 46 return webkit_event; 47 } 48 49 #endif 50 51 WebKit::WebMouseEvent MakeWebMouseEventFromAuraEvent( 52 ui::MouseEvent* event); 53 WebKit::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent( 54 ui::MouseWheelEvent* event); 55 56 // General approach: 57 // 58 // ui::Event only carries a subset of possible event data provided to Aura by 59 // the host platform. WebKit utilizes a larger subset of that information than 60 // Aura itself. WebKit includes some built in cracking functionality that we 61 // rely on to obtain this information cleanly and consistently. 62 // 63 // The only place where an ui::Event's data differs from what the underlying 64 // base::NativeEvent would provide is position data, since we would like to 65 // provide coordinates relative to the aura::Window that is hosting the 66 // renderer, not the top level platform window. 67 // 68 // The approach is to fully construct a WebKit::WebInputEvent from the 69 // ui::Event's base::NativeEvent, and then replace the coordinate fields with 70 // the translated values from the ui::Event. 71 // 72 // The exception is mouse events on linux. The ui::MouseEvent contains enough 73 // necessary information to construct a WebMouseEvent. So instead of extracting 74 // the information from the XEvent, which can be tricky when supporting both 75 // XInput2 and XInput, the WebMouseEvent is constructed from the 76 // ui::MouseEvent. This will not be necessary once only XInput2 is supported. 77 // 78 79 WebKit::WebMouseEvent MakeWebMouseEvent(ui::MouseEvent* event) { 80 // Construct an untranslated event from the platform event data. 81 WebKit::WebMouseEvent webkit_event = 82 #if defined(OS_WIN) 83 // On Windows we have WM_ events comming from desktop and pure aura 84 // events comming from metro mode. 85 event->native_event().message ? 86 MakeUntranslatedWebMouseEventFromNativeEvent(event->native_event()) : 87 MakeWebMouseEventFromAuraEvent(event); 88 #else 89 MakeWebMouseEventFromAuraEvent(event); 90 #endif 91 // Replace the event's coordinate fields with translated position data from 92 // |event|. 93 webkit_event.windowX = webkit_event.x = event->x(); 94 webkit_event.windowY = webkit_event.y = event->y(); 95 96 #if defined(OS_WIN) 97 if (event->native_event().message) 98 return webkit_event; 99 #endif 100 const gfx::Point root_point = event->root_location(); 101 webkit_event.globalX = root_point.x(); 102 webkit_event.globalY = root_point.y(); 103 104 return webkit_event; 105 } 106 107 WebKit::WebMouseWheelEvent MakeWebMouseWheelEvent(ui::MouseWheelEvent* event) { 108 #if defined(OS_WIN) 109 // Construct an untranslated event from the platform event data. 110 WebKit::WebMouseWheelEvent webkit_event = event->native_event().message ? 111 MakeUntranslatedWebMouseWheelEventFromNativeEvent(event->native_event()) : 112 MakeWebMouseWheelEventFromAuraEvent(event); 113 #else 114 WebKit::WebMouseWheelEvent webkit_event = 115 MakeWebMouseWheelEventFromAuraEvent(event); 116 #endif 117 118 // Replace the event's coordinate fields with translated position data from 119 // |event|. 120 webkit_event.windowX = webkit_event.x = event->x(); 121 webkit_event.windowY = webkit_event.y = event->y(); 122 123 const gfx::Point root_point = event->root_location(); 124 webkit_event.globalX = root_point.x(); 125 webkit_event.globalY = root_point.y(); 126 127 return webkit_event; 128 } 129 130 WebKit::WebMouseWheelEvent MakeWebMouseWheelEvent(ui::ScrollEvent* event) { 131 #if defined(OS_WIN) 132 // Construct an untranslated event from the platform event data. 133 WebKit::WebMouseWheelEvent webkit_event = 134 MakeUntranslatedWebMouseWheelEventFromNativeEvent(event->native_event()); 135 #else 136 WebKit::WebMouseWheelEvent webkit_event = 137 MakeWebMouseWheelEventFromAuraEvent(event); 138 #endif 139 140 // Replace the event's coordinate fields with translated position data from 141 // |event|. 142 webkit_event.windowX = webkit_event.x = event->x(); 143 webkit_event.windowY = webkit_event.y = event->y(); 144 145 const gfx::Point root_point = event->root_location(); 146 webkit_event.globalX = root_point.x(); 147 webkit_event.globalY = root_point.y(); 148 149 return webkit_event; 150 } 151 152 WebKit::WebKeyboardEvent MakeWebKeyboardEvent(ui::KeyEvent* event) { 153 // Windows can figure out whether or not to construct a RawKeyDown or a Char 154 // WebInputEvent based on the type of message carried in 155 // event->native_event(). X11 is not so fortunate, there is no separate 156 // translated event type, so DesktopHostLinux sends an extra KeyEvent with 157 // is_char() == true. We need to pass the ui::KeyEvent to the X11 function 158 // to detect this case so the right event type can be constructed. 159 #if defined(OS_WIN) 160 // Key events require no translation by the aura system. 161 return MakeWebKeyboardEventFromNativeEvent(event->native_event()); 162 #else 163 return MakeWebKeyboardEventFromAuraEvent(event); 164 #endif 165 } 166 167 WebKit::WebGestureEvent MakeWebGestureEvent(ui::GestureEvent* event) { 168 WebKit::WebGestureEvent gesture_event; 169 #if defined(OS_WIN) 170 if (event->HasNativeEvent()) 171 gesture_event = MakeWebGestureEventFromNativeEvent(event->native_event()); 172 else 173 gesture_event = MakeWebGestureEventFromUIEvent(*event); 174 #else 175 gesture_event = MakeWebGestureEventFromUIEvent(*event); 176 #endif 177 178 gesture_event.x = event->x(); 179 gesture_event.y = event->y(); 180 181 const gfx::Point root_point = event->root_location(); 182 gesture_event.globalX = root_point.x(); 183 gesture_event.globalY = root_point.y(); 184 185 return gesture_event; 186 } 187 188 WebKit::WebGestureEvent MakeWebGestureEvent(ui::ScrollEvent* event) { 189 WebKit::WebGestureEvent gesture_event; 190 191 #if defined(OS_WIN) 192 gesture_event = MakeWebGestureEventFromNativeEvent(event->native_event()); 193 #else 194 gesture_event = MakeWebGestureEventFromAuraEvent(event); 195 #endif 196 197 gesture_event.x = event->x(); 198 gesture_event.y = event->y(); 199 200 const gfx::Point root_point = event->root_location(); 201 gesture_event.globalX = root_point.x(); 202 gesture_event.globalY = root_point.y(); 203 204 return gesture_event; 205 } 206 207 WebKit::WebGestureEvent MakeWebGestureEventFlingCancel() { 208 WebKit::WebGestureEvent gesture_event; 209 210 // All other fields are ignored on a GestureFlingCancel event. 211 gesture_event.type = WebKit::WebInputEvent::GestureFlingCancel; 212 gesture_event.sourceDevice = WebKit::WebGestureEvent::Touchpad; 213 return gesture_event; 214 } 215 216 WebKit::WebMouseEvent MakeWebMouseEventFromAuraEvent(ui::MouseEvent* event) { 217 WebKit::WebMouseEvent webkit_event; 218 219 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags()); 220 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF(); 221 222 webkit_event.button = WebKit::WebMouseEvent::ButtonNone; 223 if (event->flags() & ui::EF_LEFT_MOUSE_BUTTON) 224 webkit_event.button = WebKit::WebMouseEvent::ButtonLeft; 225 if (event->flags() & ui::EF_MIDDLE_MOUSE_BUTTON) 226 webkit_event.button = WebKit::WebMouseEvent::ButtonMiddle; 227 if (event->flags() & ui::EF_RIGHT_MOUSE_BUTTON) 228 webkit_event.button = WebKit::WebMouseEvent::ButtonRight; 229 230 switch (event->type()) { 231 case ui::ET_MOUSE_PRESSED: 232 webkit_event.type = WebKit::WebInputEvent::MouseDown; 233 webkit_event.clickCount = event->GetClickCount(); 234 break; 235 case ui::ET_MOUSE_RELEASED: 236 webkit_event.type = WebKit::WebInputEvent::MouseUp; 237 break; 238 case ui::ET_MOUSE_ENTERED: 239 case ui::ET_MOUSE_EXITED: 240 case ui::ET_MOUSE_MOVED: 241 case ui::ET_MOUSE_DRAGGED: 242 webkit_event.type = WebKit::WebInputEvent::MouseMove; 243 break; 244 default: 245 NOTIMPLEMENTED() << "Received unexpected event: " << event->type(); 246 break; 247 } 248 249 return webkit_event; 250 } 251 252 WebKit::WebMouseWheelEvent MakeWebMouseWheelEventFromAuraEvent( 253 ui::MouseWheelEvent* event) { 254 WebKit::WebMouseWheelEvent webkit_event; 255 256 webkit_event.type = WebKit::WebInputEvent::MouseWheel; 257 webkit_event.button = WebKit::WebMouseEvent::ButtonNone; 258 webkit_event.modifiers = EventFlagsToWebEventModifiers(event->flags()); 259 webkit_event.timeStampSeconds = event->time_stamp().InSecondsF(); 260 webkit_event.deltaX = event->x_offset(); 261 webkit_event.deltaY = event->y_offset(); 262 webkit_event.wheelTicksX = webkit_event.deltaX / kPixelsPerTick; 263 webkit_event.wheelTicksY = webkit_event.deltaY / kPixelsPerTick; 264 265 return webkit_event; 266 } 267 268 } // namespace content 269