diff options
-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 | ||||
-rw-r--r-- | tests/auto/client/seat/tst_seat.cpp | 39 | ||||
-rw-r--r-- | tests/auto/client/shared/coreprotocol.cpp | 7 | ||||
-rw-r--r-- | tests/auto/client/shared/coreprotocol.h | 3 |
6 files changed, 72 insertions, 24 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: diff --git a/tests/auto/client/seat/tst_seat.cpp b/tests/auto/client/seat/tst_seat.cpp index 34409c2ca..d3bc1eda3 100644 --- a/tests/auto/client/seat/tst_seat.cpp +++ b/tests/auto/client/seat/tst_seat.cpp @@ -17,7 +17,7 @@ public: removeAll<Seat>(); uint capabilities = MockCompositor::Seat::capability_pointer | MockCompositor::Seat::capability_touch; - int version = 8; + int version = 9; add<Seat>(capabilities, version); }); } @@ -54,13 +54,13 @@ private slots: void tst_seat::bindsToSeat() { QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().size(), 1); - QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().first()->version(), 8); + QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().first()->version(), 9); } void tst_seat::createsPointer() { QCOMPOSITOR_TRY_COMPARE(pointer()->resourceMap().size(), 1); - QCOMPOSITOR_TRY_COMPARE(pointer()->resourceMap().first()->version(), 8); + QCOMPOSITOR_TRY_COMPARE(pointer()->resourceMap().first()->version(), 9); } void tst_seat::setsCursorOnEnter() @@ -114,10 +114,6 @@ public: QCOMPARE(event->pixelDelta(), QPoint(0, 0)); } - // The axis vector of the event is already in surface space, so there is now way to tell - // whether it is inverted or not. - QCOMPARE(event->inverted(), false); - // We didn't press any buttons QCOMPARE(event->buttons(), Qt::NoButton); @@ -131,12 +127,14 @@ public: , pixelDelta(event->pixelDelta()) , angleDelta(event->angleDelta()) , source(event->source()) + , inverted(event->inverted()) { } Qt::ScrollPhase phase{}; QPoint pixelDelta; QPoint angleDelta; // eights of a degree, positive is upwards, left Qt::MouseEventSource source{}; + bool inverted = false; }; QList<Event> m_events; }; @@ -146,13 +144,21 @@ void tst_seat::simpleAxis_data() QTest::addColumn<uint>("axis"); QTest::addColumn<qreal>("value"); QTest::addColumn<QPoint>("angleDelta"); + QTest::addColumn<bool>("inverted"); // Directions in regular windows/linux terms (no "natural" scrolling) - QTest::newRow("down") << uint(Pointer::axis_vertical_scroll) << 1.0 << QPoint{0, -12}; - QTest::newRow("up") << uint(Pointer::axis_vertical_scroll) << -1.0 << QPoint{0, 12}; - QTest::newRow("left") << uint(Pointer::axis_horizontal_scroll) << 1.0 << QPoint{-12, 0}; - QTest::newRow("right") << uint(Pointer::axis_horizontal_scroll) << -1.0 << QPoint{12, 0}; - QTest::newRow("up big") << uint(Pointer::axis_vertical_scroll) << -10.0 << QPoint{0, 120}; + QTest::newRow("down") << uint(Pointer::axis_vertical_scroll) << 1.0 << QPoint{0, -12} << false; + QTest::newRow("up") << uint(Pointer::axis_vertical_scroll) << -1.0 << QPoint{0, 12} << false; + QTest::newRow("left") << uint(Pointer::axis_horizontal_scroll) << 1.0 << QPoint{-12, 0} << false; + QTest::newRow("right") << uint(Pointer::axis_horizontal_scroll) << -1.0 << QPoint{12, 0} << false; + QTest::newRow("up big") << uint(Pointer::axis_vertical_scroll) << -10.0 << QPoint{0, 120} << false; + + // (natural) scrolling + QTest::newRow("down inverted") << uint(Pointer::axis_vertical_scroll) << 1.0 << QPoint{0, -12} << true; + QTest::newRow("up inverted") << uint(Pointer::axis_vertical_scroll) << -1.0 << QPoint{0, 12} << true; + QTest::newRow("left inverted") << uint(Pointer::axis_horizontal_scroll) << 1.0 << QPoint{-12, 0} << true; + QTest::newRow("right inverted") << uint(Pointer::axis_horizontal_scroll) << -1.0 << QPoint{12, 0} << true; + QTest::newRow("up big inverted") << uint(Pointer::axis_vertical_scroll) << -10.0 << QPoint{0, 120} << true; } void tst_seat::simpleAxis() @@ -160,6 +166,7 @@ void tst_seat::simpleAxis() QFETCH(uint, axis); QFETCH(qreal, value); QFETCH(QPoint, angleDelta); + QFETCH(bool, inverted); WheelWindow window; QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); @@ -173,6 +180,8 @@ void tst_seat::simpleAxis() Pointer::axis(axis), value // Length of vector in surface-local space. i.e. positive is downwards ); + auto direction = inverted ? Pointer::axis_relative_direction_inverted : Pointer::axis_relative_direction_identical; + p->sendAxisRelativeDirection(client(), Pointer::axis(axis), direction); p->sendFrame(client()); }); @@ -186,6 +195,8 @@ void tst_seat::simpleAxis() // Documentation says not synthesized is appropriate in such cases QCOMPARE(e.source, Qt::MouseEventNotSynthesized); QCOMPARE(e.angleDelta, angleDelta); + + QCOMPARE(e.inverted, inverted); } // Sending axis_stop is not mandatory when axis source != finger @@ -386,6 +397,8 @@ void tst_seat::continuousScroll() QCOMPARE(e.phase, Qt::NoScrollPhase); QCOMPARE(e.pixelDelta, QPoint(5, -10)); QCOMPARE(e.source, Qt::MouseEventSynthesizedBySystem); // touchpads are not wheels + QCOMPARE(e.inverted, false); + } // Sending axis_stop is not mandatory when axis source != finger } @@ -393,7 +406,7 @@ void tst_seat::continuousScroll() void tst_seat::createsTouch() { QCOMPOSITOR_TRY_COMPARE(touch()->resourceMap().size(), 1); - QCOMPOSITOR_TRY_COMPARE(touch()->resourceMap().first()->version(), 8); + QCOMPOSITOR_TRY_COMPARE(touch()->resourceMap().first()->version(), 9); } class TouchWindow : public QRasterWindow { diff --git a/tests/auto/client/shared/coreprotocol.cpp b/tests/auto/client/shared/coreprotocol.cpp index 64586d413..915b0f914 100644 --- a/tests/auto/client/shared/coreprotocol.cpp +++ b/tests/auto/client/shared/coreprotocol.cpp @@ -432,6 +432,13 @@ void Pointer::sendAxisValue120(wl_client *client, QtWaylandServer::wl_pointer::a send_axis_value120(r->handle, axis, value120); } +void Pointer::sendAxisRelativeDirection(wl_client *client, QtWaylandServer::wl_pointer::axis axis, QtWaylandServer::wl_pointer::axis_relative_direction direction) +{ + const auto pointerResources = resourceMap().values(client); + for (auto *r : pointerResources) + send_axis_relative_direction(r->handle, axis, direction); +} + void Pointer::pointer_set_cursor(Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) { Q_UNUSED(resource); diff --git a/tests/auto/client/shared/coreprotocol.h b/tests/auto/client/shared/coreprotocol.h index e41c719e8..20a3f2122 100644 --- a/tests/auto/client/shared/coreprotocol.h +++ b/tests/auto/client/shared/coreprotocol.h @@ -299,7 +299,7 @@ class Seat : public Global, public QtWaylandServer::wl_seat { Q_OBJECT public: - explicit Seat(CoreCompositor *compositor, uint capabilities = Seat::capability_pointer | Seat::capability_keyboard | Seat::capability_touch, int version = 8); + explicit Seat(CoreCompositor *compositor, uint capabilities = Seat::capability_pointer | Seat::capability_keyboard | Seat::capability_touch, int version = 9); ~Seat() override; void send_capabilities(Resource *resource, uint capabilities) = delete; // Use wrapper instead void send_capabilities(uint capabilities) = delete; // Use wrapper instead @@ -350,6 +350,7 @@ public: void sendAxisStop(wl_client *client, axis axis); void sendFrame(wl_client *client); void sendAxisValue120(wl_client *client, axis axis, int value120); + void sendAxisRelativeDirection(wl_client *client, axis axis, axis_relative_direction direction); Seat *m_seat = nullptr; QList<uint> m_enterSerials; |