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

Side by Side Diff: content/browser/renderer_host/input/web_input_event_builders_win.cc

Issue 2234023002: Refactor WebInputEventAura to ui/events/blink (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 4 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
OLDNEW
(Empty)
1 // Copyright 2013 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/input/web_input_event_builders_win.h"
6
7 #include "base/logging.h"
8 #include "content/browser/renderer_host/input/web_input_event_util.h"
9 #include "ui/display/win/screen_win.h"
10 #include "ui/events/blink/blink_event_util.h"
11 #include "ui/events/event_utils.h"
12
13 using blink::WebInputEvent;
14 using blink::WebKeyboardEvent;
15 using blink::WebMouseEvent;
16 using blink::WebMouseWheelEvent;
17
18 namespace content {
19
20 static const unsigned long kDefaultScrollLinesPerWheelDelta = 3;
21 static const unsigned long kDefaultScrollCharsPerWheelDelta = 1;
22
23 WebKeyboardEvent WebKeyboardEventBuilder::Build(HWND hwnd,
24 UINT message,
25 WPARAM wparam,
26 LPARAM lparam,
27 double time_stamp) {
28 WebKeyboardEvent result;
29
30 result.timeStampSeconds = time_stamp;
31
32 result.windowsKeyCode = static_cast<int>(wparam);
33 // Record the scan code (along with other context bits) for this key event.
34 result.nativeKeyCode = static_cast<int>(lparam);
35
36 switch (message) {
37 case WM_SYSKEYDOWN:
38 result.isSystemKey = true;
39 case WM_KEYDOWN:
40 result.type = WebInputEvent::RawKeyDown;
41 break;
42 case WM_SYSKEYUP:
43 result.isSystemKey = true;
44 case WM_KEYUP:
45 result.type = WebInputEvent::KeyUp;
46 break;
47 case WM_IME_CHAR:
48 result.type = WebInputEvent::Char;
49 break;
50 case WM_SYSCHAR:
51 result.isSystemKey = true;
52 result.type = WebInputEvent::Char;
53 case WM_CHAR:
54 result.type = WebInputEvent::Char;
55 break;
56 default:
57 NOTREACHED();
58 }
59
60 if (result.type == WebInputEvent::Char
61 || result.type == WebInputEvent::RawKeyDown) {
62 result.text[0] = result.windowsKeyCode;
63 result.unmodifiedText[0] = result.windowsKeyCode;
64 }
65 result.modifiers =
66 ui::EventFlagsToWebEventModifiers(ui::GetModifiersFromKeyState());
67 // NOTE: There doesn't seem to be a way to query the mouse button state in
68 // this case.
69
70 // Bit 30 of lParam represents the "previous key state". If set, the key was
71 // already down, therefore this is an auto-repeat. Only apply this to key
72 // down events, to match DOM semantics.
73 if ((result.type == WebInputEvent::RawKeyDown) && (lparam & 0x40000000))
74 result.modifiers |= WebInputEvent::IsAutoRepeat;
75
76 return result;
77 }
78
79 // WebMouseEvent --------------------------------------------------------------
80
81 static int g_last_click_count = 0;
82 static double g_last_click_time = 0;
83
84 static LPARAM GetRelativeCursorPos(HWND hwnd) {
85 POINT pos = {-1, -1};
86 GetCursorPos(&pos);
87 ScreenToClient(hwnd, &pos);
88 return MAKELPARAM(pos.x, pos.y);
89 }
90
91 WebMouseEvent WebMouseEventBuilder::Build(
92 HWND hwnd,
93 UINT message,
94 WPARAM wparam,
95 LPARAM lparam,
96 double time_stamp,
97 blink::WebPointerProperties::PointerType pointer_type) {
98 WebMouseEvent result;
99
100 switch (message) {
101 case WM_MOUSEMOVE:
102 result.type = WebInputEvent::MouseMove;
103 if (wparam & MK_LBUTTON)
104 result.button = WebMouseEvent::ButtonLeft;
105 else if (wparam & MK_MBUTTON)
106 result.button = WebMouseEvent::ButtonMiddle;
107 else if (wparam & MK_RBUTTON)
108 result.button = WebMouseEvent::ButtonRight;
109 else
110 result.button = WebMouseEvent::ButtonNone;
111 break;
112 case WM_MOUSELEAVE:
113 case WM_NCMOUSELEAVE:
114 // TODO(rbyers): This should be MouseLeave but is disabled temporarily.
115 // See http://crbug.com/450631
116 result.type = WebInputEvent::MouseMove;
117 result.button = WebMouseEvent::ButtonNone;
118 // set the current mouse position (relative to the client area of the
119 // current window) since none is specified for this event
120 lparam = GetRelativeCursorPos(hwnd);
121 break;
122 case WM_LBUTTONDOWN:
123 case WM_LBUTTONDBLCLK:
124 result.type = WebInputEvent::MouseDown;
125 result.button = WebMouseEvent::ButtonLeft;
126 break;
127 case WM_MBUTTONDOWN:
128 case WM_MBUTTONDBLCLK:
129 result.type = WebInputEvent::MouseDown;
130 result.button = WebMouseEvent::ButtonMiddle;
131 break;
132 case WM_RBUTTONDOWN:
133 case WM_RBUTTONDBLCLK:
134 result.type = WebInputEvent::MouseDown;
135 result.button = WebMouseEvent::ButtonRight;
136 break;
137 case WM_LBUTTONUP:
138 result.type = WebInputEvent::MouseUp;
139 result.button = WebMouseEvent::ButtonLeft;
140 break;
141 case WM_MBUTTONUP:
142 result.type = WebInputEvent::MouseUp;
143 result.button = WebMouseEvent::ButtonMiddle;
144 break;
145 case WM_RBUTTONUP:
146 result.type = WebInputEvent::MouseUp;
147 result.button = WebMouseEvent::ButtonRight;
148 break;
149 default:
150 NOTREACHED();
151 }
152
153 result.timeStampSeconds = time_stamp;
154 result.pointerType = pointer_type;
155
156 // set position fields:
157
158 result.x = static_cast<short>(LOWORD(lparam));
159 result.y = static_cast<short>(HIWORD(lparam));
160 result.windowX = result.x;
161 result.windowY = result.y;
162
163 POINT global_point = { result.x, result.y };
164 ClientToScreen(hwnd, &global_point);
165
166 // We need to convert the global point back to DIP before using it.
167 gfx::Point dip_global_point = display::win::ScreenWin::ScreenToDIPPoint(
168 gfx::Point(global_point.x, global_point.y));
169
170 result.globalX = dip_global_point.x();
171 result.globalY = dip_global_point.y();
172
173 // calculate number of clicks:
174
175 // This differs slightly from the WebKit code in WebKit/win/WebView.cpp
176 // where their original code looks buggy.
177 static int last_click_position_x;
178 static int last_click_position_y;
179 static WebMouseEvent::Button last_click_button = WebMouseEvent::ButtonLeft;
180
181 double current_time = result.timeStampSeconds;
182 bool cancel_previous_click =
183 (abs(last_click_position_x - result.x) >
184 (::GetSystemMetrics(SM_CXDOUBLECLK) / 2))
185 || (abs(last_click_position_y - result.y) >
186 (::GetSystemMetrics(SM_CYDOUBLECLK) / 2))
187 || ((current_time - g_last_click_time) * 1000.0 > ::GetDoubleClickTime());
188
189 if (result.type == WebInputEvent::MouseDown) {
190 if (!cancel_previous_click && (result.button == last_click_button)) {
191 ++g_last_click_count;
192 } else {
193 g_last_click_count = 1;
194 last_click_position_x = result.x;
195 last_click_position_y = result.y;
196 }
197 g_last_click_time = current_time;
198 last_click_button = result.button;
199 } else if (result.type == WebInputEvent::MouseMove
200 || result.type == WebInputEvent::MouseLeave) {
201 if (cancel_previous_click) {
202 g_last_click_count = 0;
203 last_click_position_x = 0;
204 last_click_position_y = 0;
205 g_last_click_time = 0;
206 }
207 }
208 result.clickCount = g_last_click_count;
209
210 // set modifiers:
211 result.modifiers =
212 ui::EventFlagsToWebEventModifiers(ui::GetModifiersFromKeyState());
213 if (wparam & MK_CONTROL)
214 result.modifiers |= WebInputEvent::ControlKey;
215 if (wparam & MK_SHIFT)
216 result.modifiers |= WebInputEvent::ShiftKey;
217 if (wparam & MK_LBUTTON)
218 result.modifiers |= WebInputEvent::LeftButtonDown;
219 if (wparam & MK_MBUTTON)
220 result.modifiers |= WebInputEvent::MiddleButtonDown;
221 if (wparam & MK_RBUTTON)
222 result.modifiers |= WebInputEvent::RightButtonDown;
223
224 return result;
225 }
226
227 // WebMouseWheelEvent ---------------------------------------------------------
228
229 WebMouseWheelEvent WebMouseWheelEventBuilder::Build(
230 HWND hwnd,
231 UINT message,
232 WPARAM wparam,
233 LPARAM lparam,
234 double time_stamp,
235 blink::WebPointerProperties::PointerType pointer_type) {
236 WebMouseWheelEvent result;
237
238 result.type = WebInputEvent::MouseWheel;
239
240 result.timeStampSeconds = time_stamp;
241
242 result.button = WebMouseEvent::ButtonNone;
243
244 result.pointerType = pointer_type;
245
246 // Get key state, coordinates, and wheel delta from event.
247 UINT key_state;
248 float wheel_delta;
249 bool horizontal_scroll = false;
250 if ((message == WM_VSCROLL) || (message == WM_HSCROLL)) {
251 // Synthesize mousewheel event from a scroll event. This is needed to
252 // simulate middle mouse scrolling in some laptops. Use GetAsyncKeyState
253 // for key state since we are synthesizing the input event.
254 key_state = 0;
255 if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
256 key_state |= MK_SHIFT;
257 if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
258 key_state |= MK_CONTROL;
259 // NOTE: There doesn't seem to be a way to query the mouse button state
260 // in this case.
261
262 POINT cursor_position = {0};
263 GetCursorPos(&cursor_position);
264 result.globalX = cursor_position.x;
265 result.globalY = cursor_position.y;
266
267 switch (LOWORD(wparam)) {
268 case SB_LINEUP: // == SB_LINELEFT
269 wheel_delta = WHEEL_DELTA;
270 break;
271 case SB_LINEDOWN: // == SB_LINERIGHT
272 wheel_delta = -WHEEL_DELTA;
273 break;
274 case SB_PAGEUP:
275 wheel_delta = 1;
276 result.scrollByPage = true;
277 break;
278 case SB_PAGEDOWN:
279 wheel_delta = -1;
280 result.scrollByPage = true;
281 break;
282 default: // We don't supoprt SB_THUMBPOSITION or SB_THUMBTRACK here.
283 wheel_delta = 0;
284 break;
285 }
286
287 if (message == WM_HSCROLL)
288 horizontal_scroll = true;
289 } else {
290 // Non-synthesized event; we can just read data off the event.
291 key_state = GET_KEYSTATE_WPARAM(wparam);
292
293 result.globalX = static_cast<short>(LOWORD(lparam));
294 result.globalY = static_cast<short>(HIWORD(lparam));
295
296 // Currently we leave hasPreciseScrollingDeltas false, even for trackpad
297 // scrolls that generate WM_MOUSEWHEEL, since we don't have a good way to
298 // distinguish these from real mouse wheels (crbug.com/545234).
299 wheel_delta = static_cast<float>(GET_WHEEL_DELTA_WPARAM(wparam));
300
301 if (message == WM_MOUSEHWHEEL) {
302 horizontal_scroll = true;
303 wheel_delta = -wheel_delta; // Windows is <- -/+ ->, WebKit <- +/- ->.
304 }
305 }
306 if (key_state & MK_SHIFT)
307 horizontal_scroll = true;
308
309 // Set modifiers based on key state.
310 result.modifiers =
311 ui::EventFlagsToWebEventModifiers(ui::GetModifiersFromKeyState());
312 if (key_state & MK_SHIFT)
313 result.modifiers |= WebInputEvent::ShiftKey;
314 if (key_state & MK_CONTROL)
315 result.modifiers |= WebInputEvent::ControlKey;
316 if (key_state & MK_LBUTTON)
317 result.modifiers |= WebInputEvent::LeftButtonDown;
318 if (key_state & MK_MBUTTON)
319 result.modifiers |= WebInputEvent::MiddleButtonDown;
320 if (key_state & MK_RBUTTON)
321 result.modifiers |= WebInputEvent::RightButtonDown;
322
323 // Set coordinates by translating event coordinates from screen to client.
324 POINT client_point = { result.globalX, result.globalY };
325 MapWindowPoints(0, hwnd, &client_point, 1);
326 result.x = client_point.x;
327 result.y = client_point.y;
328 result.windowX = result.x;
329 result.windowY = result.y;
330
331 // Convert wheel delta amount to a number of pixels to scroll.
332 //
333 // How many pixels should we scroll per line? Gecko uses the height of the
334 // current line, which means scroll distance changes as you go through the
335 // page or go to different pages. IE 8 is ~60 px/line, although the value
336 // seems to vary slightly by page and zoom level. Also, IE defaults to
337 // smooth scrolling while Firefox doesn't, so it can get away with somewhat
338 // larger scroll values without feeling as jerky. Here we use 100 px per
339 // three lines (the default scroll amount is three lines per wheel tick).
340 // Even though we have smooth scrolling, we don't make this as large as IE
341 // because subjectively IE feels like it scrolls farther than you want while
342 // reading articles.
343 static const float kScrollbarPixelsPerLine = 100.0f / 3.0f;
344 wheel_delta /= WHEEL_DELTA;
345 float scroll_delta = wheel_delta;
346 if (horizontal_scroll) {
347 unsigned long scroll_chars = kDefaultScrollCharsPerWheelDelta;
348 SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scroll_chars, 0);
349 // TODO(pkasting): Should probably have a different multiplier
350 // scrollbarPixelsPerChar here.
351 scroll_delta *= static_cast<float>(scroll_chars) * kScrollbarPixelsPerLine;
352 } else {
353 unsigned long scroll_lines = kDefaultScrollLinesPerWheelDelta;
354 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scroll_lines, 0);
355 if (scroll_lines == WHEEL_PAGESCROLL)
356 result.scrollByPage = true;
357 if (!result.scrollByPage) {
358 scroll_delta *=
359 static_cast<float>(scroll_lines) * kScrollbarPixelsPerLine;
360 }
361 }
362
363 // Set scroll amount based on above calculations. WebKit expects positive
364 // deltaY to mean "scroll up" and positive deltaX to mean "scroll left".
365 if (horizontal_scroll) {
366 result.deltaX = scroll_delta;
367 result.wheelTicksX = wheel_delta;
368 } else {
369 result.deltaY = scroll_delta;
370 result.wheelTicksY = wheel_delta;
371 }
372
373 return result;
374 }
375
376 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698