From 0ed0066d74de2c7e5e9609c394e22a2e03f2dbcc Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 3 Nov 2020 20:44:32 +0200 Subject: [PATCH] Port pointer-constraints-v1 to the new design --- src/wayland/CMakeLists.txt | 7 +- .../client/test_pointer_constraints.cpp | 57 ++- src/wayland/display.cpp | 11 +- src/wayland/display.h | 7 +- src/wayland/pointer_interface.cpp | 4 +- .../pointerconstraints_v1_interface.cpp | 331 ++++++++++++++++++ ...ce.h => pointerconstraints_v1_interface.h} | 168 ++++----- .../pointerconstraints_v1_interface_p.h | 92 +++++ .../server/pointerconstraints_interface.cpp | 197 ----------- .../server/pointerconstraints_interface_p.h | 123 ------- .../pointerconstraints_interface_v1.cpp | 269 -------------- src/wayland/surface_interface.cpp | 68 ++-- src/wayland/surface_interface.h | 8 +- src/wayland/surface_interface_p.h | 8 +- 14 files changed, 566 insertions(+), 784 deletions(-) create mode 100644 src/wayland/pointerconstraints_v1_interface.cpp rename src/wayland/{server/pointerconstraints_interface.h => pointerconstraints_v1_interface.h} (65%) create mode 100644 src/wayland/pointerconstraints_v1_interface_p.h delete mode 100644 src/wayland/server/pointerconstraints_interface.cpp delete mode 100644 src/wayland/server/pointerconstraints_interface_p.h delete mode 100644 src/wayland/server/pointerconstraints_interface_v1.cpp diff --git a/src/wayland/CMakeLists.txt b/src/wayland/CMakeLists.txt index 9a9f31a2db..193d2b8591 100644 --- a/src/wayland/CMakeLists.txt +++ b/src/wayland/CMakeLists.txt @@ -37,8 +37,7 @@ set(SERVER_LIB_SRCS plasmavirtualdesktop_interface.cpp plasmawindowmanagement_interface.cpp pointer_interface.cpp - pointerconstraints_interface.cpp - pointerconstraints_interface_v1.cpp + pointerconstraints_v1_interface.cpp pointergestures_v1_interface.cpp primaryselectiondevice_v1_interface.cpp primaryselectiondevicemanager_v1_interface.cpp @@ -175,7 +174,7 @@ ecm_add_qtwayland_server_protocol(SERVER_LIB_SRCS BASENAME pointer-gestures-unstable-v1 ) -ecm_add_wayland_server_protocol(SERVER_LIB_SRCS +ecm_add_qtwayland_server_protocol(SERVER_LIB_SRCS PROTOCOL ${WaylandProtocols_DATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml BASENAME pointer-constraints-unstable-v1 ) @@ -409,7 +408,7 @@ set(SERVER_LIB_HEADERS plasmavirtualdesktop_interface.h plasmawindowmanagement_interface.h pointer_interface.h - pointerconstraints_interface.h + pointerconstraints_v1_interface.h pointergestures_v1_interface.h primaryselectiondevicemanager_v1_interface.h region_interface.h diff --git a/src/wayland/autotests/client/test_pointer_constraints.cpp b/src/wayland/autotests/client/test_pointer_constraints.cpp index 65021c3b0a..a11c34c193 100644 --- a/src/wayland/autotests/client/test_pointer_constraints.cpp +++ b/src/wayland/autotests/client/test_pointer_constraints.cpp @@ -17,7 +17,7 @@ // server #include "../../src/server/display.h" #include "../../src/server/compositor_interface.h" -#include "../../src/server/pointerconstraints_interface.h" +#include "../../src/server/pointerconstraints_v1_interface.h" #include "../../src/server/seat_interface.h" #include "../../src/server/surface_interface.h" @@ -25,8 +25,8 @@ using namespace KWayland::Client; using namespace KWaylandServer; Q_DECLARE_METATYPE(KWayland::Client::PointerConstraints::LifeTime) -Q_DECLARE_METATYPE(KWaylandServer::ConfinedPointerInterface::LifeTime) -Q_DECLARE_METATYPE(KWaylandServer::LockedPointerInterface::LifeTime) +Q_DECLARE_METATYPE(KWaylandServer::ConfinedPointerV1Interface::LifeTime) +Q_DECLARE_METATYPE(KWaylandServer::LockedPointerV1Interface::LifeTime) class TestPointerConstraints : public QObject { @@ -47,7 +47,7 @@ private: Display *m_display = nullptr; CompositorInterface *m_compositorInterface = nullptr; SeatInterface *m_seatInterface = nullptr; - PointerConstraintsInterface *m_pointerConstraintsInterface = nullptr; + PointerConstraintsV1Interface *m_pointerConstraintsInterface = nullptr; ConnectionThread *m_connection = nullptr; QThread *m_thread = nullptr; EventQueue *m_queue = nullptr; @@ -71,8 +71,7 @@ void TestPointerConstraints::init() m_seatInterface->setHasPointer(true); m_seatInterface->create(); m_compositorInterface = m_display->createCompositor(m_display); - m_pointerConstraintsInterface = m_display->createPointerConstraints(PointerConstraintsInterfaceVersion::UnstableV1, m_display); - m_pointerConstraintsInterface->create(); + m_pointerConstraintsInterface = m_display->createPointerConstraintsV1(m_display); // setup connection m_connection = new KWayland::Client::ConnectionThread; @@ -153,12 +152,12 @@ void TestPointerConstraints::cleanup() void TestPointerConstraints::testLockPointer_data() { QTest::addColumn("clientLifeTime"); - QTest::addColumn("serverLifeTime"); + QTest::addColumn("serverLifeTime"); QTest::addColumn("hasConstraintAfterUnlock"); QTest::addColumn("pointerChangedCount"); - QTest::newRow("persistent") << PointerConstraints::LifeTime::Persistent << LockedPointerInterface::LifeTime::Persistent << true << 1; - QTest::newRow("oneshot") << PointerConstraints::LifeTime::OneShot << LockedPointerInterface::LifeTime::OneShot << false << 2; + QTest::newRow("persistent") << PointerConstraints::LifeTime::Persistent << LockedPointerV1Interface::LifeTime::Persistent << true << 1; + QTest::newRow("oneshot") << PointerConstraints::LifeTime::OneShot << LockedPointerV1Interface::LifeTime::OneShot << false << 2; } void TestPointerConstraints::testLockPointer() @@ -173,8 +172,8 @@ void TestPointerConstraints::testLockPointer() auto serverSurface = surfaceCreatedSpy.first().first().value(); QVERIFY(serverSurface); - QVERIFY(serverSurface->lockedPointer().isNull()); - QVERIFY(serverSurface->confinedPointer().isNull()); + QVERIFY(!serverSurface->lockedPointer()); + QVERIFY(!serverSurface->confinedPointer()); // now create the locked pointer QSignalSpy pointerConstraintsChangedSpy(serverSurface, &SurfaceInterface::pointerConstraintsChanged); @@ -190,20 +189,20 @@ void TestPointerConstraints::testLockPointer() auto serverLockedPointer = serverSurface->lockedPointer(); QVERIFY(serverLockedPointer); - QVERIFY(serverSurface->confinedPointer().isNull()); + QVERIFY(!serverSurface->confinedPointer()); QCOMPARE(serverLockedPointer->isLocked(), false); QCOMPARE(serverLockedPointer->region(), QRegion()); - QFETCH(LockedPointerInterface::LifeTime, serverLifeTime); + QFETCH(LockedPointerV1Interface::LifeTime, serverLifeTime); QCOMPARE(serverLockedPointer->lifeTime(), serverLifeTime); // setting to unlocked now should not trigger an unlocked spy serverLockedPointer->setLocked(false); QVERIFY(!unlockedSpy.wait(500)); // try setting a region - QSignalSpy destroyedSpy(serverLockedPointer.data(), &QObject::destroyed); + QSignalSpy destroyedSpy(serverLockedPointer, &QObject::destroyed); QVERIFY(destroyedSpy.isValid()); - QSignalSpy regionChangedSpy(serverLockedPointer.data(), &LockedPointerInterface::regionChanged); + QSignalSpy regionChangedSpy(serverLockedPointer, &LockedPointerV1Interface::regionChanged); QVERIFY(regionChangedSpy.isValid()); lockedPointer->setRegion(m_compositor->createRegion(QRegion(0, 5, 10, 20), m_compositor)); // it's double buffered @@ -218,7 +217,7 @@ void TestPointerConstraints::testLockPointer() QCOMPARE(serverLockedPointer->region(), QRegion()); // let's lock the surface - QSignalSpy lockedChangedSpy(serverLockedPointer.data(), &LockedPointerInterface::lockedChanged); + QSignalSpy lockedChangedSpy(serverLockedPointer, &LockedPointerV1Interface::lockedChanged); QVERIFY(lockedChangedSpy.isValid()); m_seatInterface->setFocusedPointerSurface(serverSurface); QSignalSpy pointerMotionSpy(m_pointer, &Pointer::motion); @@ -236,7 +235,7 @@ void TestPointerConstraints::testLockPointer() QVERIFY(unlockedSpy.isEmpty()); const QPointF hint = QPointF(1.5, 0.5); - QSignalSpy hintChangedSpy(serverLockedPointer.data(), &LockedPointerInterface::cursorPositionHintChanged); + QSignalSpy hintChangedSpy(serverLockedPointer, &LockedPointerV1Interface::cursorPositionHintChanged); lockedPointer->setCursorPositionHint(hint); QCOMPARE(serverLockedPointer->cursorPositionHint(), QPointF(-1., -1.)); surface->commit(Surface::CommitFlag::None); @@ -248,7 +247,7 @@ void TestPointerConstraints::testLockPointer() QCOMPARE(serverLockedPointer->isLocked(), false); QCOMPARE(serverLockedPointer->cursorPositionHint(), QPointF(-1., -1.)); QCOMPARE(lockedChangedSpy.count(), 2); - QTEST(!serverSurface->lockedPointer().isNull(), "hasConstraintAfterUnlock"); + QTEST(bool(serverSurface->lockedPointer()), "hasConstraintAfterUnlock"); QTEST(pointerConstraintsChangedSpy.count(), "pointerChangedCount"); QVERIFY(unlockedSpy.wait()); QCOMPARE(unlockedSpy.count(), 1); @@ -267,12 +266,12 @@ void TestPointerConstraints::testLockPointer() void TestPointerConstraints::testConfinePointer_data() { QTest::addColumn("clientLifeTime"); - QTest::addColumn("serverLifeTime"); + QTest::addColumn("serverLifeTime"); QTest::addColumn("hasConstraintAfterUnlock"); QTest::addColumn("pointerChangedCount"); - QTest::newRow("persistent") << PointerConstraints::LifeTime::Persistent << ConfinedPointerInterface::LifeTime::Persistent << true << 1; - QTest::newRow("oneshot") << PointerConstraints::LifeTime::OneShot << ConfinedPointerInterface::LifeTime::OneShot << false << 2; + QTest::newRow("persistent") << PointerConstraints::LifeTime::Persistent << ConfinedPointerV1Interface::LifeTime::Persistent << true << 1; + QTest::newRow("oneshot") << PointerConstraints::LifeTime::OneShot << ConfinedPointerV1Interface::LifeTime::OneShot << false << 2; } void TestPointerConstraints::testConfinePointer() @@ -287,8 +286,8 @@ void TestPointerConstraints::testConfinePointer() auto serverSurface = surfaceCreatedSpy.first().first().value(); QVERIFY(serverSurface); - QVERIFY(serverSurface->lockedPointer().isNull()); - QVERIFY(serverSurface->confinedPointer().isNull()); + QVERIFY(!serverSurface->lockedPointer()); + QVERIFY(!serverSurface->confinedPointer()); // now create the confined pointer QSignalSpy pointerConstraintsChangedSpy(serverSurface, &SurfaceInterface::pointerConstraintsChanged); @@ -304,20 +303,20 @@ void TestPointerConstraints::testConfinePointer() auto serverConfinedPointer = serverSurface->confinedPointer(); QVERIFY(serverConfinedPointer); - QVERIFY(serverSurface->lockedPointer().isNull()); + QVERIFY(!serverSurface->lockedPointer()); QCOMPARE(serverConfinedPointer->isConfined(), false); QCOMPARE(serverConfinedPointer->region(), QRegion()); - QFETCH(ConfinedPointerInterface::LifeTime, serverLifeTime); + QFETCH(ConfinedPointerV1Interface::LifeTime, serverLifeTime); QCOMPARE(serverConfinedPointer->lifeTime(), serverLifeTime); // setting to unconfined now should not trigger an unconfined spy serverConfinedPointer->setConfined(false); QVERIFY(!unconfinedSpy.wait(500)); // try setting a region - QSignalSpy destroyedSpy(serverConfinedPointer.data(), &QObject::destroyed); + QSignalSpy destroyedSpy(serverConfinedPointer, &QObject::destroyed); QVERIFY(destroyedSpy.isValid()); - QSignalSpy regionChangedSpy(serverConfinedPointer.data(), &ConfinedPointerInterface::regionChanged); + QSignalSpy regionChangedSpy(serverConfinedPointer, &ConfinedPointerV1Interface::regionChanged); QVERIFY(regionChangedSpy.isValid()); confinedPointer->setRegion(m_compositor->createRegion(QRegion(0, 5, 10, 20), m_compositor)); // it's double buffered @@ -332,7 +331,7 @@ void TestPointerConstraints::testConfinePointer() QCOMPARE(serverConfinedPointer->region(), QRegion()); // let's confine the surface - QSignalSpy confinedChangedSpy(serverConfinedPointer.data(), &ConfinedPointerInterface::confinedChanged); + QSignalSpy confinedChangedSpy(serverConfinedPointer, &ConfinedPointerV1Interface::confinedChanged); QVERIFY(confinedChangedSpy.isValid()); m_seatInterface->setFocusedPointerSurface(serverSurface); serverConfinedPointer->setConfined(true); @@ -346,7 +345,7 @@ void TestPointerConstraints::testConfinePointer() serverConfinedPointer->setConfined(false); QCOMPARE(serverConfinedPointer->isConfined(), false); QCOMPARE(confinedChangedSpy.count(), 2); - QTEST(!serverSurface->confinedPointer().isNull(), "hasConstraintAfterUnlock"); + QTEST(bool(serverSurface->confinedPointer()), "hasConstraintAfterUnlock"); QTEST(pointerConstraintsChangedSpy.count(), "pointerChangedCount"); QVERIFY(unconfinedSpy.wait()); QCOMPARE(unconfinedSpy.count(), 1); diff --git a/src/wayland/display.cpp b/src/wayland/display.cpp index e14f5d0d77..aaf048706e 100644 --- a/src/wayland/display.cpp +++ b/src/wayland/display.cpp @@ -28,7 +28,7 @@ #include "plasmashell_interface.h" #include "plasmavirtualdesktop_interface.h" #include "plasmawindowmanagement_interface.h" -#include "pointerconstraints_interface_p.h" +#include "pointerconstraints_v1_interface_p.h" #include "pointergestures_v1_interface.h" #include "primaryselectiondevicemanager_v1_interface.h" #include "relativepointer_v1_interface.h" @@ -380,14 +380,9 @@ PointerGesturesV1Interface *Display::createPointerGesturesV1(QObject *parent) return p; } -PointerConstraintsInterface *Display::createPointerConstraints(const PointerConstraintsInterfaceVersion &version, QObject *parent) +PointerConstraintsV1Interface *Display::createPointerConstraintsV1(QObject *parent) { - PointerConstraintsInterface *p = nullptr; - switch (version) { - case PointerConstraintsInterfaceVersion::UnstableV1: - p = new PointerConstraintsUnstableV1Interface(this, parent); - break; - } + PointerConstraintsV1Interface *p = new PointerConstraintsV1Interface(this, parent); connect(this, &Display::aboutToTerminate, p, [p] { delete p; }); return p; } diff --git a/src/wayland/display.h b/src/wayland/display.h index 6d0cd0daec..62ab52c383 100644 --- a/src/wayland/display.h +++ b/src/wayland/display.h @@ -59,8 +59,7 @@ class TextInputManagerV3Interface; class XdgShellInterface; class RelativePointerManagerV1Interface; class PointerGesturesV1Interface; -enum class PointerConstraintsInterfaceVersion; -class PointerConstraintsInterface; +class PointerConstraintsV1Interface; class XdgForeignV2Interface; class AppMenuManagerInterface; class ServerSideDecorationPaletteManagerInterface; @@ -228,12 +227,12 @@ public: PointerGesturesV1Interface *createPointerGesturesV1(QObject *parent = nullptr); /** - * Creates the PointerConstraintsInterface in interface @p version + * Creates the PointerConstraintsV1Interface * * @returns The created manager object * @since 5.29 **/ - PointerConstraintsInterface *createPointerConstraints(const PointerConstraintsInterfaceVersion &version, QObject *parent = nullptr); + PointerConstraintsV1Interface *createPointerConstraintsV1(QObject *parent = nullptr); /** * Creates the XdgForeignV2Interface in interface @p version diff --git a/src/wayland/pointer_interface.cpp b/src/wayland/pointer_interface.cpp index 30b673fb84..4fcb8d9598 100644 --- a/src/wayland/pointer_interface.cpp +++ b/src/wayland/pointer_interface.cpp @@ -5,7 +5,7 @@ */ #include "pointer_interface.h" #include "pointer_interface_p.h" -#include "pointerconstraints_interface.h" +#include "pointerconstraints_v1_interface.h" #include "pointergestures_v1_interface_p.h" #include "resource_p.h" #include "relativepointer_v1_interface_p.h" @@ -220,7 +220,7 @@ PointerInterface::PointerInterface(SeatInterface *parent, wl_resource *parentRes return; } } - if (!d->focusedSurface->lockedPointer().isNull() && d->focusedSurface->lockedPointer()->isLocked()) { + if (d->focusedSurface->lockedPointer() && d->focusedSurface->lockedPointer()->isLocked()) { return; } const QPointF pos = d->seat->focusedPointerSurfaceTransformation().map(d->seat->pointerPos()); diff --git a/src/wayland/pointerconstraints_v1_interface.cpp b/src/wayland/pointerconstraints_v1_interface.cpp new file mode 100644 index 0000000000..3a4fec0e0c --- /dev/null +++ b/src/wayland/pointerconstraints_v1_interface.cpp @@ -0,0 +1,331 @@ +/* + SPDX-FileCopyrightText: 2016 Martin Gräßlin + SPDX-FileCopyrightText: 2020 Vlad Zahorodnii + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#include "pointerconstraints_v1_interface.h" +#include "display.h" +#include "pointer_interface.h" +#include "pointerconstraints_v1_interface_p.h" +#include "region_interface.h" +#include "surface_interface_p.h" + +namespace KWaylandServer +{ + +static const int s_version = 1; + +PointerConstraintsV1InterfacePrivate::PointerConstraintsV1InterfacePrivate(Display *display) + : QtWaylandServer::zwp_pointer_constraints_v1(*display, s_version) +{ +} + +static QRegion regionFromResource(::wl_resource *resource) +{ + const RegionInterface *region = RegionInterface::get(resource); + return region ? region->region() : QRegion(); +} + +void PointerConstraintsV1InterfacePrivate::zwp_pointer_constraints_v1_lock_pointer(Resource *resource, + uint32_t id, + ::wl_resource *surface_resource, + ::wl_resource *pointer_resource, + ::wl_resource *region_resource, + uint32_t lifetime) +{ + PointerInterface *pointer = PointerInterface::get(pointer_resource); + if (!pointer) { + wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, + "invalid pointer"); + return; + } + + SurfaceInterface *surface = SurfaceInterface::get(surface_resource); + if (!surface) { + wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, + "invalid surface"); + return; + } + + if (surface->lockedPointer() || surface->confinedPointer()) { + wl_resource_post_error(resource->handle, error_already_constrained, + "the surface is already constrained"); + return; + } + + if (lifetime != lifetime_oneshot && lifetime != lifetime_persistent) { + wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, + "unknown lifetime %d", lifetime); + return; + } + + wl_resource *lockedPointerResource = wl_resource_create(resource->client(), + &zwp_locked_pointer_v1_interface, + resource->version(), id); + if (!lockedPointerResource) { + wl_resource_post_no_memory(resource->handle); + return; + } + + auto lockedPointer = new LockedPointerV1Interface(LockedPointerV1Interface::LifeTime(lifetime), + regionFromResource(region_resource), + lockedPointerResource); + + SurfaceInterfacePrivate::get(surface)->installPointerConstraint(lockedPointer); +} + +void PointerConstraintsV1InterfacePrivate::zwp_pointer_constraints_v1_confine_pointer(Resource *resource, + uint32_t id, + ::wl_resource *surface_resource, + ::wl_resource *pointer_resource, + ::wl_resource *region_resource, + uint32_t lifetime) +{ + PointerInterface *pointer = PointerInterface::get(pointer_resource); + if (!pointer) { + wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, + "invalid pointer"); + return; + } + + SurfaceInterface *surface = SurfaceInterface::get(surface_resource); + if (!surface) { + wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, + "invalid surface"); + return; + } + + if (lifetime != lifetime_oneshot && lifetime != lifetime_persistent) { + wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, + "unknown lifetime %d", lifetime); + return; + } + + if (surface->lockedPointer() || surface->confinedPointer()) { + wl_resource_post_error(resource->handle, error_already_constrained, + "the surface is already constrained"); + return; + } + + wl_resource *confinedPointerResource = wl_resource_create(resource->client(), + &zwp_confined_pointer_v1_interface, + resource->version(), id); + if (!confinedPointerResource) { + wl_resource_post_no_memory(resource->handle); + return; + } + + auto confinedPointer = new ConfinedPointerV1Interface(ConfinedPointerV1Interface::LifeTime(lifetime), + regionFromResource(region_resource), + confinedPointerResource); + + SurfaceInterfacePrivate::get(surface)->installPointerConstraint(confinedPointer); +} + +void PointerConstraintsV1InterfacePrivate::zwp_pointer_constraints_v1_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +PointerConstraintsV1Interface::PointerConstraintsV1Interface(Display *display, QObject *parent) + : QObject(parent) + , d(new PointerConstraintsV1InterfacePrivate(display)) +{ +} + +PointerConstraintsV1Interface::~PointerConstraintsV1Interface() +{ +} + +LockedPointerV1InterfacePrivate *LockedPointerV1InterfacePrivate::get(LockedPointerV1Interface *q) +{ + return q->d.data(); +} + +LockedPointerV1InterfacePrivate::LockedPointerV1InterfacePrivate(LockedPointerV1Interface *q, + LockedPointerV1Interface::LifeTime lifeTime, + const QRegion ®ion, + ::wl_resource *resource) + : QtWaylandServer::zwp_locked_pointer_v1(resource) + , q(q) + , lifeTime(lifeTime) + , region(region) +{ +} + +void LockedPointerV1InterfacePrivate::commit() +{ + if (hasPendingRegion) { + region = pendingRegion; + hasPendingRegion = false; + emit q->regionChanged(); + } + if (hasPendingHint) { + hint = pendingHint; + hasPendingHint = false; + emit q->cursorPositionHintChanged(); + } +} + +void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_destroy_resource(Resource *resource) +{ + Q_UNUSED(resource) + emit q->aboutToBeDestroyed(); + delete q; +} + +void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_set_cursor_position_hint(Resource *resource, + wl_fixed_t surface_x, + wl_fixed_t surface_y) +{ + Q_UNUSED(resource) + pendingHint = QPointF(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)); + hasPendingHint = true; +} + +void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_set_region(Resource *resource, + ::wl_resource *region_resource) +{ + Q_UNUSED(resource) + pendingRegion = regionFromResource(region_resource); + hasPendingRegion = true; +} + +LockedPointerV1Interface::LockedPointerV1Interface(LifeTime lifeTime, const QRegion ®ion, + ::wl_resource *resource) + : d(new LockedPointerV1InterfacePrivate(this, lifeTime, region, resource)) +{ +} + +LockedPointerV1Interface::~LockedPointerV1Interface() +{ +} + +LockedPointerV1Interface::LifeTime LockedPointerV1Interface::lifeTime() const +{ + return d->lifeTime; +} + +QRegion LockedPointerV1Interface::region() const +{ + return d->region; +} + +QPointF LockedPointerV1Interface::cursorPositionHint() const +{ + return d->hint; +} + +bool LockedPointerV1Interface::isLocked() const +{ + return d->isLocked; +} + +void LockedPointerV1Interface::setLocked(bool locked) +{ + if (d->isLocked == locked) { + return; + } + if (!locked) { + d->hint = QPointF(-1, -1); + } + d->isLocked = locked; + if (d->isLocked) { + d->send_locked(); + } else { + d->send_unlocked(); + } + emit lockedChanged(); +} + +ConfinedPointerV1InterfacePrivate *ConfinedPointerV1InterfacePrivate::get(ConfinedPointerV1Interface *q) +{ + return q->d.data(); +} + +ConfinedPointerV1InterfacePrivate::ConfinedPointerV1InterfacePrivate(ConfinedPointerV1Interface *q, + ConfinedPointerV1Interface::LifeTime lifeTime, + const QRegion ®ion, + ::wl_resource *resource) + : QtWaylandServer::zwp_confined_pointer_v1(resource) + , q(q) + , lifeTime(lifeTime) + , region(region) +{ +} + +void ConfinedPointerV1InterfacePrivate::commit() +{ + if (hasPendingRegion) { + region = pendingRegion; + hasPendingRegion = false; + emit q->regionChanged(); + } +} + +void ConfinedPointerV1InterfacePrivate::zwp_confined_pointer_v1_destroy_resource(Resource *resource) +{ + Q_UNUSED(resource) + delete q; +} + +void ConfinedPointerV1InterfacePrivate::zwp_confined_pointer_v1_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void ConfinedPointerV1InterfacePrivate::zwp_confined_pointer_v1_set_region(Resource *resource, + ::wl_resource *region_resource) +{ + Q_UNUSED(resource) + pendingRegion = regionFromResource(region_resource); + hasPendingRegion = true; +} + +ConfinedPointerV1Interface::ConfinedPointerV1Interface(LifeTime lifeTime, const QRegion ®ion, + ::wl_resource *resource) + : d(new ConfinedPointerV1InterfacePrivate(this, lifeTime, region, resource)) +{ +} + +ConfinedPointerV1Interface::~ConfinedPointerV1Interface() +{ +} + +ConfinedPointerV1Interface::LifeTime ConfinedPointerV1Interface::lifeTime() const +{ + return d->lifeTime; +} + +QRegion ConfinedPointerV1Interface::region() const +{ + return d->region; +} + +bool ConfinedPointerV1Interface::isConfined() const +{ + return d->isConfined; +} + +void ConfinedPointerV1Interface::setConfined(bool confined) +{ + if (d->isConfined == confined) { + return; + } + d->isConfined = confined; + if (d->isConfined) { + d->send_confined(); + } else { + d->send_unconfined(); + } + emit confinedChanged(); +} + +} // namespace KWaylandServer diff --git a/src/wayland/server/pointerconstraints_interface.h b/src/wayland/pointerconstraints_v1_interface.h similarity index 65% rename from src/wayland/server/pointerconstraints_interface.h rename to src/wayland/pointerconstraints_v1_interface.h index 5b58b9f8f8..71ed69226a 100644 --- a/src/wayland/server/pointerconstraints_interface.h +++ b/src/wayland/pointerconstraints_v1_interface.h @@ -1,96 +1,72 @@ /* SPDX-FileCopyrightText: 2016 Martin Gräßlin + SPDX-FileCopyrightText: 2020 Vlad Zahorodnii SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL */ -#ifndef KWAYLAND_SERVER_POINTERCONSTRAINTS_INTERFACE_H -#define KWAYLAND_SERVER_POINTERCONSTRAINTS_INTERFACE_H -#include "global.h" -#include "resource.h" +#pragma once #include +#include #include +struct wl_resource; + namespace KWaylandServer { +class ConfinedPointerV1InterfacePrivate; class Display; +class LockedPointerV1InterfacePrivate; +class PointerConstraintsV1InterfacePrivate; class SurfaceInterface; -/** - * Enum describing the interface versions the PointerConstraintsInterface can support. - * - * @since 5.29 - **/ -enum class PointerConstraintsInterfaceVersion { - /** - * zwp_pointer_constraints_v1 - **/ - UnstableV1 -}; - /** * Manager object to create pointer constraints. * - * To create this manager use {@link Display::createPointerConstraints} + * To create this manager use {@link Display::createPointerConstraintsV1} * - * @see ConfinedPointerInterface - * @see LockedPointerInterface - * @see Display::createPointerConstraints - * @since 5.29 - **/ -class KWAYLANDSERVER_EXPORT PointerConstraintsInterface : public Global + * @see ConfinedPointerV1Interface + * @see LockedPointerV1Interface + */ +class KWAYLANDSERVER_EXPORT PointerConstraintsV1Interface : public QObject { Q_OBJECT + public: - virtual ~PointerConstraintsInterface(); - - /** - * @returns The interface version used by this PointerConstraintsInterface - **/ - PointerConstraintsInterfaceVersion interfaceVersion() const; - -protected: - class Private; - explicit PointerConstraintsInterface(Private *d, QObject *parent = nullptr); + explicit PointerConstraintsV1Interface(Display *display, QObject *parent = nullptr); + ~PointerConstraintsV1Interface() override; private: - Private *d_func() const; + QScopedPointer d; }; /** - * The LockedPointerInterface lets the client request to disable movements of + * The LockedPointerV1Interface lets the client request to disable movements of * the virtual pointer (i.e. the cursor), effectively locking the pointer * to a position. * * It is up to the compositor whether the lock gets activated. - * To activate it needs to use {@link LockedPointerInterface::setLocked}. + * To activate it needs to use {@link LockedPointerV1Interface::setLocked}. * The compositor needs to ensure that the SurfaceInterface has pointer focus - * and that the pointer is inside the {@link LockedPointerInterface::region} when + * and that the pointer is inside the {@link LockedPointerV1Interface::region} when * it activates the lock. * * While the lock is active the PointerInterface does no longer emit pointer motion * events, but still emits relative pointer motion events. - * - * @since 5.29 - **/ -class KWAYLANDSERVER_EXPORT LockedPointerInterface : public Resource + */ +class KWAYLANDSERVER_EXPORT LockedPointerV1Interface : public QObject { Q_OBJECT + public: + ~LockedPointerV1Interface() override; - virtual ~LockedPointerInterface(); - - /** - * @returns The interface version used by this LockedPointerInterface - **/ - PointerConstraintsInterfaceVersion interfaceVersion() const; - - enum class LifeTime { - OneShot, - Persistent + enum class LifeTime : uint { + OneShot = 1, + Persistent = 2 }; LifeTime lifeTime() const; @@ -105,7 +81,7 @@ public: * * @see regionChanged * @see SurfaceInterface::input - **/ + */ QRegion region() const; /** @@ -122,22 +98,21 @@ public: * call this function when the aboutToBeUnbound signal has been emitted. * * @see cursorPositionHintChanged - * @since 5.49 - **/ + */ QPointF cursorPositionHint() const; /** * Whether the Compositor set this pointer lock to be active. * @see setLocked * @see lockedChanged - **/ + */ bool isLocked() const; /** * Activates or deactivates the lock. * * A pointer lock can only be activated if the SurfaceInterface - * this LockedPointerInterface was created for has pointer focus + * this LockedPointerV1Interface was created for has pointer focus * and the pointer is inside the {@link region}. * * Unlocking resets the cursor position hint. @@ -145,74 +120,69 @@ public: * @param locked Whether the lock should be active * @see isLocked * @see lockedChanged - **/ + */ void setLocked(bool locked); Q_SIGNALS: + /** + * This is signal is emitted when the locked pointer is about to be destroyed. + */ + void aboutToBeDestroyed(); + /** * Emitted whenever the region changes. * This happens when the parent SurfaceInterface gets committed * @see region - **/ + */ void regionChanged(); /** * Emitted whenever the cursor position hint changes. * This happens when the parent SurfaceInterface gets committed * @see cursorPositionHint - * @since 5.49 - **/ + */ void cursorPositionHintChanged(); /** * Emitted whenever the {@link isLocked} state changes. * @see isLocked * @see setLocked - **/ + */ void lockedChanged(); -protected: - class Private; - explicit LockedPointerInterface(Private *p, QObject *parent = nullptr); - private: - Private *d_func() const; - friend class SurfaceInterfacePrivate; + LockedPointerV1Interface(LifeTime lifeTime, const QRegion ®ion, ::wl_resource *resource); + QScopedPointer d; + friend class LockedPointerV1InterfacePrivate; + friend class PointerConstraintsV1InterfacePrivate; }; /** * - * The ConfinedPointerInterface gets installed on a SurfaceInterface. + * The ConfinedPointerV1Interface gets installed on a SurfaceInterface. * The confinement indicates that the SurfaceInterface wants to confine the * pointer to a region of the SurfaceInterface. * * It is up to the compositor whether the confinement gets activated. - * To activate it needs to use {@link ConfinedPointerInterface::setConfined}. + * To activate it needs to use {@link ConfinedPointerV1Interface::setConfined}. * The compositor needs to ensure that the SurfaceInterface has pointer focus - * and that the pointer is inside the {@link ConfinedPointerInterface::region} when + * and that the pointer is inside the {@link ConfinedPointerV1Interface::region} when * it activates the confinement. * - * From client side the confinement gets deactivated by destroying the ConfinedPointerInterface. + * From client side the confinement gets deactivated by destroying the ConfinedPointerV1Interface. * From compositor side the confinement can be deactivated by setting - * {@link ConfinedPointerInterface::setConfined} to @c false. - * - * @since 5.29 - **/ -class KWAYLANDSERVER_EXPORT ConfinedPointerInterface : public Resource + * {@link ConfinedPointerV1Interface::setConfined} to @c false. + */ +class KWAYLANDSERVER_EXPORT ConfinedPointerV1Interface : public QObject { Q_OBJECT + public: + ~ConfinedPointerV1Interface() override; - virtual ~ConfinedPointerInterface(); - - /** - * @returns The interface version used by this ConfinedPointerInterface - **/ - PointerConstraintsInterfaceVersion interfaceVersion() const; - - enum class LifeTime { - OneShot, - Persistent + enum class LifeTime : uint { + OneShot = 1, + Persistent = 2 }; LifeTime lifeTime() const; @@ -227,27 +197,27 @@ public: * * @see regionChanged * @see SurfaceInterface::input - **/ + */ QRegion region() const; /** * Whether the Compositor set this pointer confinement to be active. * @see setConfined * @see confinedChanged - **/ + */ bool isConfined() const; /** * Activates or deactivates the confinement. * * A pointer confinement can only be activated if the SurfaceInterface - * this ConfinedPointerInterface was created for has pointer focus + * this ConfinedPointerV1Interface was created for has pointer focus * and the pointer is inside the {@link region}. * * @param confined Whether the confinement should be active * @see isConfined * @see confinedChanged - **/ + */ void setConfined(bool confined); Q_SIGNALS: @@ -255,25 +225,21 @@ Q_SIGNALS: * Emitted whenever the region changes. * This happens when the parent SurfaceInterface gets committed * @see region - **/ + */ void regionChanged(); /** * Emitted whenever the {@link isConfined} state changes. * @see isConfined * @see setConfined - **/ + */ void confinedChanged(); -protected: - class Private; - explicit ConfinedPointerInterface(Private *p, QObject *parent = nullptr); - private: - Private *d_func() const; - friend class SurfaceInterfacePrivate; + ConfinedPointerV1Interface(LifeTime lifeTime, const QRegion ®ion, ::wl_resource *resource); + QScopedPointer d; + friend class ConfinedPointerV1InterfacePrivate; + friend class PointerConstraintsV1InterfacePrivate; }; -} - -#endif +} // namespace KWaylandServer diff --git a/src/wayland/pointerconstraints_v1_interface_p.h b/src/wayland/pointerconstraints_v1_interface_p.h new file mode 100644 index 0000000000..d89a074947 --- /dev/null +++ b/src/wayland/pointerconstraints_v1_interface_p.h @@ -0,0 +1,92 @@ +/* + SPDX-FileCopyrightText: 2016 Martin Gräßlin + SPDX-FileCopyrightText: 2020 Vlad Zahorodnii + + SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL +*/ + +#pragma once + +#include "pointerconstraints_v1_interface.h" + +#include "qwayland-server-pointer-constraints-unstable-v1.h" + +namespace KWaylandServer +{ + +class PointerConstraintsV1InterfacePrivate : public QtWaylandServer::zwp_pointer_constraints_v1 +{ +public: + explicit PointerConstraintsV1InterfacePrivate(Display *display); + +protected: + void zwp_pointer_constraints_v1_lock_pointer(Resource *resource, uint32_t id, + struct ::wl_resource *surface_resource, + struct ::wl_resource *pointer_resource, + struct ::wl_resource *region_resource, + uint32_t lifetime) override; + void zwp_pointer_constraints_v1_confine_pointer(Resource *resource, uint32_t id, + struct ::wl_resource *surface_resource, + struct ::wl_resource *pointer_resource, + struct ::wl_resource *region_resource, + uint32_t lifetime) override; + void zwp_pointer_constraints_v1_destroy(Resource *resource) override; +}; + +class LockedPointerV1InterfacePrivate : public QtWaylandServer::zwp_locked_pointer_v1 +{ +public: + static LockedPointerV1InterfacePrivate *get(LockedPointerV1Interface *pointer); + + LockedPointerV1InterfacePrivate(LockedPointerV1Interface *q, + LockedPointerV1Interface::LifeTime lifeTime, + const QRegion ®ion, ::wl_resource *resource); + + void commit(); + + LockedPointerV1Interface *q; + LockedPointerV1Interface::LifeTime lifeTime; + QRegion region; + QRegion pendingRegion; + QPointF hint = QPointF(-1, -1); + QPointF pendingHint; + bool hasPendingRegion = false; + bool hasPendingHint = false; + bool isLocked = false; + +protected: + void zwp_locked_pointer_v1_destroy_resource(Resource *resource) override; + void zwp_locked_pointer_v1_destroy(Resource *resource) override; + void zwp_locked_pointer_v1_set_cursor_position_hint(Resource *resource, + wl_fixed_t surface_x, + wl_fixed_t surface_y) override; + void zwp_locked_pointer_v1_set_region(Resource *resource, + struct ::wl_resource *region_resource) override; +}; + +class ConfinedPointerV1InterfacePrivate : public QtWaylandServer::zwp_confined_pointer_v1 +{ +public: + static ConfinedPointerV1InterfacePrivate *get(ConfinedPointerV1Interface *pointer); + + ConfinedPointerV1InterfacePrivate(ConfinedPointerV1Interface *q, + ConfinedPointerV1Interface::LifeTime lifeTime, + const QRegion ®ion, ::wl_resource *resource); + + void commit(); + + ConfinedPointerV1Interface *q; + ConfinedPointerV1Interface::LifeTime lifeTime; + QRegion region; + QRegion pendingRegion; + bool hasPendingRegion = false; + bool isConfined = false; + +protected: + void zwp_confined_pointer_v1_destroy_resource(Resource *resource) override; + void zwp_confined_pointer_v1_destroy(Resource *resource) override; + void zwp_confined_pointer_v1_set_region(Resource *resource, + struct ::wl_resource *region_resource) override; +}; + +} // namespace KWaylandServer diff --git a/src/wayland/server/pointerconstraints_interface.cpp b/src/wayland/server/pointerconstraints_interface.cpp deleted file mode 100644 index df0e671774..0000000000 --- a/src/wayland/server/pointerconstraints_interface.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - SPDX-FileCopyrightText: 2016 Martin Gräßlin - - SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL -*/ -#include "pointerconstraints_interface_p.h" - -#include - -namespace KWaylandServer -{ - -PointerConstraintsInterface::Private::Private(PointerConstraintsInterfaceVersion interfaceVersion, PointerConstraintsInterface *q, Display *d, const wl_interface *interface, quint32 version) - : Global::Private(d, interface, version) - , interfaceVersion(interfaceVersion) - , q(q) -{ -} - -PointerConstraintsInterface::PointerConstraintsInterface(Private *d, QObject *parent) - : Global(d, parent) -{ -} - -PointerConstraintsInterface::~PointerConstraintsInterface() = default; - -PointerConstraintsInterfaceVersion PointerConstraintsInterface::interfaceVersion() const -{ - Q_D(); - return d->interfaceVersion; -} - -PointerConstraintsInterface::Private *PointerConstraintsInterface::d_func() const -{ - return reinterpret_cast(d.data()); -} - -LockedPointerInterface::Private::Private(PointerConstraintsInterfaceVersion interfaceVersion, LockedPointerInterface *q, Global *c, wl_resource *parentResource, const wl_interface *interface, const void *implementation) - : Resource::Private(q, c, parentResource, interface, implementation) - , interfaceVersion(interfaceVersion) -{ -} - -LockedPointerInterface::Private::~Private() -{ - if (resource) { - wl_resource_destroy(resource); - resource = nullptr; - } -} - -void LockedPointerInterface::Private::commit() -{ - if (regionIsSet) { - region = pendingRegion; - pendingRegion = QRegion(); - regionIsSet = false; - emit q_func()->regionChanged(); - } - if (hintIsSet) { - hint = pendingHint; - hintIsSet = false; - emit q_func()->cursorPositionHintChanged(); - } -} - -LockedPointerInterface::LockedPointerInterface(Private *p, QObject *parent) - : Resource(p, parent) -{ - connect(this, &LockedPointerInterface::unbound, this, [this]() { setLocked(false); }); -} - -LockedPointerInterface::~LockedPointerInterface() = default; - -PointerConstraintsInterfaceVersion LockedPointerInterface::interfaceVersion() const -{ - Q_D(); - return d->interfaceVersion; -} - -LockedPointerInterface::LifeTime LockedPointerInterface::lifeTime() const -{ - Q_D(); - return d->lifeTime; -} - -QRegion LockedPointerInterface::region() const -{ - Q_D(); - return d->region; -} - -QPointF LockedPointerInterface::cursorPositionHint() const -{ - Q_D(); - return d->hint; -} - -bool LockedPointerInterface::isLocked() const -{ - Q_D(); - return d->locked; -} - -void LockedPointerInterface::setLocked(bool locked) -{ - Q_D(); - if (locked == d->locked) { - return; - } - if (!locked) { - d->hint = QPointF(-1., -1.); - } - d->locked = locked; - d->updateLocked(); - emit lockedChanged(); -} - -LockedPointerInterface::Private *LockedPointerInterface::d_func() const -{ - return reinterpret_cast(d.data()); -} - -ConfinedPointerInterface::Private::Private(PointerConstraintsInterfaceVersion interfaceVersion, ConfinedPointerInterface *q, Global *c, wl_resource *parentResource, const wl_interface *interface, const void *implementation) - : Resource::Private(q, c, parentResource, interface, implementation) - , interfaceVersion(interfaceVersion) -{ -} - -ConfinedPointerInterface::Private::~Private() -{ - if (resource) { - wl_resource_destroy(resource); - resource = nullptr; - } -} - -void ConfinedPointerInterface::Private::commit() -{ - if (!regionIsSet) { - return; - } - region = pendingRegion; - pendingRegion = QRegion(); - regionIsSet = false; - emit q_func()->regionChanged(); -} - -ConfinedPointerInterface::ConfinedPointerInterface(Private *p, QObject *parent) - : Resource(p, parent) -{ - connect(this, &ConfinedPointerInterface::unbound, this, [this]() { setConfined(false); }); -} - -ConfinedPointerInterface::~ConfinedPointerInterface() = default; - -PointerConstraintsInterfaceVersion ConfinedPointerInterface::interfaceVersion() const -{ - Q_D(); - return d->interfaceVersion; -} - -ConfinedPointerInterface::LifeTime ConfinedPointerInterface::lifeTime() const -{ - Q_D(); - return d->lifeTime; -} - -QRegion ConfinedPointerInterface::region() const -{ - Q_D(); - return d->region; -} - -bool ConfinedPointerInterface::isConfined() const -{ - Q_D(); - return d->confined; -} - -void ConfinedPointerInterface::setConfined(bool confined) -{ - Q_D(); - if (confined == d->confined) { - return; - } - d->confined = confined; - d->updateConfined(); - emit confinedChanged(); -} - -ConfinedPointerInterface::Private *ConfinedPointerInterface::d_func() const -{ - return reinterpret_cast(d.data()); -} - -} diff --git a/src/wayland/server/pointerconstraints_interface_p.h b/src/wayland/server/pointerconstraints_interface_p.h deleted file mode 100644 index a2169e651f..0000000000 --- a/src/wayland/server/pointerconstraints_interface_p.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - SPDX-FileCopyrightText: 2016 Martin Gräßlin - - SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL -*/ -#ifndef KWAYLAND_SERVER_POINTERCONSTRAINTS_INTERFACE_P_H -#define KWAYLAND_SERVER_POINTERCONSTRAINTS_INTERFACE_P_H -#include "pointerconstraints_interface.h" -#include "global_p.h" -#include "resource_p.h" - -#include - -namespace KWaylandServer -{ - -class PointerConstraintsInterface::Private : public Global::Private -{ -public: - PointerConstraintsInterfaceVersion interfaceVersion; - -protected: - Private(PointerConstraintsInterfaceVersion interfaceVersion, PointerConstraintsInterface *q, Display *d, const wl_interface *interface, quint32 version); - PointerConstraintsInterface *q; -}; - -class PointerConstraintsUnstableV1Interface : public PointerConstraintsInterface -{ - Q_OBJECT -public: - explicit PointerConstraintsUnstableV1Interface(Display *display, QObject *parent = nullptr); - virtual ~PointerConstraintsUnstableV1Interface(); - -private: - class Private; -}; - -class LockedPointerInterface::Private : public Resource::Private -{ -public: - ~Private(); - - virtual void updateLocked() = 0; - void commit(); - - PointerConstraintsInterfaceVersion interfaceVersion; - - LifeTime lifeTime; - QRegion region; - bool locked = false; - QPointF hint = QPointF(-1., -1.); - -protected: - Private(PointerConstraintsInterfaceVersion interfaceVersion, LockedPointerInterface *q, Global *c, wl_resource *parentResource, const wl_interface *interface, const void *implementation); - - QRegion pendingRegion; - bool regionIsSet = false; - - QPointF pendingHint; - bool hintIsSet = false; - -private: - LockedPointerInterface *q_func() { - return reinterpret_cast(q); - } -}; - -class LockedPointerUnstableV1Interface : public LockedPointerInterface -{ - Q_OBJECT -public: - explicit LockedPointerUnstableV1Interface(PointerConstraintsUnstableV1Interface *parent, wl_resource *parentResource); - virtual ~LockedPointerUnstableV1Interface(); - -private: - class Private; - Private *d_func() const; - friend class PointerConstraintsUnstableV1Interface; -}; - -class ConfinedPointerInterface::Private : public Resource::Private -{ -public: - ~Private(); - - virtual void updateConfined() = 0; - void commit(); - - PointerConstraintsInterfaceVersion interfaceVersion; - - LifeTime lifeTime; - QRegion region; - - bool confined = false; - -protected: - Private(PointerConstraintsInterfaceVersion interfaceVersion, ConfinedPointerInterface *q, Global *c, wl_resource *parentResource, const wl_interface *interface, const void *implementation); - - QRegion pendingRegion; - bool regionIsSet = false; - -private: - ConfinedPointerInterface *q_func() { - return reinterpret_cast(q); - } -}; - -class ConfinedPointerUnstableV1Interface : public ConfinedPointerInterface -{ - Q_OBJECT -public: - explicit ConfinedPointerUnstableV1Interface(PointerConstraintsUnstableV1Interface *parent, wl_resource *parentResource); - virtual ~ConfinedPointerUnstableV1Interface(); - -private: - class Private; - Private *d_func() const; - friend class PointerConstraintsUnstableV1Interface; -}; - -} - -#endif diff --git a/src/wayland/server/pointerconstraints_interface_v1.cpp b/src/wayland/server/pointerconstraints_interface_v1.cpp deleted file mode 100644 index 7cbe5955bc..0000000000 --- a/src/wayland/server/pointerconstraints_interface_v1.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* - SPDX-FileCopyrightText: 2016 Martin Gräßlin - - SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL -*/ -#include "pointerconstraints_interface_p.h" -#include "display.h" -#include "pointer_interface.h" -#include "region_interface.h" -#include "surface_interface_p.h" - -#include - -namespace KWaylandServer -{ - -class PointerConstraintsUnstableV1Interface::Private : public PointerConstraintsInterface::Private -{ -public: - Private(PointerConstraintsUnstableV1Interface *q, Display *d); - -private: - void bind(wl_client *client, uint32_t version, uint32_t id) override; - - template - void createConstraint(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface, wl_resource *pointer, wl_resource *region, uint32_t lifetime); - - static void unbind(wl_resource *resource); - static Private *cast(wl_resource *r) { - return reinterpret_cast(wl_resource_get_user_data(r)); - } - - static void destroyCallback(wl_client *client, wl_resource *resource); - static void lockPointerCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * surface, wl_resource * pointer, wl_resource * region, uint32_t lifetime); - static void confinePointerCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * surface, wl_resource * pointer, wl_resource * region, uint32_t lifetime); - - PointerConstraintsUnstableV1Interface *q; - static const struct zwp_pointer_constraints_v1_interface s_interface; - static const quint32 s_version; -}; - -class LockedPointerUnstableV1Interface::Private : public LockedPointerInterface::Private -{ -public: - Private(LockedPointerUnstableV1Interface *q, PointerConstraintsUnstableV1Interface *c, wl_resource *parentResource); - ~Private(); - - void updateLocked() override; - -private: - static void setCursorPositionHintCallback(wl_client *client, wl_resource *resource, wl_fixed_t surface_x, wl_fixed_t surface_y); - static void setRegionCallback(wl_client *client, wl_resource *resource, wl_resource * region); - - LockedPointerUnstableV1Interface *q_func() { - return reinterpret_cast(q); - } - - static const struct zwp_locked_pointer_v1_interface s_interface; -}; - -const quint32 PointerConstraintsUnstableV1Interface::Private::s_version = 1; - -#ifndef K_DOXYGEN -const struct zwp_pointer_constraints_v1_interface PointerConstraintsUnstableV1Interface::Private::s_interface = { - destroyCallback, - lockPointerCallback, - confinePointerCallback -}; -#endif - -void PointerConstraintsUnstableV1Interface::Private::destroyCallback(wl_client *client, wl_resource *resource) -{ - Q_UNUSED(client) - wl_resource_destroy(resource); -} - -template -void PointerConstraintsUnstableV1Interface::Private::createConstraint(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface, wl_resource *pointer, wl_resource *region, uint32_t lifetime) -{ - auto s = SurfaceInterface::get(surface); - auto p = PointerInterface::get(pointer); - if (!s || !p) { - // send error? - return; - } - if (!s->lockedPointer().isNull() || !s->confinedPointer().isNull()) { - wl_resource_post_error(surface, ZWP_POINTER_CONSTRAINTS_V1_ERROR_ALREADY_CONSTRAINED, "Surface already constrained"); - return; - } - auto constraint = new T(q, resource); - switch (lifetime) { - case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT: - constraint->d_func()->lifeTime = T::LifeTime::Persistent; - break; - case ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT: // fall through - default: - constraint->d_func()->lifeTime = T::LifeTime::OneShot; - break; - } - auto r = RegionInterface::get(region); - constraint->d_func()->region = r ? r->region() : QRegion(); - constraint->d_func()->create(display->getConnection(client), version, id); - SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(s); - surfacePrivate->installPointerConstraint(constraint); -} - -void PointerConstraintsUnstableV1Interface::Private::lockPointerCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface, wl_resource *pointer, wl_resource *region, uint32_t lifetime) -{ - cast(resource)->createConstraint(client, resource, id, surface, pointer, region, lifetime); -} - -void PointerConstraintsUnstableV1Interface::Private::confinePointerCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *surface, wl_resource *pointer, wl_resource *region, uint32_t lifetime) -{ - cast(resource)->createConstraint(client, resource, id, surface, pointer, region, lifetime); -} - -PointerConstraintsUnstableV1Interface::Private::Private(PointerConstraintsUnstableV1Interface *q, Display *d) - : PointerConstraintsInterface::Private(PointerConstraintsInterfaceVersion::UnstableV1, q, d, &zwp_pointer_constraints_v1_interface, s_version) - , q(q) -{ -} - -void PointerConstraintsUnstableV1Interface::Private::bind(wl_client *client, uint32_t version, uint32_t id) -{ - auto c = display->getConnection(client); - wl_resource *resource = c->createResource(&zwp_pointer_constraints_v1_interface, qMin(version, s_version), id); - if (!resource) { - wl_client_post_no_memory(client); - return; - } - wl_resource_set_implementation(resource, &s_interface, this, unbind); - // TODO: should we track? -} - -void PointerConstraintsUnstableV1Interface::Private::unbind(wl_resource *resource) -{ - Q_UNUSED(resource) - // TODO: implement? -} - -PointerConstraintsUnstableV1Interface::PointerConstraintsUnstableV1Interface(Display *display, QObject *parent) - : PointerConstraintsInterface(new Private(this, display), parent) -{ -} - -PointerConstraintsUnstableV1Interface::~PointerConstraintsUnstableV1Interface() = default; - -#ifndef K_DOXYGEN -const struct zwp_locked_pointer_v1_interface LockedPointerUnstableV1Interface::Private::s_interface = { - resourceDestroyedCallback, - setCursorPositionHintCallback, - setRegionCallback -}; -#endif - -void LockedPointerUnstableV1Interface::Private::setCursorPositionHintCallback(wl_client *client, wl_resource *resource, wl_fixed_t surface_x, wl_fixed_t surface_y) -{ - Q_UNUSED(client) - auto p = cast(resource); - p->pendingHint = QPointF(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)); - p->hintIsSet = true; -} - -void LockedPointerUnstableV1Interface::Private::setRegionCallback(wl_client *client, wl_resource *resource, wl_resource * region) -{ - Q_UNUSED(client) - auto p = cast(resource); - auto r = RegionInterface::get(region); - p->pendingRegion = r ? r->region() : QRegion(); - p->regionIsSet = true; -} - -void LockedPointerUnstableV1Interface::Private::updateLocked() -{ - if (!resource) { - return; - } - if (locked) { - zwp_locked_pointer_v1_send_locked(resource); - } else { - zwp_locked_pointer_v1_send_unlocked(resource); - } -} - -LockedPointerUnstableV1Interface::Private::Private(LockedPointerUnstableV1Interface *q, PointerConstraintsUnstableV1Interface *c, wl_resource *parentResource) - : LockedPointerInterface::Private(PointerConstraintsInterfaceVersion::UnstableV1, q, c, parentResource, &zwp_locked_pointer_v1_interface, &s_interface) -{ -} - -LockedPointerUnstableV1Interface::LockedPointerUnstableV1Interface(PointerConstraintsUnstableV1Interface *parent, wl_resource *parentResource) - : LockedPointerInterface(new Private(this, parent, parentResource)) -{ -} - -LockedPointerUnstableV1Interface::Private::~Private() = default; - -LockedPointerUnstableV1Interface::~LockedPointerUnstableV1Interface() = default; - -LockedPointerUnstableV1Interface::Private *LockedPointerUnstableV1Interface::d_func() const -{ - return reinterpret_cast(d.data()); -} - -class ConfinedPointerUnstableV1Interface::Private : public ConfinedPointerInterface::Private -{ -public: - Private(ConfinedPointerUnstableV1Interface *q, PointerConstraintsUnstableV1Interface *c, wl_resource *parentResource); - ~Private(); - - void updateConfined() override; - -private: - static void setRegionCallback(wl_client *client, wl_resource *resource, wl_resource * region); - - ConfinedPointerUnstableV1Interface *q_func() { - return reinterpret_cast(q); - } - - static const struct zwp_confined_pointer_v1_interface s_interface; -}; - -#ifndef K_DOXYGEN -const struct zwp_confined_pointer_v1_interface ConfinedPointerUnstableV1Interface::Private::s_interface = { - resourceDestroyedCallback, - setRegionCallback -}; -#endif - -void ConfinedPointerUnstableV1Interface::Private::setRegionCallback(wl_client *client, wl_resource *resource, wl_resource *region) -{ - Q_UNUSED(client) - auto p = cast(resource); - auto r = RegionInterface::get(region); - p->pendingRegion = r ? r->region() : QRegion(); - p->regionIsSet = true; -} - -ConfinedPointerUnstableV1Interface::Private::Private(ConfinedPointerUnstableV1Interface *q, PointerConstraintsUnstableV1Interface *c, wl_resource *parentResource) - : ConfinedPointerInterface::Private(PointerConstraintsInterfaceVersion::UnstableV1, q, c, parentResource, &zwp_confined_pointer_v1_interface, &s_interface) -{ -} - -ConfinedPointerUnstableV1Interface::ConfinedPointerUnstableV1Interface(PointerConstraintsUnstableV1Interface *parent, wl_resource *parentResource) - : ConfinedPointerInterface(new Private(this, parent, parentResource)) -{ -} - -ConfinedPointerUnstableV1Interface::Private::~Private() = default; - -ConfinedPointerUnstableV1Interface::~ConfinedPointerUnstableV1Interface() = default; - -void ConfinedPointerUnstableV1Interface::Private::updateConfined() -{ - if (!resource) { - return; - } - if (confined) { - zwp_confined_pointer_v1_send_confined(resource); - } else { - zwp_confined_pointer_v1_send_unconfined(resource); - } -} - -ConfinedPointerUnstableV1Interface::Private *ConfinedPointerUnstableV1Interface::d_func() const -{ - return reinterpret_cast(d.data()); -} - -} diff --git a/src/wayland/surface_interface.cpp b/src/wayland/surface_interface.cpp index 5615887ad2..32a5fc48a4 100644 --- a/src/wayland/surface_interface.cpp +++ b/src/wayland/surface_interface.cpp @@ -11,7 +11,7 @@ #include "compositor_interface.h" #include "display.h" #include "idleinhibit_v1_interface_p.h" -#include "pointerconstraints_interface_p.h" +#include "pointerconstraints_v1_interface_p.h" #include "region_interface.h" #include "subcompositor_interface.h" #include "subsurface_interface_p.h" @@ -202,14 +202,15 @@ void SurfaceInterfacePrivate::setContrast(const QPointer &con pending.contrastIsSet = true; } -void SurfaceInterfacePrivate::installPointerConstraint(LockedPointerInterface *lock) +void SurfaceInterfacePrivate::installPointerConstraint(LockedPointerV1Interface *lock) { - Q_ASSERT(lockedPointer.isNull()); - Q_ASSERT(confinedPointer.isNull()); - lockedPointer = QPointer(lock); + Q_ASSERT(!lockedPointer); + Q_ASSERT(!confinedPointer); + + lockedPointer = lock; auto cleanUp = [this]() { - lockedPointer.clear(); + lockedPointer = nullptr; QObject::disconnect(constrainsOneShotConnection); constrainsOneShotConnection = QMetaObject::Connection(); QObject::disconnect(constrainsUnboundConnection); @@ -217,35 +218,29 @@ void SurfaceInterfacePrivate::installPointerConstraint(LockedPointerInterface *l emit q->pointerConstraintsChanged(); }; - if (lock->lifeTime() == LockedPointerInterface::LifeTime::OneShot) { - constrainsOneShotConnection = QObject::connect(lock, &LockedPointerInterface::lockedChanged, q, + if (lock->lifeTime() == LockedPointerV1Interface::LifeTime::OneShot) { + constrainsOneShotConnection = QObject::connect(lock, &LockedPointerV1Interface::lockedChanged, q, [this, cleanUp] { - if (lockedPointer.isNull() || lockedPointer->isLocked()) { + if (lockedPointer->isLocked()) { return; } cleanUp(); } ); } - constrainsUnboundConnection = QObject::connect(lock, &LockedPointerInterface::unbound, q, - [this, cleanUp] { - if (lockedPointer.isNull()) { - return; - } - cleanUp(); - } - ); + constrainsUnboundConnection = QObject::connect(lock, &LockedPointerV1Interface::destroyed, q, cleanUp); emit q->pointerConstraintsChanged(); } -void SurfaceInterfacePrivate::installPointerConstraint(ConfinedPointerInterface *confinement) +void SurfaceInterfacePrivate::installPointerConstraint(ConfinedPointerV1Interface *confinement) { - Q_ASSERT(lockedPointer.isNull()); - Q_ASSERT(confinedPointer.isNull()); - confinedPointer = QPointer(confinement); + Q_ASSERT(!lockedPointer); + Q_ASSERT(!confinedPointer); + + confinedPointer = confinement; auto cleanUp = [this]() { - confinedPointer.clear(); + confinedPointer = nullptr; QObject::disconnect(constrainsOneShotConnection); constrainsOneShotConnection = QMetaObject::Connection(); QObject::disconnect(constrainsUnboundConnection); @@ -253,24 +248,17 @@ void SurfaceInterfacePrivate::installPointerConstraint(ConfinedPointerInterface emit q->pointerConstraintsChanged(); }; - if (confinement->lifeTime() == ConfinedPointerInterface::LifeTime::OneShot) { - constrainsOneShotConnection = QObject::connect(confinement, &ConfinedPointerInterface::confinedChanged, q, + if (confinement->lifeTime() == ConfinedPointerV1Interface::LifeTime::OneShot) { + constrainsOneShotConnection = QObject::connect(confinement, &ConfinedPointerV1Interface::confinedChanged, q, [this, cleanUp] { - if (confinedPointer.isNull() || confinedPointer->isConfined()) { + if (confinedPointer->isConfined()) { return; } cleanUp(); } ); } - constrainsUnboundConnection = QObject::connect(confinement, &ConfinedPointerInterface::unbound, q, - [this, cleanUp] { - if (confinedPointer.isNull()) { - return; - } - cleanUp(); - } - ); + constrainsUnboundConnection = QObject::connect(confinement, &ConfinedPointerV1Interface::destroyed, q, cleanUp); emit q->pointerConstraintsChanged(); } @@ -572,11 +560,13 @@ void SurfaceInterfacePrivate::swapStates(State *source, State *target, bool emit target->bufferTransform = source->bufferTransform; target->bufferTransformIsSet = true; } - if (!lockedPointer.isNull()) { - lockedPointer->d_func()->commit(); + if (lockedPointer) { + auto lockedPointerPrivate = LockedPointerV1InterfacePrivate::get(lockedPointer); + lockedPointerPrivate->commit(); } - if (!confinedPointer.isNull()) { - confinedPointer->d_func()->commit(); + if (confinedPointer) { + auto confinedPointerPrivate = ConfinedPointerV1InterfacePrivate::get(confinedPointer); + confinedPointerPrivate->commit(); } *source = State{}; @@ -909,12 +899,12 @@ SurfaceInterface *SurfaceInterface::inputSurfaceAt(const QPointF &position) return nullptr; } -QPointer SurfaceInterface::lockedPointer() const +LockedPointerV1Interface *SurfaceInterface::lockedPointer() const { return d->lockedPointer; } -QPointer SurfaceInterface::confinedPointer() const +ConfinedPointerV1Interface *SurfaceInterface::confinedPointer() const { return d->confinedPointer; } diff --git a/src/wayland/surface_interface.h b/src/wayland/surface_interface.h index e0e5df09e8..8dabd4eed9 100644 --- a/src/wayland/surface_interface.h +++ b/src/wayland/surface_interface.h @@ -20,10 +20,10 @@ namespace KWaylandServer { class BlurInterface; class BufferInterface; -class ConfinedPointerInterface; +class ConfinedPointerV1Interface; class ContrastInterface; class CompositorInterface; -class LockedPointerInterface; +class LockedPointerV1Interface; class ShadowInterface; class SlideInterface; class SubSurfaceInterface; @@ -323,14 +323,14 @@ public: * @see pointerConstraintsChanged * @since 5.29 **/ - QPointer confinedPointer() const; + ConfinedPointerV1Interface *confinedPointer() const; /** * Pointer lock installed on this SurfaceInterface. * @see pointerConstraintsChanged * @since 5.29 **/ - QPointer lockedPointer() const; + LockedPointerV1Interface *lockedPointer() const; /** * @returns Whether this SurfaceInterface wants idle to be inhibited on the Output it is shown diff --git a/src/wayland/surface_interface_p.h b/src/wayland/surface_interface_p.h index 46cd353bf5..c1a14a3d78 100644 --- a/src/wayland/surface_interface_p.h +++ b/src/wayland/surface_interface_p.h @@ -84,8 +84,8 @@ public: void setBlur(const QPointer &blur); void setContrast(const QPointer &contrast); void setSlide(const QPointer &slide); - void installPointerConstraint(LockedPointerInterface *lock); - void installPointerConstraint(ConfinedPointerInterface *confinement); + void installPointerConstraint(LockedPointerV1Interface *lock); + void installPointerConstraint(ConfinedPointerV1Interface *confinement); void installIdleInhibitor(IdleInhibitorV1Interface *inhibitor); void commit(); @@ -114,8 +114,8 @@ public: QVector outputs; - QPointer lockedPointer; - QPointer confinedPointer; + LockedPointerV1Interface *lockedPointer = nullptr; + ConfinedPointerV1Interface *confinedPointer = nullptr; QHash outputDestroyedConnections; QVector idleInhibitors; ViewportInterface *viewportExtension = nullptr;