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>bb10
parent
eea5a6ea15
commit
f451d48005
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1031,6 +1031,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
|
|||
QWindowsWindow::baseWindowOf(platformWindow->window())->applyCursor();
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -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,26 +423,39 @@ 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (handleEvent) {
|
||||
const QPoint posDip = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos) / QWindowsScaling::factor();
|
||||
QWindowSystemInterface::handleWheelEvent(receiver,
|
||||
posDip, globalPos / QWindowsScaling::factor(),
|
||||
delta / QWindowsScaling::factor(),
|
||||
orientation, mods);
|
||||
}
|
||||
redirectWheelEvent(window, QCursor::pos(), delta, Qt::Horizontal, Qt::NoModifier);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue