diff options
author | David Edmundson <davidedmundson@kde.org> | 2023-01-18 13:44:46 +0000 |
---|---|---|
committer | Vlad Zahorodnii <vlad.zahorodnii@kde.org> | 2023-11-06 13:30:49 +0200 |
commit | cf7fb478f5b57ac71181d7450045538de6e24176 (patch) | |
tree | 6edb81e395205fa763dc01920a2723a2ceb7e0d3 /src | |
parent | 2eff0cfa25d60091c36b78490591bf9509bcc624 (diff) |
client: Implement QWheelEvent::inverted
"Natural scrolling" is a setting that makes trackpads act in the
inverse; moving up moves content down to mimic behavior of
touchscreens.
However not all scroll events are used for scrolling, so it can be
useful to know the real direction. This was exposed in QWheelEvent it
just needs plumbing.
While this is technically an implementation of wl_pointer version 9,
on the other hand, it fixes the value of QWheelEvent::inverted(), which
makes scrolling with touchpad on wayland behave in a more expected
fashion, so this can be viewed as a bugfix as well. The patch has been
tested for almost a month, no regressions have been noticed.
Change-Id: I050b8b3e55796beff33badb7c073c0b93589294e
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Reviewed-by: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
(cherry picked from commit 6b8a99afa3c6dff60bd4096c2273f8db0e4d1247)
Diffstat (limited to 'src')
-rw-r--r-- | src/client/qwaylandinputdevice.cpp | 36 | ||||
-rw-r--r-- | src/client/qwaylandinputdevice_p.h | 7 | ||||
-rw-r--r-- | src/client/qwaylandwindow.cpp | 4 |
3 files changed, 37 insertions, 10 deletions
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index 51a98ca61..a4f8757e3 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -383,7 +383,7 @@ QWaylandInputDevice::Touch::~Touch() } QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, int version, uint32_t id) - : QtWayland::wl_seat(display->wl_registry(), id, qMin(version, 8)) + : QtWayland::wl_seat(display->wl_registry(), id, qMin(version, 9)) , mQDisplay(display) , mDisplay(display->wl_display()) { @@ -879,9 +879,9 @@ class WheelEvent : public QWaylandPointerEvent public: WheelEvent(QWaylandWindow *surface, Qt::ScrollPhase phase, ulong timestamp, const QPointF &local, const QPointF &global, const QPoint &pixelDelta, const QPoint &angleDelta, - Qt::MouseEventSource source, Qt::KeyboardModifiers modifiers) + Qt::MouseEventSource source, Qt::KeyboardModifiers modifiers, bool inverted) : QWaylandPointerEvent(QEvent::Wheel, phase, surface, timestamp, - local, global, pixelDelta, angleDelta, source, modifiers) + local, global, pixelDelta, angleDelta, source, modifiers, inverted) { } }; @@ -975,8 +975,9 @@ void QWaylandInputDevice::Pointer::pointer_axis_stop(uint32_t time, uint32_t axi if (!target) target = focusWindow(); Qt::KeyboardModifiers mods = mParent->modifiers(); + const bool inverted = mFrameData.verticalAxisInverted || mFrameData.horizontalAxisInverted; WheelEvent wheelEvent(focusWindow(), Qt::ScrollEnd, mParent->mTime, mSurfacePos, mGlobalPos, - QPoint(), QPoint(), Qt::MouseEventNotSynthesized, mods); + QPoint(), QPoint(), Qt::MouseEventNotSynthesized, mods, inverted); target->handleMouse(mParent, wheelEvent); mScrollBeginSent = false; mScrollDeltaRemainder = QPointF(); @@ -1025,6 +1026,21 @@ void QWaylandInputDevice::Pointer::pointer_axis_value120(uint32_t axis, int32_t } } +void QWaylandInputDevice::Pointer::pointer_axis_relative_direction(uint32_t axis, uint32_t direction) +{ + const bool inverted = direction == axis_relative_direction_inverted; + switch (axis) { + case axis_vertical_scroll: + mFrameData.verticalAxisInverted = inverted; + break; + case axis_horizontal_scroll: + mFrameData.horizontalAxisInverted = inverted; + break; + default: + qCWarning(lcQpaWaylandInput) << "wl_pointer.axis_relative_direction: Unknown axis:" << axis; + } +} + void QWaylandInputDevice::Pointer::setFrameEvent(QWaylandPointerEvent *event) { qCDebug(lcQpaWaylandInput) << "Setting frame event " << event->type; @@ -1046,6 +1062,8 @@ void QWaylandInputDevice::Pointer::FrameData::resetScrollData() delta120 = QPoint(); delta = QPointF(); axisSource = axis_source_wheel; + horizontalAxisInverted = false; + verticalAxisInverted = false; } bool QWaylandInputDevice::Pointer::FrameData::hasPixelDelta() const @@ -1127,7 +1145,7 @@ void QWaylandInputDevice::Pointer::flushScrollEvent() target->handleMouse(mParent, WheelEvent(focusWindow(), Qt::ScrollBegin, mParent->mTime, mSurfacePos, mGlobalPos, QPoint(), QPoint(), Qt::MouseEventNotSynthesized, - mParent->modifiers())); + mParent->modifiers(), false)); mScrollBeginSent = true; mScrollDeltaRemainder = QPointF(); } @@ -1136,11 +1154,15 @@ void QWaylandInputDevice::Pointer::flushScrollEvent() QPoint pixelDelta = mFrameData.pixelDeltaAndError(&mScrollDeltaRemainder); Qt::MouseEventSource source = mFrameData.wheelEventSource(); + + // The wayland protocol has separate horizontal and vertical axes, Qt has just the one inverted flag + // Pragmatically it should't come up + const bool inverted = mFrameData.verticalAxisInverted || mFrameData.horizontalAxisInverted; + qCDebug(lcQpaWaylandInput) << "Flushing scroll event" << phase << pixelDelta << angleDelta; target->handleMouse(mParent, WheelEvent(focusWindow(), phase, mParent->mTime, mSurfacePos, mGlobalPos, - pixelDelta, angleDelta, source, mParent->modifiers())); + pixelDelta, angleDelta, source, mParent->modifiers(), inverted)); } - mFrameData.resetScrollData(); } diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h index a2019e8c0..4561bdefd 100644 --- a/src/client/qwaylandinputdevice_p.h +++ b/src/client/qwaylandinputdevice_p.h @@ -309,6 +309,7 @@ protected: void pointer_axis_discrete(uint32_t axis, int32_t value) override; void pointer_frame() override; void pointer_axis_value120(uint32_t axis, int32_t value120) override; + void pointer_axis_relative_direction(uint32_t axis, uint32_t direction) override; private slots: void handleFocusDestroyed() { invalidateFocus(); } @@ -347,6 +348,8 @@ public: QPointF delta; QPoint delta120; axis_source axisSource = axis_source_wheel; + bool verticalAxisInverted = false; + bool horizontalAxisInverted = false; void resetScrollData(); bool hasPixelDelta() const; @@ -420,7 +423,7 @@ public: ulong timestamp, const QPointF &local, const QPointF &global, const QPoint &pixelDelta, const QPoint &angleDelta, Qt::MouseEventSource source, - Qt::KeyboardModifiers modifiers) + Qt::KeyboardModifiers modifiers, bool inverted) : type(type) , phase(phase) , timestamp(timestamp) @@ -431,6 +434,7 @@ public: , angleDelta(angleDelta) , source(source) , surface(surface) + , inverted(inverted) {} QEvent::Type type = QEvent::None; @@ -445,6 +449,7 @@ public: QPoint angleDelta; Qt::MouseEventSource source = Qt::MouseEventNotSynthesized; QPointer<QWaylandWindow> surface; + bool inverted = false; }; #ifndef QT_NO_GESTURES diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 15044d660..4841ba95b 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -1161,7 +1161,7 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylan case QEvent::Wheel: QWindowSystemInterface::handleWheelEvent(window(), e.timestamp, e.local, e.global, e.pixelDelta, e.angleDelta, e.modifiers, - e.phase, e.source, false); + e.phase, e.source, e.inverted); break; default: Q_UNREACHABLE(); @@ -1352,7 +1352,7 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe QWindowSystemInterface::handleWheelEvent(window(), e.timestamp, localTranslated, globalTranslated, e.pixelDelta, e.angleDelta, e.modifiers, - e.phase, e.source, false); + e.phase, e.source, e.inverted); break; } default: |