summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorVlad Zahorodnii <vlad.zahorodnii@kde.org>2022-10-24 22:13:33 +0300
committerVlad Zahorodnii <vlad.zahorodnii@kde.org>2022-10-26 22:34:20 +0300
commitf1e71327d462d2dae0b46677bbc478afb0d1b2f7 (patch)
tree0e5e8c08dd8e71d94cc5aeaa1b27bdd8c67eeda7 /tests
parent763b3dba2c0e62926072a40373aa7685a6264b7b (diff)
downloadqtwayland-f1e71327d462d2dae0b46677bbc478afb0d1b2f7.tar.gz
Client: Add support for high-resolution scrolling
With wl_pointer version 8, the axis_discrete event is replaced with the axis_value120 event. The main difference between axis_discrete and axis_value120 is that the latter carries scroll deltas that can be fractions of 120, e.g. 30, etc. See also https://gitlab.freedesktop.org/wayland/wayland/-/merge_requests/72 Change-Id: I4f724ead7ba146dde6d8975fa4edfcfca761769d Reviewed-by: David Edmundson <davidedmundson@kde.org> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/client/CMakeLists.txt1
-rw-r--r--tests/auto/client/seat/tst_seat.cpp52
-rw-r--r--tests/auto/client/seatv7/CMakeLists.txt13
-rw-r--r--tests/auto/client/seatv7/tst_seatv7.cpp130
-rw-r--r--tests/auto/client/shared/coreprotocol.cpp7
-rw-r--r--tests/auto/client/shared/coreprotocol.h3
6 files changed, 182 insertions, 24 deletions
diff --git a/tests/auto/client/CMakeLists.txt b/tests/auto/client/CMakeLists.txt
index dd5c6e5b..749e6b83 100644
--- a/tests/auto/client/CMakeLists.txt
+++ b/tests/auto/client/CMakeLists.txt
@@ -17,6 +17,7 @@ if (NOT WEBOS)
add_subdirectory(output)
add_subdirectory(primaryselectionv1)
add_subdirectory(seatv4)
+ add_subdirectory(seatv7)
add_subdirectory(seat)
add_subdirectory(surface)
add_subdirectory(tabletv2)
diff --git a/tests/auto/client/seat/tst_seat.cpp b/tests/auto/client/seat/tst_seat.cpp
index 68749486..8a9375d6 100644
--- a/tests/auto/client/seat/tst_seat.cpp
+++ b/tests/auto/client/seat/tst_seat.cpp
@@ -18,7 +18,7 @@ public:
removeAll<Seat>();
uint capabilities = MockCompositor::Seat::capability_pointer | MockCompositor::Seat::capability_touch;
- int version = 7;
+ int version = 8;
add<Seat>(capabilities, version);
});
}
@@ -40,8 +40,7 @@ private slots:
void fingerScroll();
void fingerScrollSlow();
void continuousScroll();
- void wheelDiscreteScroll_data();
- void wheelDiscreteScroll();
+ void highResolutionScroll();
// Touch tests
void createsTouch();
@@ -56,13 +55,13 @@ private slots:
void tst_seat::bindsToSeat()
{
QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().size(), 1);
- QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().first()->version(), 7);
+ QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().first()->version(), 8);
}
void tst_seat::createsPointer()
{
QCOMPOSITOR_TRY_COMPARE(pointer()->resourceMap().size(), 1);
- QCOMPOSITOR_TRY_COMPARE(pointer()->resourceMap().first()->version(), 7);
+ QCOMPOSITOR_TRY_COMPARE(pointer()->resourceMap().first()->version(), 8);
}
void tst_seat::setsCursorOnEnter()
@@ -320,28 +319,38 @@ void tst_seat::fingerScrollSlow()
QCOMPARE(accumulated.y(), -1);
}
-void tst_seat::wheelDiscreteScroll_data()
-{
- QTest::addColumn<uint>("source");
- QTest::newRow("wheel") << uint(Pointer::axis_source_wheel);
- QTest::newRow("wheel tilt") << uint(Pointer::axis_source_wheel_tilt);
-}
-
-void tst_seat::wheelDiscreteScroll()
+void tst_seat::highResolutionScroll()
{
WheelWindow window;
QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
- QFETCH(uint, source);
-
exec([=] {
auto *p = pointer();
auto *c = client();
p->sendEnter(xdgToplevel()->surface(), {32, 32});
p->sendFrame(c);
- p->sendAxisSource(c, Pointer::axis_source(source));
- p->sendAxisDiscrete(c, Pointer::axis_vertical_scroll, 1); // 1 click downwards
- p->sendAxis(c, Pointer::axis_vertical_scroll, 1.0);
+ p->sendAxisSource(c, Pointer::axis_source_wheel);
+ p->sendAxisValue120(c, Pointer::axis_vertical_scroll, 30); // quarter of a click
+ p->sendAxis(c, Pointer::axis_vertical_scroll, 3.75);
+ p->sendFrame(c);
+ });
+
+ QTRY_VERIFY(!window.m_events.empty());
+ {
+ auto e = window.m_events.takeFirst();
+ QCOMPARE(e.phase, Qt::NoScrollPhase);
+ QVERIFY(qAbs(e.angleDelta.x()) <= qAbs(e.angleDelta.y())); // Vertical scroll
+ QCOMPARE(e.angleDelta, QPoint(0, -30));
+ // Click scrolls are not continuous and should not have a pixel delta
+ QCOMPARE(e.pixelDelta, QPoint(0, 0));
+ }
+
+ exec([=] {
+ auto *p = pointer();
+ auto *c = client();
+ p->sendAxisSource(c, Pointer::axis_source_wheel);
+ p->sendAxisValue120(c, Pointer::axis_vertical_scroll, 90); // complete the click
+ p->sendAxis(c, Pointer::axis_vertical_scroll, 11.25);
p->sendFrame(c);
});
@@ -350,10 +359,7 @@ void tst_seat::wheelDiscreteScroll()
auto e = window.m_events.takeFirst();
QCOMPARE(e.phase, Qt::NoScrollPhase);
QVERIFY(qAbs(e.angleDelta.x()) <= qAbs(e.angleDelta.y())); // Vertical scroll
- // According to the docs the angle delta is in eights of a degree and most mice have
- // 1 click = 15 degrees. The angle delta should therefore be:
- // 15 degrees / (1/8 eights per degrees) = 120 eights of degrees.
- QCOMPARE(e.angleDelta, QPoint(0, -120));
+ QCOMPARE(e.angleDelta, QPoint(0, -90));
// Click scrolls are not continuous and should not have a pixel delta
QCOMPARE(e.pixelDelta, QPoint(0, 0));
}
@@ -388,7 +394,7 @@ void tst_seat::continuousScroll()
void tst_seat::createsTouch()
{
QCOMPOSITOR_TRY_COMPARE(touch()->resourceMap().size(), 1);
- QCOMPOSITOR_TRY_COMPARE(touch()->resourceMap().first()->version(), 7);
+ QCOMPOSITOR_TRY_COMPARE(touch()->resourceMap().first()->version(), 8);
}
class TouchWindow : public QRasterWindow {
diff --git a/tests/auto/client/seatv7/CMakeLists.txt b/tests/auto/client/seatv7/CMakeLists.txt
new file mode 100644
index 00000000..cf3ade8c
--- /dev/null
+++ b/tests/auto/client/seatv7/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_seatv7 Test:
+#####################################################################
+
+qt_internal_add_test(tst_seatv7
+ SOURCES
+ tst_seatv7.cpp
+ LIBRARIES
+ SharedClientTest
+)
diff --git a/tests/auto/client/seatv7/tst_seatv7.cpp b/tests/auto/client/seatv7/tst_seatv7.cpp
new file mode 100644
index 00000000..c341ec96
--- /dev/null
+++ b/tests/auto/client/seatv7/tst_seatv7.cpp
@@ -0,0 +1,130 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "mockcompositor.h"
+#include <QtOpenGL/QOpenGLWindow>
+#include <QtGui/QRasterWindow>
+#include <QtGui/QEventPoint>
+
+using namespace MockCompositor;
+
+class SeatCompositor : public DefaultCompositor {
+public:
+ explicit SeatCompositor()
+ {
+ exec([this] {
+ m_config.autoConfigure = true;
+
+ removeAll<Seat>();
+
+ uint capabilities = MockCompositor::Seat::capability_pointer | MockCompositor::Seat::capability_touch;
+ int version = 7;
+ add<Seat>(capabilities, version);
+ });
+ }
+};
+
+class tst_seatv7 : public QObject, private SeatCompositor
+{
+ Q_OBJECT
+private slots:
+ void cleanup() { QTRY_VERIFY2(isClean(), qPrintable(dirtyMessage())); }
+ void bindsToSeat();
+
+ // Pointer tests
+ void wheelDiscreteScroll_data();
+ void wheelDiscreteScroll();
+};
+
+void tst_seatv7::bindsToSeat()
+{
+ QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().size(), 1);
+ QCOMPOSITOR_COMPARE(get<Seat>()->resourceMap().first()->version(), 7);
+}
+
+class WheelWindow : QRasterWindow {
+public:
+ WheelWindow()
+ {
+ resize(64, 64);
+ show();
+ }
+ void wheelEvent(QWheelEvent *event) override
+ {
+ QRasterWindow::wheelEvent(event);
+// qDebug() << event << "angleDelta" << event->angleDelta() << "pixelDelta" << event->pixelDelta();
+
+ if (event->phase() != Qt::ScrollUpdate && event->phase() != Qt::NoScrollPhase) {
+ // Shouldn't have deltas in the these phases
+ QCOMPARE(event->angleDelta(), QPoint(0, 0));
+ 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);
+
+ m_events.append(Event{event});
+ }
+ struct Event // Because I didn't find a convenient way to copy it entirely
+ {
+ explicit Event() = default;
+ explicit Event(const QWheelEvent *event)
+ : phase(event->phase())
+ , pixelDelta(event->pixelDelta())
+ , angleDelta(event->angleDelta())
+ , source(event->source())
+ {
+ }
+ Qt::ScrollPhase phase{};
+ QPoint pixelDelta;
+ QPoint angleDelta; // eights of a degree, positive is upwards, left
+ Qt::MouseEventSource source{};
+ };
+ QList<Event> m_events;
+};
+
+void tst_seatv7::wheelDiscreteScroll_data()
+{
+ QTest::addColumn<uint>("source");
+ QTest::newRow("wheel") << uint(Pointer::axis_source_wheel);
+ QTest::newRow("wheel tilt") << uint(Pointer::axis_source_wheel_tilt);
+}
+
+void tst_seatv7::wheelDiscreteScroll()
+{
+ WheelWindow window;
+ QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
+
+ QFETCH(uint, source);
+
+ exec([=] {
+ auto *p = pointer();
+ auto *c = client();
+ p->sendEnter(xdgToplevel()->surface(), {32, 32});
+ p->sendFrame(c);
+ p->sendAxisSource(c, Pointer::axis_source(source));
+ p->sendAxisDiscrete(c, Pointer::axis_vertical_scroll, 1); // 1 click downwards
+ p->sendAxis(c, Pointer::axis_vertical_scroll, 1.0);
+ p->sendFrame(c);
+ });
+
+ QTRY_VERIFY(!window.m_events.empty());
+ {
+ auto e = window.m_events.takeFirst();
+ QCOMPARE(e.phase, Qt::NoScrollPhase);
+ QVERIFY(qAbs(e.angleDelta.x()) <= qAbs(e.angleDelta.y())); // Vertical scroll
+ // According to the docs the angle delta is in eights of a degree and most mice have
+ // 1 click = 15 degrees. The angle delta should therefore be:
+ // 15 degrees / (1/8 eights per degrees) = 120 eights of degrees.
+ QCOMPARE(e.angleDelta, QPoint(0, -120));
+ // Click scrolls are not continuous and should not have a pixel delta
+ QCOMPARE(e.pixelDelta, QPoint(0, 0));
+ }
+}
+
+QCOMPOSITOR_TEST_MAIN(tst_seatv7)
+#include "tst_seatv7.moc"
diff --git a/tests/auto/client/shared/coreprotocol.cpp b/tests/auto/client/shared/coreprotocol.cpp
index 005151f7..4f3d21d8 100644
--- a/tests/auto/client/shared/coreprotocol.cpp
+++ b/tests/auto/client/shared/coreprotocol.cpp
@@ -423,6 +423,13 @@ void Pointer::sendFrame(wl_client *client)
send_frame(r->handle);
}
+void Pointer::sendAxisValue120(wl_client *client, QtWaylandServer::wl_pointer::axis axis, int value120)
+{
+ const auto pointerResources = resourceMap().values(client);
+ for (auto *r : pointerResources)
+ send_axis_value120(r->handle, axis, value120);
+}
+
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 370b8cd8..74f07afb 100644
--- a/tests/auto/client/shared/coreprotocol.h
+++ b/tests/auto/client/shared/coreprotocol.h
@@ -296,7 +296,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 = 7);
+ explicit Seat(CoreCompositor *compositor, uint capabilities = Seat::capability_pointer | Seat::capability_keyboard | Seat::capability_touch, int version = 8);
~Seat() override;
void send_capabilities(Resource *resource, uint capabilities) = delete; // Use wrapper instead
void send_capabilities(uint capabilities) = delete; // Use wrapper instead
@@ -346,6 +346,7 @@ public:
void sendAxisSource(wl_client *client, axis_source source);
void sendAxisStop(wl_client *client, axis axis);
void sendFrame(wl_client *client);
+ void sendAxisValue120(wl_client *client, axis axis, int value120);
Seat *m_seat = nullptr;
QList<uint> m_enterSerials;