diff options
author | Sérgio Martins <sergio.martins@kdab.com> | 2015-03-25 13:37:31 +0000 |
---|---|---|
committer | Sérgio Martins <sergio.martins@kdab.com> | 2015-03-26 14:57:45 +0000 |
commit | f451d4800595caf00b6aa61408006cd100a6d416 (patch) | |
tree | 70d194ceb890279872ea3c60d17bfb1051b2185a /src | |
parent | eea5a6ea15651a4bc2d0d1b1f45a2542a26083d0 (diff) | |
download | qtbase-f451d4800595caf00b6aa61408006cd100a6d416.tar.gz |
Windows: Add support for horizontal scroll on some touchpads.
While most (all?) touchpads send WM_MOUSEWHEEL for vertical scroll
the story is quite different for horizontal scroll. Some of them
send WM_HSCROLL instead of WM_MOUSEHWHEEL.
Some of them even send left/right key event but those are lost cases.
Task-number: QTBUG-45120
Change-Id: I3bf86e25a6f4f3ba03ac7e89a23f4b7bc432f2de
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Diffstat (limited to 'src')
4 files changed, 69 insertions, 18 deletions
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index 083d82ed8c..74fa561e10 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -57,7 +57,8 @@ enum TouchEventFlag = 0x400000, ClipboardEventFlag = 0x800000, ApplicationEventFlag = 0x1000000, - ThemingEventFlag = 0x2000000 + ThemingEventFlag = 0x2000000, + GenericEventFlag = 0x4000000, // Misc }; enum WindowsEventType // Simplify event types @@ -108,6 +109,7 @@ enum WindowsEventType // Simplify event types CompositionSettingsChanged = ThemingEventFlag + 2, DisplayChangedEvent = 437, SettingChangedEvent = DisplayChangedEvent + 1, + ScrollEvent = GenericEventFlag + 1, ContextMenu = 123, GestureEvent = 124, UnknownEvent = 542 @@ -145,6 +147,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI return QtWindows::CursorEvent; case WM_MOUSELEAVE: return QtWindows::MouseEvent; + case WM_HSCROLL: + return QtWindows::ScrollEvent; case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: return QtWindows::MouseWheelEvent; diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 72bfeec143..bcd3922773 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -1032,6 +1032,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return true; } #endif + case QtWindows::ScrollEvent: +#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) + return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result); +#else + return d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result); +#endif case QtWindows::MouseWheelEvent: case QtWindows::MouseEvent: case QtWindows::LeaveEvent: diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 0fa34041d6..0ce8c09fc4 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -42,6 +42,7 @@ #include <QtGui/QGuiApplication> #include <QtGui/QScreen> #include <QtGui/QWindow> +#include <QtGui/QCursor> #include <QtCore/QDebug> #include <QtCore/QScopedArrayPointer> @@ -375,6 +376,31 @@ static bool isValidWheelReceiver(QWindow *candidate) return false; } +static void redirectWheelEvent(QWindow *window, const QPoint &globalPos, int delta, + Qt::Orientation orientation, Qt::KeyboardModifiers mods) +{ + // Redirect wheel event to one of the following, in order of preference: + // 1) The window under mouse + // 2) The window receiving the event + // If a window is blocked by modality, it can't get the event. + + QWindow *receiver = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE); + bool handleEvent = true; + if (!isValidWheelReceiver(receiver)) { + receiver = window; + if (!isValidWheelReceiver(receiver)) + handleEvent = false; + } + + if (handleEvent) { + const QPoint posDip = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos) / QWindowsScaling::factor(); + QWindowSystemInterface::handleWheelEvent(receiver, + posDip, globalPos / QWindowsScaling::factor(), + delta / QWindowsScaling::factor(), + orientation, mods); + } +} + bool QWindowsMouseHandler::translateMouseWheelEvent(QWindow *window, HWND, MSG msg, LRESULT *) { @@ -397,27 +423,40 @@ bool QWindowsMouseHandler::translateMouseWheelEvent(QWindow *window, HWND, if (msg.message == WM_MOUSEHWHEEL) delta = -delta; - // Redirect wheel event to one of the following, in order of preference: - // 1) The window under mouse - // 2) The window receiving the event - // If a window is blocked by modality, it can't get the event. const QPoint globalPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); - QWindow *receiver = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE); - bool handleEvent = true; - if (!isValidWheelReceiver(receiver)) { - receiver = window; - if (!isValidWheelReceiver(receiver)) - handleEvent = false; - } + redirectWheelEvent(window, globalPos, delta, orientation, mods); - if (handleEvent) { - const QPoint posDip = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos) / QWindowsScaling::factor(); - QWindowSystemInterface::handleWheelEvent(receiver, - posDip, globalPos / QWindowsScaling::factor(), - delta / QWindowsScaling::factor(), - orientation, mods); + return true; +} + +bool QWindowsMouseHandler::translateScrollEvent(QWindow *window, HWND, + MSG msg, LRESULT *) +{ + // This is a workaround against some touchpads that send WM_HSCROLL instead of WM_MOUSEHWHEEL. + // We could also handle vertical scroll here but there's no reason to, there's no bug for vertical + // (broken vertical scroll would have been noticed long time ago), so lets keep the change small + // and minimize the chance for regressions. + + int delta = 0; + switch (LOWORD(msg.wParam)) { + case SB_LINELEFT: + delta = 120; + break; + case SB_LINERIGHT: + delta = -120; + break; + case SB_PAGELEFT: + delta = 240; + break; + case SB_PAGERIGHT: + delta = -240; + break; + default: + return false; } + redirectWheelEvent(window, QCursor::pos(), delta, Qt::Horizontal, Qt::NoModifier); + return true; } diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h index 60fe26b2b9..76d45897f0 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.h +++ b/src/plugins/platforms/windows/qwindowsmousehandler.h @@ -59,6 +59,8 @@ public: bool translateTouchEvent(QWindow *widget, HWND hwnd, QtWindows::WindowsEventType t, MSG msg, LRESULT *result); + bool translateScrollEvent(QWindow *window, HWND hwnd, + MSG msg, LRESULT *result); static inline Qt::MouseButtons keyStateToMouseButtons(int); static inline Qt::KeyboardModifiers keyStateToModifiers(int); |