Port pointer locking away from KWayland
Use QtWaylandScanner directly
This commit is contained in:
parent
ecc5325fab
commit
22cd3b1e5c
6 changed files with 103 additions and 99 deletions
|
@ -24,7 +24,6 @@ Dependencies:
|
||||||
|
|
||||||
- 'on': ['Linux', 'FreeBSD']
|
- 'on': ['Linux', 'FreeBSD']
|
||||||
'require':
|
'require':
|
||||||
'frameworks/kwayland': '@stable'
|
|
||||||
'frameworks/kpackage': '@stable'
|
'frameworks/kpackage': '@stable'
|
||||||
'libraries/pulseaudio-qt': '@stable'
|
'libraries/pulseaudio-qt': '@stable'
|
||||||
'libraries/plasma-wayland-protocols': '@stable'
|
'libraries/plasma-wayland-protocols': '@stable'
|
||||||
|
|
|
@ -66,7 +66,7 @@ else()
|
||||||
set(Qca_LIBRARY qca-qt${QT_MAJOR_VERSION})
|
set(Qca_LIBRARY qca-qt${QT_MAJOR_VERSION})
|
||||||
|
|
||||||
set(KF5_REQUIRED_COMPONENTS I18n ConfigWidgets DBusAddons IconThemes Notifications KIO KCMUtils Service Solid Kirigami2 People WindowSystem GuiAddons)
|
set(KF5_REQUIRED_COMPONENTS I18n ConfigWidgets DBusAddons IconThemes Notifications KIO KCMUtils Service Solid Kirigami2 People WindowSystem GuiAddons)
|
||||||
set(KF5_OPTIONAL_COMPONENTS DocTools Wayland)
|
set(KF5_OPTIONAL_COMPONENTS DocTools)
|
||||||
|
|
||||||
set_package_properties(KF5Kirigami2 PROPERTIES
|
set_package_properties(KF5Kirigami2 PROPERTIES
|
||||||
DESCRIPTION "QtQuick plugins to build user interfaces based on KDE UX guidelines"
|
DESCRIPTION "QtQuick plugins to build user interfaces based on KDE UX guidelines"
|
||||||
|
@ -84,6 +84,7 @@ else()
|
||||||
find_package(Wayland 1.9 REQUIRED Client)
|
find_package(Wayland 1.9 REQUIRED Client)
|
||||||
find_package(Qt${QT_MAJOR_VERSION} REQUIRED COMPONENTS WaylandClient)
|
find_package(Qt${QT_MAJOR_VERSION} REQUIRED COMPONENTS WaylandClient)
|
||||||
find_package(PlasmaWaylandProtocols REQUIRED)
|
find_package(PlasmaWaylandProtocols REQUIRED)
|
||||||
|
find_package(WaylandProtocols REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(KF5PeopleVCard)
|
find_package(KF5PeopleVCard)
|
||||||
|
|
|
@ -14,12 +14,22 @@ ecm_target_qml_sources(kdeconnectdeclarativeplugin
|
||||||
qml/RemoteKeyboard.qml
|
qml/RemoteKeyboard.qml
|
||||||
VERSION 1.0)
|
VERSION 1.0)
|
||||||
|
|
||||||
if (TARGET KF5::WaylandClient)
|
if(UNIX AND NOT APPLE)
|
||||||
target_sources(kdeconnectdeclarativeplugin PRIVATE pointerlockerwayland.cpp)
|
|
||||||
target_link_libraries(kdeconnectdeclarativeplugin PRIVATE KF5::WaylandClient)
|
if (QT_MAJOR_VERSION EQUAL "5")
|
||||||
|
ecm_add_qtwayland_client_protocol(wayland_SRCS
|
||||||
|
PROTOCOL ${WaylandProtocols_DATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml
|
||||||
|
BASENAME pointer-constraints-unstable-v1
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
qt6_generate_wayland_protocol_client_sources(kdeconnectdeclarativeplugin FILES
|
||||||
|
${WaylandProtocols_DATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_sources(kdeconnectdeclarativeplugin PRIVATE ${wayland_SRCS})
|
||||||
|
target_link_libraries(kdeconnectdeclarativeplugin PRIVATE Wayland::Client Qt::WaylandClient Qt::GuiPrivate)
|
||||||
|
target_sources(kdeconnectdeclarativeplugin PUBLIC pointerlockerwayland.cpp)
|
||||||
target_compile_definitions(kdeconnectdeclarativeplugin PRIVATE -DWITH_WAYLAND=1)
|
target_compile_definitions(kdeconnectdeclarativeplugin PRIVATE -DWITH_WAYLAND=1)
|
||||||
else()
|
|
||||||
target_compile_definitions(kdeconnectdeclarativeplugin PRIVATE -DWITH_WAYLAND=0)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(kdeconnectdeclarativeplugin PRIVATE Qt::Quick kdeconnectinterfaces kdeconnectcore)
|
target_link_libraries(kdeconnectdeclarativeplugin PRIVATE Qt::Quick kdeconnectinterfaces kdeconnectcore)
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <pluginmodel.h>
|
#include <pluginmodel.h>
|
||||||
#include <remotecommandsmodel.h>
|
#include <remotecommandsmodel.h>
|
||||||
#include <remotesinksmodel.h>
|
#include <remotesinksmodel.h>
|
||||||
#if WITH_WAYLAND == 1
|
#if WITH_WAYLAND
|
||||||
#include "pointerlockerwayland.h"
|
#include "pointerlockerwayland.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ void KdeConnectDeclarativePlugin::registerTypes(const char *uri)
|
||||||
});
|
});
|
||||||
qmlRegisterSingletonType<AbstractPointerLocker>("org.kde.kdeconnect", 1, 0, "PointerLocker", [](QQmlEngine *, QJSEngine *) -> QObject * {
|
qmlRegisterSingletonType<AbstractPointerLocker>("org.kde.kdeconnect", 1, 0, "PointerLocker", [](QQmlEngine *, QJSEngine *) -> QObject * {
|
||||||
AbstractPointerLocker *ret;
|
AbstractPointerLocker *ret;
|
||||||
#if WITH_WAYLAND == 1
|
#if WITH_WAYLAND
|
||||||
if (qGuiApp->platformName() == QLatin1String("wayland"))
|
if (qGuiApp->platformName() == QLatin1String("wayland"))
|
||||||
ret = new PointerLockerWayland;
|
ret = new PointerLockerWayland;
|
||||||
else
|
else
|
||||||
|
|
|
@ -9,71 +9,73 @@
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include <KWayland/Client/compositor.h>
|
#include "qwayland-pointer-constraints-unstable-v1.h"
|
||||||
#include <KWayland/Client/connection_thread.h>
|
#include <QtWaylandClient/qwaylandclientextension.h>
|
||||||
#include <KWayland/Client/pointer.h>
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
#include <KWayland/Client/pointerconstraints.h>
|
|
||||||
#include <KWayland/Client/region.h>
|
|
||||||
#include <KWayland/Client/registry.h>
|
|
||||||
#include <KWayland/Client/relativepointer.h>
|
|
||||||
#include <KWayland/Client/seat.h>
|
|
||||||
#include <KWayland/Client/surface.h>
|
|
||||||
|
|
||||||
using namespace KWayland::Client;
|
#include <QGuiApplication>
|
||||||
|
|
||||||
|
class PointerConstraints : public QWaylandClientExtensionTemplate<PointerConstraints>, public QtWayland::zwp_pointer_constraints_v1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PointerConstraints()
|
||||||
|
: QWaylandClientExtensionTemplate<PointerConstraints>(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class LockedPointer : public QObject, public QtWayland::zwp_locked_pointer_v1
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
LockedPointer(struct ::zwp_locked_pointer_v1 *object, QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, zwp_locked_pointer_v1(object)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SIGNAL void locked();
|
||||||
|
|
||||||
|
Q_SIGNAL void unlocked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void zwp_locked_pointer_v1_locked() override
|
||||||
|
{
|
||||||
|
Q_EMIT locked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void zwp_locked_pointer_v1_unlocked() override
|
||||||
|
{
|
||||||
|
Q_EMIT unlocked();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
PointerLockerWayland::PointerLockerWayland(QObject *parent)
|
PointerLockerWayland::PointerLockerWayland(QObject *parent)
|
||||||
: AbstractPointerLocker(parent)
|
: AbstractPointerLocker(parent)
|
||||||
, m_connectionThreadObject(ConnectionThread::fromApplication(this))
|
|
||||||
{
|
{
|
||||||
setupRegistry();
|
m_pointerConstraints = new PointerConstraints;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PointerLockerWayland::setupRegistry()
|
PointerLockerWayland::~PointerLockerWayland()
|
||||||
{
|
{
|
||||||
Registry *registry = new Registry(this);
|
delete m_pointerConstraints;
|
||||||
|
|
||||||
connect(registry, &Registry::compositorAnnounced, this, [this, registry](quint32 name, quint32 version) {
|
|
||||||
m_compositor = registry->createCompositor(name, version, this);
|
|
||||||
});
|
|
||||||
connect(registry, &Registry::relativePointerManagerUnstableV1Announced, this, [this, registry](quint32 name, quint32 version) {
|
|
||||||
Q_ASSERT(!m_relativePointerManager);
|
|
||||||
m_relativePointerManager = registry->createRelativePointerManager(name, version, this);
|
|
||||||
});
|
|
||||||
connect(registry, &Registry::seatAnnounced, this, [this, registry](quint32 name, quint32 version) {
|
|
||||||
m_seat = registry->createSeat(name, version, this);
|
|
||||||
if (m_seat->hasPointer()) {
|
|
||||||
m_pointer = m_seat->createPointer(this);
|
|
||||||
}
|
|
||||||
connect(m_seat, &Seat::hasPointerChanged, this, [this](bool hasPointer) {
|
|
||||||
delete m_pointer;
|
|
||||||
|
|
||||||
if (!hasPointer)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_pointer = m_seat->createPointer(this);
|
|
||||||
|
|
||||||
delete m_relativePointer;
|
|
||||||
m_relativePointer = m_relativePointerManager->createRelativePointer(m_pointer, this);
|
|
||||||
connect(m_relativePointer, &RelativePointer::relativeMotion, this, [this](const QSizeF &delta) {
|
|
||||||
Q_EMIT pointerMoved({delta.width(), delta.height()});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
connect(registry, &Registry::pointerConstraintsUnstableV1Announced, this, [this, registry](quint32 name, quint32 version) {
|
|
||||||
m_pointerConstraints = registry->createPointerConstraints(name, version, this);
|
|
||||||
});
|
|
||||||
connect(registry, &Registry::interfacesAnnounced, this, [this] {
|
|
||||||
Q_ASSERT(m_compositor);
|
|
||||||
Q_ASSERT(m_seat);
|
|
||||||
Q_ASSERT(m_pointerConstraints);
|
|
||||||
});
|
|
||||||
registry->create(m_connectionThreadObject);
|
|
||||||
registry->setup();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PointerLockerWayland::isLockEffective() const
|
bool PointerLockerWayland::isLockEffective() const
|
||||||
{
|
{
|
||||||
return m_lockedPointer && m_lockedPointer->isValid();
|
return m_lockedPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_pointer *PointerLockerWayland::getPointer()
|
||||||
|
{
|
||||||
|
QPlatformNativeInterface *native = qGuiApp->platformNativeInterface();
|
||||||
|
if (!native) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
window()->create();
|
||||||
|
|
||||||
|
return reinterpret_cast<wl_pointer *>(native->nativeResourceForIntegration(QByteArrayLiteral("wl_pointer")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PointerLockerWayland::enforceLock()
|
void PointerLockerWayland::enforceLock()
|
||||||
|
@ -82,23 +84,31 @@ void PointerLockerWayland::enforceLock()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QScopedPointer<Surface> winSurface(Surface::fromWindow(m_window));
|
wl_surface *wlSurface = [](QWindow *window) -> wl_surface * {
|
||||||
if (!winSurface) {
|
if (!window) {
|
||||||
qWarning() << "Locking a window that is not mapped";
|
return nullptr;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
auto *lockedPointer = m_pointerConstraints->lockPointer(winSurface.data(), m_pointer, nullptr, PointerConstraints::LifeTime::Persistent, this);
|
|
||||||
|
|
||||||
if (!lockedPointer) {
|
QPlatformNativeInterface *native = qGuiApp->platformNativeInterface();
|
||||||
|
if (!native) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
window->create();
|
||||||
|
return reinterpret_cast<wl_surface *>(native->nativeResourceForWindow(QByteArrayLiteral("surface"), window));
|
||||||
|
}(m_window);
|
||||||
|
|
||||||
|
m_lockedPointer =
|
||||||
|
new LockedPointer(m_pointerConstraints->lock_pointer(wlSurface, getPointer(), nullptr, PointerConstraints::lifetime::lifetime_persistent), this);
|
||||||
|
|
||||||
|
if (!m_lockedPointer) {
|
||||||
qDebug() << "ERROR when receiving locked pointer!";
|
qDebug() << "ERROR when receiving locked pointer!";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_lockedPointer = lockedPointer;
|
|
||||||
|
|
||||||
connect(lockedPointer, &LockedPointer::locked, this, [this] {
|
connect(m_lockedPointer, &LockedPointer::locked, this, [this] {
|
||||||
Q_EMIT lockEffectiveChanged(true);
|
Q_EMIT lockEffectiveChanged(true);
|
||||||
});
|
});
|
||||||
connect(lockedPointer, &LockedPointer::unlocked, this, [this] {
|
connect(m_lockedPointer, &LockedPointer::unlocked, this, [this] {
|
||||||
Q_EMIT lockEffectiveChanged(false);
|
Q_EMIT lockEffectiveChanged(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -128,7 +138,7 @@ void PointerLockerWayland::cleanupLock()
|
||||||
if (!m_lockedPointer) {
|
if (!m_lockedPointer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_lockedPointer->release();
|
m_lockedPointer->destroy();
|
||||||
m_lockedPointer->deleteLater();
|
m_lockedPointer->deleteLater();
|
||||||
m_lockedPointer = nullptr;
|
m_lockedPointer = nullptr;
|
||||||
Q_EMIT lockEffectiveChanged(false);
|
Q_EMIT lockEffectiveChanged(false);
|
||||||
|
@ -151,3 +161,5 @@ void PointerLockerWayland::setWindow(QWindow *window)
|
||||||
enforceLock();
|
enforceLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "pointerlockerwayland.moc"
|
||||||
|
|
|
@ -9,30 +9,16 @@
|
||||||
|
|
||||||
#include "pointerlocker.h"
|
#include "pointerlocker.h"
|
||||||
|
|
||||||
namespace KWayland
|
|
||||||
{
|
|
||||||
namespace Client
|
|
||||||
{
|
|
||||||
|
|
||||||
class ConnectionThread;
|
|
||||||
class Registry;
|
|
||||||
class Compositor;
|
|
||||||
class Seat;
|
|
||||||
class Pointer;
|
|
||||||
class PointerConstraints;
|
class PointerConstraints;
|
||||||
class LockedPointer;
|
class LockedPointer;
|
||||||
class ConfinedPointer;
|
class wl_pointer;
|
||||||
class RelativePointer;
|
|
||||||
class RelativePointerManager;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PointerLockerWayland : public AbstractPointerLocker
|
class PointerLockerWayland : public AbstractPointerLocker
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
PointerLockerWayland(QObject *parent = nullptr);
|
PointerLockerWayland(QObject *parent = nullptr);
|
||||||
|
~PointerLockerWayland();
|
||||||
|
|
||||||
void setLocked(bool locked) override;
|
void setLocked(bool locked) override;
|
||||||
bool isLocked() const override
|
bool isLocked() const override
|
||||||
|
@ -42,7 +28,7 @@ public:
|
||||||
bool isLockEffective() const override;
|
bool isLockEffective() const override;
|
||||||
bool isSupported() const override
|
bool isSupported() const override
|
||||||
{
|
{
|
||||||
return m_pointerConstraints && m_relativePointerManager;
|
return m_pointerConstraints;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWindow(QWindow *window) override;
|
void setWindow(QWindow *window) override;
|
||||||
|
@ -52,16 +38,12 @@ private:
|
||||||
void enforceLock();
|
void enforceLock();
|
||||||
void cleanupLock();
|
void cleanupLock();
|
||||||
|
|
||||||
bool m_isLocked = false;
|
wl_pointer *getPointer();
|
||||||
KWayland::Client::ConnectionThread *m_connectionThreadObject;
|
|
||||||
KWayland::Client::Compositor *m_compositor = nullptr;
|
|
||||||
KWayland::Client::Seat *m_seat = nullptr;
|
|
||||||
KWayland::Client::Pointer *m_pointer = nullptr;
|
|
||||||
KWayland::Client::PointerConstraints *m_pointerConstraints = nullptr;
|
|
||||||
KWayland::Client::RelativePointer *m_relativePointer = nullptr;
|
|
||||||
KWayland::Client::RelativePointerManager *m_relativePointerManager = nullptr;
|
|
||||||
|
|
||||||
KWayland::Client::LockedPointer *m_lockedPointer = nullptr;
|
bool m_isLocked = false;
|
||||||
|
|
||||||
|
PointerConstraints *m_pointerConstraints;
|
||||||
|
LockedPointer *m_lockedPointer = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue