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

Side by Side Diff: webkit/glue/webinputevent_win.cc

Issue 40135: Various fixes to mouse wheel scrolling:... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 9 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 #include "config.h" 5 #include "config.h"
6 6
7 #include "webkit/glue/webinputevent.h" 7 #include "webkit/glue/webinputevent.h"
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
11 #include "webkit/glue/webinputevent_util.h" 11 #include "webkit/glue/webinputevent_util.h"
12 12
13 static const unsigned long kDefaultScrollLinesPerWheelDelta = 3; 13 static const unsigned long kDefaultScrollLinesPerWheelDelta = 3;
14 static const unsigned long kDefaultScrollCharsPerWheelDelta = 1;
14 15
15 // WebMouseEvent -------------------------------------------------------------- 16 // WebMouseEvent --------------------------------------------------------------
16 17
17 static LPARAM GetRelativeCursorPos(HWND hwnd) { 18 static LPARAM GetRelativeCursorPos(HWND hwnd) {
18 POINT pos = {-1, -1}; 19 POINT pos = {-1, -1};
19 GetCursorPos(&pos); 20 GetCursorPos(&pos);
20 ScreenToClient(hwnd, &pos); 21 ScreenToClient(hwnd, &pos);
21 return MAKELPARAM(pos.x, pos.y); 22 return MAKELPARAM(pos.x, pos.y);
22 } 23 }
23 24
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 // TODO(pkasting): http://b/1117926 Instead of using GetTickCount() here, we 106 // TODO(pkasting): http://b/1117926 Instead of using GetTickCount() here, we
106 // should use GetMessageTime() on the original Windows message in the browser 107 // should use GetMessageTime() on the original Windows message in the browser
107 // process, and pass that in the WebMouseEvent. 108 // process, and pass that in the WebMouseEvent.
108 timestamp_sec = GetTickCount() / 1000.0; 109 timestamp_sec = GetTickCount() / 1000.0;
109 110
110 layout_test_click_count = 0; 111 layout_test_click_count = 0;
111 } 112 }
112 113
113 // WebMouseWheelEvent --------------------------------------------------------- 114 // WebMouseWheelEvent ---------------------------------------------------------
114 115
115 WebMouseWheelEvent::WebMouseWheelEvent(HWND hwnd, UINT message, WPARAM wparam, 116 WebMouseWheelEvent::WebMouseWheelEvent(HWND hwnd,
116 LPARAM lparam) { 117 UINT message,
118 WPARAM wparam,
119 LPARAM lparam)
120 : scroll_by_page(false) {
117 type = MOUSE_WHEEL; 121 type = MOUSE_WHEEL;
118 button = BUTTON_NONE; 122 button = BUTTON_NONE;
119 123
120 // Add a simple workaround to scroll multiples units per page. 124 // Get key state, coordinates, and wheel delta from event.
121 // The right fix needs to extend webkit's implementation of
122 // wheel events and that's not something we want to do at
123 // this time. See bug# 928509
124 // TODO(joshia): Implement the right fix for bug# 928509
125 const int kPageScroll = 10; // 10 times wheel scroll
126
127 UINT key_state = GET_KEYSTATE_WPARAM(wparam);
128 int wheel_delta = static_cast<int>(GET_WHEEL_DELTA_WPARAM(wparam));
129
130 typedef SHORT (WINAPI *GetKeyStateFunction)(int key); 125 typedef SHORT (WINAPI *GetKeyStateFunction)(int key);
131 GetKeyStateFunction get_key_state = GetKeyState; 126 GetKeyStateFunction get_key_state;
132 127 UINT key_state;
133 // Synthesize mousewheel event from a scroll event. 128 float wheel_delta;
134 // This is needed to simulate middle mouse scrolling in some 129 bool horizontal_scroll = false;
135 // laptops (Thinkpads) 130 if ((message == WM_VSCROLL) || (message == WM_HSCROLL)) {
136 if ((WM_VSCROLL == message) || (WM_HSCROLL == message)) { 131 // Synthesize mousewheel event from a scroll event. This is needed to
132 // simulate middle mouse scrolling in some laptops. Use GetAsyncKeyState
133 // for key state since we are synthesizing the input event.
134 get_key_state = GetAsyncKeyState;
135 key_state = 0;
136 if (get_key_state(VK_SHIFT))
137 key_state |= MK_SHIFT;
138 if (get_key_state(VK_CONTROL))
139 key_state |= MK_CONTROL;
137 140
138 POINT cursor_position = {0}; 141 POINT cursor_position = {0};
139 GetCursorPos(&cursor_position); 142 GetCursorPos(&cursor_position);
140
141 global_x = cursor_position.x; 143 global_x = cursor_position.x;
142 global_y = cursor_position.y; 144 global_y = cursor_position.y;
143 145
144 key_state = 0;
145
146 // Since we are synthesizing the wheel event, we have to
147 // use GetAsyncKeyState
148 if (GetAsyncKeyState(VK_SHIFT))
149 key_state |= MK_SHIFT;
150
151 if (GetAsyncKeyState(VK_CONTROL))
152 key_state |= MK_CONTROL;
153
154 switch (LOWORD(wparam)) { 146 switch (LOWORD(wparam)) {
155 case SB_LINEUP: // == SB_LINELEFT 147 case SB_LINEUP: // == SB_LINELEFT
156 wheel_delta = WHEEL_DELTA; 148 wheel_delta = WHEEL_DELTA;
157 break; 149 break;
158 case SB_LINEDOWN: // == SB_LINERIGHT 150 case SB_LINEDOWN: // == SB_LINERIGHT
159 wheel_delta = -WHEEL_DELTA; 151 wheel_delta = -WHEEL_DELTA;
160 break; 152 break;
161 case SB_PAGEUP: 153 case SB_PAGEUP:
162 wheel_delta = kPageScroll * WHEEL_DELTA; 154 wheel_delta = 1;
155 scroll_by_page = true;
163 break; 156 break;
164 case SB_PAGEDOWN: 157 case SB_PAGEDOWN:
165 wheel_delta = -kPageScroll * WHEEL_DELTA; 158 wheel_delta = -1;
159 scroll_by_page = true;
166 break; 160 break;
167 // TODO(joshia): Handle SB_THUMBPOSITION and SB_THUMBTRACK 161 default: // We don't supoprt SB_THUMBPOSITION or SB_THUMBTRACK here.
168 // for compeleteness 162 wheel_delta = 0;
169 default:
170 break; 163 break;
171 } 164 }
172 165
173 // Touchpads (or trackpoints) send the following messages in scrolling 166 if (message == WM_HSCROLL) {
174 // horizontally. 167 horizontal_scroll = true;
175 // * Scrolling left
176 // message == WM_HSCROLL, wparam == SB_LINELEFT (== SB_LINEUP).
177 // * Scrolling right
178 // message == WM_HSCROLL, wparam == SB_LINERIGHT (== SB_LINEDOWN).
179 if (WM_HSCROLL == message) {
180 key_state |= MK_SHIFT;
181 wheel_delta = -wheel_delta; 168 wheel_delta = -wheel_delta;
182 } 169 }
183
184 // Use GetAsyncKeyState for key state since we are synthesizing
185 // the input
186 get_key_state = GetAsyncKeyState;
187 } else { 170 } else {
188 // TODO(hbono): we should add a new variable which indicates scroll 171 // Non-synthesized event; we can just read data off the event.
189 // direction and remove this key_state hack. 172 get_key_state = GetKeyState;
190 if (WM_MOUSEHWHEEL == message) 173 key_state = GET_KEYSTATE_WPARAM(wparam);
191 key_state |= MK_SHIFT;
192 174
193 global_x = static_cast<short>(LOWORD(lparam)); 175 global_x = static_cast<short>(LOWORD(lparam));
194 global_y = static_cast<short>(HIWORD(lparam)); 176 global_y = static_cast<short>(HIWORD(lparam));
177
178 wheel_delta = static_cast<float>(GET_WHEEL_DELTA_WPARAM(wparam));
179 if (((message == WM_MOUSEHWHEEL) || (key_state & MK_SHIFT)) &&
180 (wheel_delta != 0))
181 horizontal_scroll = true;
195 } 182 }
196 183
197 POINT client_point = { global_x, global_y }; 184 // Set modifiers based on key state.
198 ScreenToClient(hwnd, &client_point);
199 x = client_point.x;
200 y = client_point.y;
201
202 // compute the scroll delta based on Raymond Chen's algorithm:
203 // http://blogs.msdn.com/oldnewthing/archive/2003/08/07/54615.aspx
204
205 static int carryover = 0;
206 static HWND last_window = NULL;
207
208 if (hwnd != last_window) {
209 last_window = hwnd;
210 carryover = 0;
211 }
212
213 unsigned long scroll_lines = kDefaultScrollLinesPerWheelDelta;
214 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scroll_lines, 0);
215
216 int delta_lines = 0;
217 if (scroll_lines == WHEEL_PAGESCROLL) {
218 scroll_lines = kPageScroll;
219 }
220
221 if (scroll_lines == 0) {
222 carryover = 0;
223 } else {
224 const int delta = carryover + wheel_delta;
225
226 // see how many lines we should scroll. relies on round-toward-zero.
227 delta_lines = delta * static_cast<int>(scroll_lines) / WHEEL_DELTA;
228
229 // record the unused portion as the next carryover.
230 carryover =
231 delta - delta_lines * WHEEL_DELTA / static_cast<int>(scroll_lines);
232 }
233
234 // Scroll horizontally if shift is held. WebKit's WebKit/win/WebView.cpp
235 // does the equivalent.
236 // TODO(jackson): Support WM_MOUSEHWHEEL = 0x020E event as well.
237 // (Need a mouse with horizontal scrolling capabilities to test it.)
238 if (key_state & MK_SHIFT) {
239 // Scrolling up should move left, scrolling down should move right
240 delta_x = -delta_lines;
241 delta_y = 0;
242 } else {
243 delta_x = 0;
244 delta_y = delta_lines;
245 }
246
247 if (key_state & MK_SHIFT) 185 if (key_state & MK_SHIFT)
248 modifiers |= SHIFT_KEY; 186 modifiers |= SHIFT_KEY;
249 if (key_state & MK_CONTROL) 187 if (key_state & MK_CONTROL)
250 modifiers |= CTRL_KEY; 188 modifiers |= CTRL_KEY;
251
252 // Get any additional key states needed
253 if (get_key_state(VK_MENU) & 0x8000) 189 if (get_key_state(VK_MENU) & 0x8000)
254 modifiers |= (ALT_KEY | META_KEY); 190 modifiers |= (ALT_KEY | META_KEY);
191
192 // Set coordinates by translating event coordinates from screen to client.
193 POINT client_point = { global_x, global_y };
194 MapWindowPoints(NULL, hwnd, &client_point, 1);
195 x = client_point.x;
196 y = client_point.y;
197
198 // Convert wheel delta amount to a number of lines/chars to scroll.
199 float scroll_delta = wheel_delta / WHEEL_DELTA;
200 if (horizontal_scroll) {
201 unsigned long scroll_chars = kDefaultScrollCharsPerWheelDelta;
202 SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scroll_chars, 0);
203 scroll_delta *= static_cast<float>(scroll_chars);
204 } else {
205 unsigned long scroll_lines = kDefaultScrollLinesPerWheelDelta;
206 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scroll_lines, 0);
207 if (scroll_lines == WHEEL_PAGESCROLL)
208 scroll_by_page = true;
209 if (!scroll_by_page)
210 scroll_delta *= static_cast<float>(scroll_lines);
211 }
212
213 // Set scroll amount based on above calculations.
214 if (horizontal_scroll) {
215 // Scrolling up should move left, scrolling down should move right. This is
216 // opposite Safari, but seems more consistent with vertical scrolling.
217 delta_x = scroll_delta;
218 delta_y = 0;
219 } else {
220 delta_x = 0;
221 delta_y = scroll_delta;
222 }
255 } 223 }
256 224
257 // WebKeyboardEvent ----------------------------------------------------------- 225 // WebKeyboardEvent -----------------------------------------------------------
258 226
259 bool IsKeyPad(WPARAM wparam, LPARAM lparam) { 227 bool IsKeyPad(WPARAM wparam, LPARAM lparam) {
260 bool keypad = false; 228 bool keypad = false;
261 switch (wparam) { 229 switch (wparam) {
262 case VK_RETURN: 230 case VK_RETURN:
263 keypad = (lparam >> 16) & KF_EXTENDED; 231 keypad = (lparam >> 16) & KF_EXTENDED;
264 break; 232 break;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 modifiers |= CTRL_KEY; 324 modifiers |= CTRL_KEY;
357 if (GetKeyState(VK_MENU) & 0x8000) 325 if (GetKeyState(VK_MENU) & 0x8000)
358 modifiers |= (ALT_KEY | META_KEY); 326 modifiers |= (ALT_KEY | META_KEY);
359 327
360 if (LOWORD(lparam) > 1) 328 if (LOWORD(lparam) > 1)
361 modifiers |= IS_AUTO_REPEAT; 329 modifiers |= IS_AUTO_REPEAT;
362 if (IsKeyPad(wparam, lparam)) 330 if (IsKeyPad(wparam, lparam))
363 modifiers |= IS_KEYPAD; 331 modifiers |= IS_KEYPAD;
364 } 332 }
365 333
OLDNEW
« webkit/glue/webinputevent_mac.mm ('K') | « webkit/glue/webinputevent_mac.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698