summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Edmundson <davidedmundson@kde.org>2023-01-18 13:44:46 +0000
committerVlad Zahorodnii <vlad.zahorodnii@kde.org>2023-11-06 13:30:49 +0200
commitcf7fb478f5b57ac71181d7450045538de6e24176 (patch)
tree6edb81e395205fa763dc01920a2723a2ceb7e0d3 /src
parent2eff0cfa25d60091c36b78490591bf9509bcc624 (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.cpp36
-rw-r--r--src/client/qwaylandinputdevice_p.h7
-rw-r--r--src/client/qwaylandwindow.cpp4
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: