| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2006-2009 Google Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | |
| 31 #include "config.h" | |
| 32 #include "WebInputEventFactory.h" | |
| 33 | |
| 34 #include "WebInputEvent.h" | |
| 35 | |
| 36 #include "wtf/Assertions.h" | |
| 37 | |
| 38 namespace WebKit { | |
| 39 | |
| 40 static const unsigned long defaultScrollLinesPerWheelDelta = 3; | |
| 41 static const unsigned long defaultScrollCharsPerWheelDelta = 1; | |
| 42 | |
| 43 // WebKeyboardEvent ----------------------------------------------------------- | |
| 44 | |
| 45 static bool isKeyDown(WPARAM wparam) | |
| 46 { | |
| 47 return GetKeyState(wparam) & 0x8000; | |
| 48 } | |
| 49 | |
| 50 static int getLocationModifier(WPARAM wparam, LPARAM lparam) | |
| 51 { | |
| 52 int modifier = 0; | |
| 53 switch (wparam) { | |
| 54 case VK_RETURN: | |
| 55 if ((lparam >> 16) & KF_EXTENDED) | |
| 56 modifier = WebInputEvent::IsKeyPad; | |
| 57 break; | |
| 58 case VK_INSERT: | |
| 59 case VK_DELETE: | |
| 60 case VK_HOME: | |
| 61 case VK_END: | |
| 62 case VK_PRIOR: | |
| 63 case VK_NEXT: | |
| 64 case VK_UP: | |
| 65 case VK_DOWN: | |
| 66 case VK_LEFT: | |
| 67 case VK_RIGHT: | |
| 68 if (!((lparam >> 16) & KF_EXTENDED)) | |
| 69 modifier = WebInputEvent::IsKeyPad; | |
| 70 break; | |
| 71 case VK_NUMPAD0: | |
| 72 case VK_NUMPAD1: | |
| 73 case VK_NUMPAD2: | |
| 74 case VK_NUMPAD3: | |
| 75 case VK_NUMPAD4: | |
| 76 case VK_NUMPAD5: | |
| 77 case VK_NUMPAD6: | |
| 78 case VK_NUMPAD7: | |
| 79 case VK_NUMPAD8: | |
| 80 case VK_NUMPAD9: | |
| 81 case VK_DIVIDE: | |
| 82 case VK_MULTIPLY: | |
| 83 case VK_SUBTRACT: | |
| 84 case VK_ADD: | |
| 85 case VK_DECIMAL: | |
| 86 case VK_CLEAR: | |
| 87 modifier = WebInputEvent::IsKeyPad; | |
| 88 break; | |
| 89 case VK_SHIFT: | |
| 90 if (isKeyDown(VK_LSHIFT)) | |
| 91 modifier = WebInputEvent::IsLeft; | |
| 92 else if (isKeyDown(VK_RSHIFT)) | |
| 93 modifier = WebInputEvent::IsRight; | |
| 94 break; | |
| 95 case VK_CONTROL: | |
| 96 if (isKeyDown(VK_LCONTROL)) | |
| 97 modifier = WebInputEvent::IsLeft; | |
| 98 else if (isKeyDown(VK_RCONTROL)) | |
| 99 modifier = WebInputEvent::IsRight; | |
| 100 break; | |
| 101 case VK_MENU: | |
| 102 if (isKeyDown(VK_LMENU)) | |
| 103 modifier = WebInputEvent::IsLeft; | |
| 104 else if (isKeyDown(VK_RMENU)) | |
| 105 modifier = WebInputEvent::IsRight; | |
| 106 break; | |
| 107 case VK_LWIN: | |
| 108 modifier = WebInputEvent::IsLeft; | |
| 109 break; | |
| 110 case VK_RWIN: | |
| 111 modifier = WebInputEvent::IsRight; | |
| 112 break; | |
| 113 } | |
| 114 | |
| 115 ASSERT(!modifier | |
| 116 || modifier == WebInputEvent::IsKeyPad | |
| 117 || modifier == WebInputEvent::IsLeft | |
| 118 || modifier == WebInputEvent::IsRight); | |
| 119 return modifier; | |
| 120 } | |
| 121 | |
| 122 // Loads the state for toggle keys into the event. | |
| 123 static void SetToggleKeyState(WebInputEvent* event) | |
| 124 { | |
| 125 // Low bit set from GetKeyState indicates "toggled". | |
| 126 if (::GetKeyState(VK_NUMLOCK) & 1) | |
| 127 event->modifiers |= WebInputEvent::NumLockOn; | |
| 128 if (::GetKeyState(VK_CAPITAL) & 1) | |
| 129 event->modifiers |= WebInputEvent::CapsLockOn; | |
| 130 } | |
| 131 | |
| 132 WebKeyboardEvent WebInputEventFactory::keyboardEvent(HWND hwnd, UINT message, | |
| 133 WPARAM wparam, LPARAM lpara
m) | |
| 134 { | |
| 135 WebKeyboardEvent result; | |
| 136 | |
| 137 // TODO(pkasting): http://b/1117926 Are we guaranteed that the message that | |
| 138 // GetMessageTime() refers to is the same one that we're passed in? Perhaps | |
| 139 // one of the construction parameters should be the time passed by the | |
| 140 // caller, who would know for sure. | |
| 141 result.timeStampSeconds = GetMessageTime() / 1000.0; | |
| 142 | |
| 143 result.windowsKeyCode = static_cast<int>(wparam); | |
| 144 // Record the scan code (along with other context bits) for this key event. | |
| 145 result.nativeKeyCode = static_cast<int>(lparam); | |
| 146 | |
| 147 switch (message) { | |
| 148 case WM_SYSKEYDOWN: | |
| 149 result.isSystemKey = true; | |
| 150 case WM_KEYDOWN: | |
| 151 result.type = WebInputEvent::RawKeyDown; | |
| 152 break; | |
| 153 case WM_SYSKEYUP: | |
| 154 result.isSystemKey = true; | |
| 155 case WM_KEYUP: | |
| 156 result.type = WebInputEvent::KeyUp; | |
| 157 break; | |
| 158 case WM_IME_CHAR: | |
| 159 result.type = WebInputEvent::Char; | |
| 160 break; | |
| 161 case WM_SYSCHAR: | |
| 162 result.isSystemKey = true; | |
| 163 result.type = WebInputEvent::Char; | |
| 164 case WM_CHAR: | |
| 165 result.type = WebInputEvent::Char; | |
| 166 break; | |
| 167 default: | |
| 168 ASSERT_NOT_REACHED(); | |
| 169 } | |
| 170 | |
| 171 if (result.type == WebInputEvent::Char || result.type == WebInputEvent::RawK
eyDown) { | |
| 172 result.text[0] = result.windowsKeyCode; | |
| 173 result.unmodifiedText[0] = result.windowsKeyCode; | |
| 174 } | |
| 175 if (result.type != WebInputEvent::Char) | |
| 176 result.setKeyIdentifierFromWindowsKeyCode(); | |
| 177 | |
| 178 if (GetKeyState(VK_SHIFT) & 0x8000) | |
| 179 result.modifiers |= WebInputEvent::ShiftKey; | |
| 180 if (GetKeyState(VK_CONTROL) & 0x8000) | |
| 181 result.modifiers |= WebInputEvent::ControlKey; | |
| 182 if (GetKeyState(VK_MENU) & 0x8000) | |
| 183 result.modifiers |= WebInputEvent::AltKey; | |
| 184 // NOTE: There doesn't seem to be a way to query the mouse button state in | |
| 185 // this case. | |
| 186 | |
| 187 if (LOWORD(lparam) > 1) | |
| 188 result.modifiers |= WebInputEvent::IsAutoRepeat; | |
| 189 | |
| 190 result.modifiers |= getLocationModifier(wparam, lparam); | |
| 191 | |
| 192 SetToggleKeyState(&result); | |
| 193 return result; | |
| 194 } | |
| 195 | |
| 196 // WebMouseEvent -------------------------------------------------------------- | |
| 197 | |
| 198 static int gLastClickCount; | |
| 199 static double gLastClickTime; | |
| 200 | |
| 201 static LPARAM GetRelativeCursorPos(HWND hwnd) | |
| 202 { | |
| 203 POINT pos = {-1, -1}; | |
| 204 GetCursorPos(&pos); | |
| 205 ScreenToClient(hwnd, &pos); | |
| 206 return MAKELPARAM(pos.x, pos.y); | |
| 207 } | |
| 208 | |
| 209 void WebInputEventFactory::resetLastClickState() | |
| 210 { | |
| 211 gLastClickTime = gLastClickCount = 0; | |
| 212 } | |
| 213 | |
| 214 WebMouseEvent WebInputEventFactory::mouseEvent(HWND hwnd, UINT message, | |
| 215 WPARAM wparam, LPARAM lparam) | |
| 216 { | |
| 217 WebMouseEvent result; //(WebInputEvent::Uninitialized()); | |
| 218 | |
| 219 switch (message) { | |
| 220 case WM_MOUSEMOVE: | |
| 221 result.type = WebInputEvent::MouseMove; | |
| 222 if (wparam & MK_LBUTTON) | |
| 223 result.button = WebMouseEvent::ButtonLeft; | |
| 224 else if (wparam & MK_MBUTTON) | |
| 225 result.button = WebMouseEvent::ButtonMiddle; | |
| 226 else if (wparam & MK_RBUTTON) | |
| 227 result.button = WebMouseEvent::ButtonRight; | |
| 228 else | |
| 229 result.button = WebMouseEvent::ButtonNone; | |
| 230 break; | |
| 231 case WM_MOUSELEAVE: | |
| 232 result.type = WebInputEvent::MouseLeave; | |
| 233 result.button = WebMouseEvent::ButtonNone; | |
| 234 // set the current mouse position (relative to the client area of the | |
| 235 // current window) since none is specified for this event | |
| 236 lparam = GetRelativeCursorPos(hwnd); | |
| 237 break; | |
| 238 case WM_LBUTTONDOWN: | |
| 239 case WM_LBUTTONDBLCLK: | |
| 240 result.type = WebInputEvent::MouseDown; | |
| 241 result.button = WebMouseEvent::ButtonLeft; | |
| 242 break; | |
| 243 case WM_MBUTTONDOWN: | |
| 244 case WM_MBUTTONDBLCLK: | |
| 245 result.type = WebInputEvent::MouseDown; | |
| 246 result.button = WebMouseEvent::ButtonMiddle; | |
| 247 break; | |
| 248 case WM_RBUTTONDOWN: | |
| 249 case WM_RBUTTONDBLCLK: | |
| 250 result.type = WebInputEvent::MouseDown; | |
| 251 result.button = WebMouseEvent::ButtonRight; | |
| 252 break; | |
| 253 case WM_LBUTTONUP: | |
| 254 result.type = WebInputEvent::MouseUp; | |
| 255 result.button = WebMouseEvent::ButtonLeft; | |
| 256 break; | |
| 257 case WM_MBUTTONUP: | |
| 258 result.type = WebInputEvent::MouseUp; | |
| 259 result.button = WebMouseEvent::ButtonMiddle; | |
| 260 break; | |
| 261 case WM_RBUTTONUP: | |
| 262 result.type = WebInputEvent::MouseUp; | |
| 263 result.button = WebMouseEvent::ButtonRight; | |
| 264 break; | |
| 265 default: | |
| 266 ASSERT_NOT_REACHED(); | |
| 267 } | |
| 268 | |
| 269 // TODO(pkasting): http://b/1117926 Are we guaranteed that the message that | |
| 270 // GetMessageTime() refers to is the same one that we're passed in? Perhaps | |
| 271 // one of the construction parameters should be the time passed by the | |
| 272 // caller, who would know for sure. | |
| 273 result.timeStampSeconds = GetMessageTime() / 1000.0; | |
| 274 | |
| 275 // set position fields: | |
| 276 | |
| 277 result.x = static_cast<short>(LOWORD(lparam)); | |
| 278 result.y = static_cast<short>(HIWORD(lparam)); | |
| 279 result.windowX = result.x; | |
| 280 result.windowY = result.y; | |
| 281 | |
| 282 POINT globalPoint = { result.x, result.y }; | |
| 283 ClientToScreen(hwnd, &globalPoint); | |
| 284 | |
| 285 result.globalX = globalPoint.x; | |
| 286 result.globalY = globalPoint.y; | |
| 287 | |
| 288 // calculate number of clicks: | |
| 289 | |
| 290 // This differs slightly from the WebKit code in WebKit/win/WebView.cpp | |
| 291 // where their original code looks buggy. | |
| 292 static int lastClickPositionX; | |
| 293 static int lastClickPositionY; | |
| 294 static WebMouseEvent::Button lastClickButton = WebMouseEvent::ButtonLeft; | |
| 295 | |
| 296 double currentTime = result.timeStampSeconds; | |
| 297 bool cancelPreviousClick = | |
| 298 (abs(lastClickPositionX - result.x) > (GetSystemMetrics(SM_CXDOUBLECLK)
/ 2)) | |
| 299 || (abs(lastClickPositionY - result.y) > (GetSystemMetrics(SM_CYDOUBLECL
K) / 2)) | |
| 300 || ((currentTime - gLastClickTime) * 1000.0 > GetDoubleClickTime()); | |
| 301 | |
| 302 if (result.type == WebInputEvent::MouseDown) { | |
| 303 if (!cancelPreviousClick && (result.button == lastClickButton)) | |
| 304 ++gLastClickCount; | |
| 305 else { | |
| 306 gLastClickCount = 1; | |
| 307 lastClickPositionX = result.x; | |
| 308 lastClickPositionY = result.y; | |
| 309 } | |
| 310 gLastClickTime = currentTime; | |
| 311 lastClickButton = result.button; | |
| 312 } else if (result.type == WebInputEvent::MouseMove | |
| 313 || result.type == WebInputEvent::MouseLeave) { | |
| 314 if (cancelPreviousClick) { | |
| 315 gLastClickCount = 0; | |
| 316 lastClickPositionX = 0; | |
| 317 lastClickPositionY = 0; | |
| 318 gLastClickTime = 0; | |
| 319 } | |
| 320 } | |
| 321 result.clickCount = gLastClickCount; | |
| 322 | |
| 323 // set modifiers: | |
| 324 | |
| 325 if (wparam & MK_CONTROL) | |
| 326 result.modifiers |= WebInputEvent::ControlKey; | |
| 327 if (wparam & MK_SHIFT) | |
| 328 result.modifiers |= WebInputEvent::ShiftKey; | |
| 329 if (GetKeyState(VK_MENU) & 0x8000) | |
| 330 result.modifiers |= WebInputEvent::AltKey; | |
| 331 if (wparam & MK_LBUTTON) | |
| 332 result.modifiers |= WebInputEvent::LeftButtonDown; | |
| 333 if (wparam & MK_MBUTTON) | |
| 334 result.modifiers |= WebInputEvent::MiddleButtonDown; | |
| 335 if (wparam & MK_RBUTTON) | |
| 336 result.modifiers |= WebInputEvent::RightButtonDown; | |
| 337 | |
| 338 SetToggleKeyState(&result); | |
| 339 return result; | |
| 340 } | |
| 341 | |
| 342 // WebMouseWheelEvent --------------------------------------------------------- | |
| 343 | |
| 344 WebMouseWheelEvent WebInputEventFactory::mouseWheelEvent(HWND hwnd, UINT message
, | |
| 345 WPARAM wparam, LPARAM l
param) | |
| 346 { | |
| 347 WebMouseWheelEvent result; //(WebInputEvent::Uninitialized()); | |
| 348 | |
| 349 result.type = WebInputEvent::MouseWheel; | |
| 350 | |
| 351 // TODO(pkasting): http://b/1117926 Are we guaranteed that the message that | |
| 352 // GetMessageTime() refers to is the same one that we're passed in? Perhaps | |
| 353 // one of the construction parameters should be the time passed by the | |
| 354 // caller, who would know for sure. | |
| 355 result.timeStampSeconds = GetMessageTime() / 1000.0; | |
| 356 | |
| 357 result.button = WebMouseEvent::ButtonNone; | |
| 358 | |
| 359 // Get key state, coordinates, and wheel delta from event. | |
| 360 typedef SHORT (WINAPI *GetKeyStateFunction)(int key); | |
| 361 GetKeyStateFunction getKeyState; | |
| 362 UINT keyState; | |
| 363 float wheelDelta; | |
| 364 bool horizontalScroll = false; | |
| 365 if ((message == WM_VSCROLL) || (message == WM_HSCROLL)) { | |
| 366 // Synthesize mousewheel event from a scroll event. This is needed to | |
| 367 // simulate middle mouse scrolling in some laptops. Use GetAsyncKeyStat
e | |
| 368 // for key state since we are synthesizing the input event. | |
| 369 getKeyState = GetAsyncKeyState; | |
| 370 keyState = 0; | |
| 371 if (getKeyState(VK_SHIFT)) | |
| 372 keyState |= MK_SHIFT; | |
| 373 if (getKeyState(VK_CONTROL)) | |
| 374 keyState |= MK_CONTROL; | |
| 375 // NOTE: There doesn't seem to be a way to query the mouse button state | |
| 376 // in this case. | |
| 377 | |
| 378 POINT cursorPosition = {0}; | |
| 379 GetCursorPos(&cursorPosition); | |
| 380 result.globalX = cursorPosition.x; | |
| 381 result.globalY = cursorPosition.y; | |
| 382 | |
| 383 switch (LOWORD(wparam)) { | |
| 384 case SB_LINEUP: // == SB_LINELEFT | |
| 385 wheelDelta = WHEEL_DELTA; | |
| 386 break; | |
| 387 case SB_LINEDOWN: // == SB_LINERIGHT | |
| 388 wheelDelta = -WHEEL_DELTA; | |
| 389 break; | |
| 390 case SB_PAGEUP: | |
| 391 wheelDelta = 1; | |
| 392 result.scrollByPage = true; | |
| 393 break; | |
| 394 case SB_PAGEDOWN: | |
| 395 wheelDelta = -1; | |
| 396 result.scrollByPage = true; | |
| 397 break; | |
| 398 default: // We don't supoprt SB_THUMBPOSITION or SB_THUMBTRACK here. | |
| 399 wheelDelta = 0; | |
| 400 break; | |
| 401 } | |
| 402 | |
| 403 if (message == WM_HSCROLL) | |
| 404 horizontalScroll = true; | |
| 405 } else { | |
| 406 // Non-synthesized event; we can just read data off the event. | |
| 407 getKeyState = GetKeyState; | |
| 408 keyState = GET_KEYSTATE_WPARAM(wparam); | |
| 409 | |
| 410 result.globalX = static_cast<short>(LOWORD(lparam)); | |
| 411 result.globalY = static_cast<short>(HIWORD(lparam)); | |
| 412 | |
| 413 wheelDelta = static_cast<float>(GET_WHEEL_DELTA_WPARAM(wparam)); | |
| 414 if (message == WM_MOUSEHWHEEL) { | |
| 415 horizontalScroll = true; | |
| 416 wheelDelta = -wheelDelta; // Windows is <- -/+ ->, WebKit <- +/- ->
. | |
| 417 } | |
| 418 } | |
| 419 if (keyState & MK_SHIFT) | |
| 420 horizontalScroll = true; | |
| 421 | |
| 422 // Set modifiers based on key state. | |
| 423 if (keyState & MK_SHIFT) | |
| 424 result.modifiers |= WebInputEvent::ShiftKey; | |
| 425 if (keyState & MK_CONTROL) | |
| 426 result.modifiers |= WebInputEvent::ControlKey; | |
| 427 if (getKeyState(VK_MENU) & 0x8000) | |
| 428 result.modifiers |= WebInputEvent::AltKey; | |
| 429 if (keyState & MK_LBUTTON) | |
| 430 result.modifiers |= WebInputEvent::LeftButtonDown; | |
| 431 if (keyState & MK_MBUTTON) | |
| 432 result.modifiers |= WebInputEvent::MiddleButtonDown; | |
| 433 if (keyState & MK_RBUTTON) | |
| 434 result.modifiers |= WebInputEvent::RightButtonDown; | |
| 435 | |
| 436 SetToggleKeyState(&result); | |
| 437 | |
| 438 // Set coordinates by translating event coordinates from screen to client. | |
| 439 POINT clientPoint = { result.globalX, result.globalY }; | |
| 440 MapWindowPoints(0, hwnd, &clientPoint, 1); | |
| 441 result.x = clientPoint.x; | |
| 442 result.y = clientPoint.y; | |
| 443 result.windowX = result.x; | |
| 444 result.windowY = result.y; | |
| 445 | |
| 446 // Convert wheel delta amount to a number of pixels to scroll. | |
| 447 // | |
| 448 // How many pixels should we scroll per line? Gecko uses the height of the | |
| 449 // current line, which means scroll distance changes as you go through the | |
| 450 // page or go to different pages. IE 8 is ~60 px/line, although the value | |
| 451 // seems to vary slightly by page and zoom level. Also, IE defaults to | |
| 452 // smooth scrolling while Firefox doesn't, so it can get away with somewhat | |
| 453 // larger scroll values without feeling as jerky. Here we use 100 px per | |
| 454 // three lines (the default scroll amount is three lines per wheel tick). | |
| 455 // Even though we have smooth scrolling, we don't make this as large as IE | |
| 456 // because subjectively IE feels like it scrolls farther than you want while | |
| 457 // reading articles. | |
| 458 static const float scrollbarPixelsPerLine = 100.0f / 3.0f; | |
| 459 wheelDelta /= WHEEL_DELTA; | |
| 460 float scrollDelta = wheelDelta; | |
| 461 if (horizontalScroll) { | |
| 462 unsigned long scrollChars = defaultScrollCharsPerWheelDelta; | |
| 463 SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0); | |
| 464 // TODO(pkasting): Should probably have a different multiplier | |
| 465 // scrollbarPixelsPerChar here. | |
| 466 scrollDelta *= static_cast<float>(scrollChars) * scrollbarPixelsPerLine; | |
| 467 } else { | |
| 468 unsigned long scrollLines = defaultScrollLinesPerWheelDelta; | |
| 469 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0); | |
| 470 if (scrollLines == WHEEL_PAGESCROLL) | |
| 471 result.scrollByPage = true; | |
| 472 if (!result.scrollByPage) | |
| 473 scrollDelta *= static_cast<float>(scrollLines) * scrollbarPixelsPerL
ine; | |
| 474 } | |
| 475 | |
| 476 // Set scroll amount based on above calculations. WebKit expects positive | |
| 477 // deltaY to mean "scroll up" and positive deltaX to mean "scroll left". | |
| 478 if (horizontalScroll) { | |
| 479 result.deltaX = scrollDelta; | |
| 480 result.wheelTicksX = wheelDelta; | |
| 481 } else { | |
| 482 result.deltaY = scrollDelta; | |
| 483 result.wheelTicksY = wheelDelta; | |
| 484 } | |
| 485 | |
| 486 return result; | |
| 487 } | |
| 488 | |
| 489 } // namespace WebKit | |
| OLD | NEW |