Implement support for the relative pointer protocol
Summary: This change implements the zwp_relative_pointer_v1 protocol which allows to send relative motion events. The (unstable) protocol consists of a RelativePointerManager which creates RelativePointers for a given Pointer. This interface currently only has one event to report the relative motion. It carries the delta, the non-accelerated-delta and a timestamp in microsends granularity. On the server side the implementation is mostly internal. Once a RelativePointerManagerInterface is created one can send relative motion events through the SeatInterface. The SeatInterface takes care of sending it to the responding RelativePointerInterface. The protocol does not restrict the sending of "normal" and relative motion events. Thus it can be combined in any way one wants. This allows to have a rather simple implementation. A user of the SeatInterface can just start to feed the relative motion events (if the information is available) to the SeatInterface together with the pointer events. On client side a new RelativePointerManager and RelativePointer class are added. The RelativePointerManager creates the RelativePointer for a given Pointer. The event sent to RelativePointer is transformed in a normal signal. Reviewers: #plasma Subscribers: plasma-devel Tags: #plasma_on_wayland Differential Revision: https://phabricator.kde.org/D2978
This commit is contained in:
parent
9f3d6c8f84
commit
a96776ac0e
15 changed files with 599 additions and 0 deletions
|
@ -23,6 +23,8 @@ set(SERVER_LIB_SRCS
|
|||
plasmawindowmanagement_interface.cpp
|
||||
qtsurfaceextension_interface.cpp
|
||||
region_interface.cpp
|
||||
relativepointer_interface.cpp
|
||||
relativepointer_interface_v1.cpp
|
||||
resource.cpp
|
||||
seat_interface.cpp
|
||||
slide_interface.cpp
|
||||
|
@ -95,6 +97,11 @@ ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
|
|||
BASENAME contrast
|
||||
)
|
||||
|
||||
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
|
||||
PROTOCOL ${KWAYLAND_SOURCE_DIR}/src/client/protocols/relative-pointer-unstable-v1.xml
|
||||
BASENAME relativepointer-unstable-v1
|
||||
)
|
||||
|
||||
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
|
||||
PROTOCOL ${KWAYLAND_SOURCE_DIR}/src/client/protocols/slide.xml
|
||||
BASENAME slide
|
||||
|
@ -180,6 +187,7 @@ install(FILES
|
|||
plasmawindowmanagement_interface.h
|
||||
qtsurfaceextension_interface.h
|
||||
region_interface.h
|
||||
relativepointer_interface.h
|
||||
resource.h
|
||||
seat_interface.h
|
||||
server_decoration_interface.h
|
||||
|
|
|
@ -27,6 +27,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "../../src/client/registry.h"
|
||||
#include "../../src/client/output.h"
|
||||
#include "../../src/client/seat.h"
|
||||
#include "../../src/client/relativepointer.h"
|
||||
#include "../../src/client/server_decoration.h"
|
||||
#include "../../src/client/shell.h"
|
||||
#include "../../src/client/subcompositor.h"
|
||||
|
@ -47,6 +48,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "../../src/server/outputdevice_interface.h"
|
||||
#include "../../src/server/textinput_interface.h"
|
||||
#include "../../src/server/xdgshell_interface.h"
|
||||
#include "../../src/server/relativepointer_interface.h"
|
||||
// Wayland
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <wayland-dpms-client-protocol.h>
|
||||
|
@ -54,6 +56,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <wayland-text-input-v0-client-protocol.h>
|
||||
#include <wayland-text-input-v2-client-protocol.h>
|
||||
#include <wayland-xdg-shell-v5-client-protocol.h>
|
||||
#include <wayland-relativepointer-unstable-v1-client-protocol.h>
|
||||
|
||||
class TestWaylandRegistry : public QObject
|
||||
{
|
||||
|
@ -80,6 +83,7 @@ private Q_SLOTS:
|
|||
void testBindTextInputManagerUnstableV0();
|
||||
void testBindTextInputManagerUnstableV2();
|
||||
void testBindXdgShellUnstableV5();
|
||||
void testBindRelativePointerManagerUnstableV1();
|
||||
void testGlobalSync();
|
||||
void testGlobalSyncThreaded();
|
||||
void testRemoval();
|
||||
|
@ -101,6 +105,7 @@ private:
|
|||
KWayland::Server::TextInputManagerInterface *m_textInputManagerV0;
|
||||
KWayland::Server::TextInputManagerInterface *m_textInputManagerV2;
|
||||
KWayland::Server::XdgShellInterface *m_xdgShellUnstableV5;
|
||||
KWayland::Server::RelativePointerManagerInterface *m_relativePointerV1;
|
||||
};
|
||||
|
||||
static const QString s_socketName = QStringLiteral("kwin-test-wayland-registry-0");
|
||||
|
@ -120,6 +125,7 @@ TestWaylandRegistry::TestWaylandRegistry(QObject *parent)
|
|||
, m_textInputManagerV0(nullptr)
|
||||
, m_textInputManagerV2(nullptr)
|
||||
, m_xdgShellUnstableV5(nullptr)
|
||||
, m_relativePointerV1(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -161,6 +167,9 @@ void TestWaylandRegistry::init()
|
|||
m_xdgShellUnstableV5 = m_display->createXdgShell(KWayland::Server::XdgShellInterfaceVersion::UnstableV5);
|
||||
m_xdgShellUnstableV5->create();
|
||||
QCOMPARE(m_xdgShellUnstableV5->interfaceVersion(), KWayland::Server::XdgShellInterfaceVersion::UnstableV5);
|
||||
m_relativePointerV1 = m_display->createRelativePointerManager(KWayland::Server::RelativePointerInterfaceVersion::UnstableV1);
|
||||
m_relativePointerV1->create();
|
||||
QCOMPARE(m_relativePointerV1->interfaceVersion(), KWayland::Server::RelativePointerInterfaceVersion::UnstableV1);
|
||||
}
|
||||
|
||||
void TestWaylandRegistry::cleanup()
|
||||
|
@ -303,6 +312,11 @@ void TestWaylandRegistry::testBindXdgShellUnstableV5()
|
|||
TEST_BIND(KWayland::Client::Registry::Interface::XdgShellUnstableV5, SIGNAL(xdgShellUnstableV5Announced(quint32,quint32)), bindXdgShellUnstableV5, xdg_shell_destroy)
|
||||
}
|
||||
|
||||
void TestWaylandRegistry::testBindRelativePointerManagerUnstableV1()
|
||||
{
|
||||
TEST_BIND(KWayland::Client::Registry::Interface::RelativePointerManagerUnstableV1, SIGNAL(relativePointerManagerUnstableV1Announced(quint32,quint32)), bindRelativePointerManagerUnstableV1, zwp_relative_pointer_manager_v1_destroy)
|
||||
}
|
||||
|
||||
#undef TEST_BIND
|
||||
|
||||
void TestWaylandRegistry::testRemoval()
|
||||
|
|
|
@ -30,6 +30,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "../../src/client/pointer.h"
|
||||
#include "../../src/client/surface.h"
|
||||
#include "../../src/client/registry.h"
|
||||
#include "../../src/client/relativepointer.h"
|
||||
#include "../../src/client/seat.h"
|
||||
#include "../../src/client/shm_pool.h"
|
||||
#include "../../src/client/subcompositor.h"
|
||||
|
@ -41,6 +42,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "../../src/server/display.h"
|
||||
#include "../../src/server/keyboard_interface.h"
|
||||
#include "../../src/server/pointer_interface.h"
|
||||
#include "../../src/server/relativepointer_interface.h"
|
||||
#include "../../src/server/seat_interface.h"
|
||||
#include "../../src/server/subcompositor_interface.h"
|
||||
#include "../../src/server/surface_interface.h"
|
||||
|
@ -87,11 +89,13 @@ private:
|
|||
KWayland::Server::CompositorInterface *m_compositorInterface;
|
||||
KWayland::Server::SeatInterface *m_seatInterface;
|
||||
KWayland::Server::SubCompositorInterface *m_subCompositorInterface;
|
||||
KWayland::Server::RelativePointerManagerInterface *m_relativePointerManagerInterface;
|
||||
KWayland::Client::ConnectionThread *m_connection;
|
||||
KWayland::Client::Compositor *m_compositor;
|
||||
KWayland::Client::Seat *m_seat;
|
||||
KWayland::Client::ShmPool *m_shm;
|
||||
KWayland::Client::SubCompositor * m_subCompositor;
|
||||
KWayland::Client::RelativePointerManager *m_relativePointerManager;
|
||||
KWayland::Client::EventQueue *m_queue;
|
||||
QThread *m_thread;
|
||||
};
|
||||
|
@ -104,11 +108,13 @@ TestWaylandSeat::TestWaylandSeat(QObject *parent)
|
|||
, m_compositorInterface(nullptr)
|
||||
, m_seatInterface(nullptr)
|
||||
, m_subCompositorInterface(nullptr)
|
||||
, m_relativePointerManagerInterface(nullptr)
|
||||
, m_connection(nullptr)
|
||||
, m_compositor(nullptr)
|
||||
, m_seat(nullptr)
|
||||
, m_shm(nullptr)
|
||||
, m_subCompositor(nullptr)
|
||||
, m_relativePointerManager(nullptr)
|
||||
, m_queue(nullptr)
|
||||
, m_thread(nullptr)
|
||||
{
|
||||
|
@ -134,6 +140,11 @@ void TestWaylandSeat::init()
|
|||
m_subCompositorInterface->create();
|
||||
QVERIFY(m_subCompositorInterface->isValid());
|
||||
|
||||
m_relativePointerManagerInterface = m_display->createRelativePointerManager(RelativePointerInterfaceVersion::UnstableV1, m_display);
|
||||
QVERIFY(m_relativePointerManagerInterface);
|
||||
m_relativePointerManagerInterface->create();
|
||||
QVERIFY(m_relativePointerManagerInterface->isValid());
|
||||
|
||||
// setup connection
|
||||
m_connection = new KWayland::Client::ConnectionThread;
|
||||
QSignalSpy connectedSpy(m_connection, SIGNAL(connected()));
|
||||
|
@ -182,10 +193,19 @@ void TestWaylandSeat::init()
|
|||
registry.interface(KWayland::Client::Registry::Interface::SubCompositor).version,
|
||||
this);
|
||||
QVERIFY(m_subCompositor->isValid());
|
||||
|
||||
m_relativePointerManager = registry.createRelativePointerManager(registry.interface(KWayland::Client::Registry::Interface::RelativePointerManagerUnstableV1).name,
|
||||
registry.interface(KWayland::Client::Registry::Interface::RelativePointerManagerUnstableV1).version,
|
||||
this);
|
||||
QVERIFY(m_relativePointerManager->isValid());
|
||||
}
|
||||
|
||||
void TestWaylandSeat::cleanup()
|
||||
{
|
||||
if (m_relativePointerManager) {
|
||||
delete m_relativePointerManager;
|
||||
m_relativePointerManager = nullptr;
|
||||
}
|
||||
if (m_subCompositor) {
|
||||
delete m_subCompositor;
|
||||
m_subCompositor = nullptr;
|
||||
|
@ -226,6 +246,9 @@ void TestWaylandSeat::cleanup()
|
|||
delete m_subCompositorInterface;
|
||||
m_subCompositorInterface = nullptr;
|
||||
|
||||
delete m_relativePointerManagerInterface;
|
||||
m_relativePointerManagerInterface = nullptr;
|
||||
|
||||
delete m_display;
|
||||
m_display = nullptr;
|
||||
}
|
||||
|
@ -342,6 +365,8 @@ void TestWaylandSeat::testPointer()
|
|||
Pointer *p = m_seat->createPointer(m_seat);
|
||||
const Pointer &cp = *p;
|
||||
QVERIFY(p->isValid());
|
||||
QScopedPointer<RelativePointer> relativePointer(m_relativePointerManager->createRelativePointer(p));
|
||||
QVERIFY(relativePointer->isValid());
|
||||
QSignalSpy pointerCreatedSpy(m_seatInterface, SIGNAL(pointerCreated(KWayland::Server::PointerInterface*)));
|
||||
QVERIFY(pointerCreatedSpy.isValid());
|
||||
// once the pointer is created it should be set as the focused pointer
|
||||
|
@ -372,6 +397,9 @@ void TestWaylandSeat::testPointer()
|
|||
QSignalSpy buttonSpy(p, SIGNAL(buttonStateChanged(quint32,quint32,quint32,KWayland::Client::Pointer::ButtonState)));
|
||||
QVERIFY(buttonSpy.isValid());
|
||||
|
||||
QSignalSpy relativeMotionSpy(relativePointer.data(), &RelativePointer::relativeMotion);
|
||||
QVERIFY(relativeMotionSpy.isValid());
|
||||
|
||||
QVERIFY(!p->enteredSurface());
|
||||
QVERIFY(!cp.enteredSurface());
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface, QPoint(10, 15));
|
||||
|
@ -393,6 +421,14 @@ void TestWaylandSeat::testPointer()
|
|||
QCOMPARE(motionSpy.first().first().toPoint(), QPoint(0, 1));
|
||||
QCOMPARE(motionSpy.first().last().value<quint32>(), quint32(1));
|
||||
|
||||
// test relative motion
|
||||
m_seatInterface->relativePointerMotion(QSizeF(1, 2), QSizeF(3, 4), quint64(-1));
|
||||
QVERIFY(relativeMotionSpy.wait());
|
||||
QCOMPARE(relativeMotionSpy.count(), 1);
|
||||
QCOMPARE(relativeMotionSpy.first().at(0).toSizeF(), QSizeF(1, 2));
|
||||
QCOMPARE(relativeMotionSpy.first().at(1).toSizeF(), QSizeF(3, 4));
|
||||
QCOMPARE(relativeMotionSpy.first().at(2).value<quint64>(), quint64(-1));
|
||||
|
||||
// test axis
|
||||
m_seatInterface->setTimestamp(2);
|
||||
m_seatInterface->pointerAxis(Qt::Horizontal, 10);
|
||||
|
@ -460,6 +496,10 @@ void TestWaylandSeat::testPointer()
|
|||
QVERIFY(!p->enteredSurface());
|
||||
QVERIFY(!cp.enteredSurface());
|
||||
|
||||
// now a relative motion should not be sent to the relative pointer
|
||||
m_seatInterface->relativePointerMotion(QSizeF(1, 2), QSizeF(3, 4), quint64(-1));
|
||||
QVERIFY(!relativeMotionSpy.wait());
|
||||
|
||||
// enter it again
|
||||
m_seatInterface->setFocusedPointerSurface(serverSurface, QPoint(0, 0));
|
||||
QCOMPARE(focusedPointerChangedSpy.count(), 6);
|
||||
|
@ -467,6 +507,14 @@ void TestWaylandSeat::testPointer()
|
|||
QCOMPARE(p->enteredSurface(), s);
|
||||
QCOMPARE(cp.enteredSurface(), s);
|
||||
|
||||
// send another relative motion event
|
||||
m_seatInterface->relativePointerMotion(QSizeF(4, 5), QSizeF(6, 7), quint64(1));
|
||||
QVERIFY(relativeMotionSpy.wait());
|
||||
QCOMPARE(relativeMotionSpy.count(), 2);
|
||||
QCOMPARE(relativeMotionSpy.last().at(0).toSizeF(), QSizeF(4, 5));
|
||||
QCOMPARE(relativeMotionSpy.last().at(1).toSizeF(), QSizeF(6, 7));
|
||||
QCOMPARE(relativeMotionSpy.last().at(2).value<quint64>(), quint64(1));
|
||||
|
||||
// destroy the focused pointer
|
||||
QSignalSpy unboundSpy(serverPointer, &Resource::unbound);
|
||||
QVERIFY(unboundSpy.isValid());
|
||||
|
@ -1368,6 +1416,7 @@ void TestWaylandSeat::testDestroy()
|
|||
connect(m_connection, &ConnectionThread::connectionDied, m_seat, &Seat::destroy);
|
||||
connect(m_connection, &ConnectionThread::connectionDied, m_shm, &ShmPool::destroy);
|
||||
connect(m_connection, &ConnectionThread::connectionDied, m_subCompositor, &SubCompositor::destroy);
|
||||
connect(m_connection, &ConnectionThread::connectionDied, m_relativePointerManager, &RelativePointerManager::destroy);
|
||||
connect(m_connection, &ConnectionThread::connectionDied, m_queue, &EventQueue::destroy);
|
||||
QVERIFY(m_seat->isValid());
|
||||
|
||||
|
@ -1378,6 +1427,7 @@ void TestWaylandSeat::testDestroy()
|
|||
m_compositorInterface = nullptr;
|
||||
m_seatInterface = nullptr;
|
||||
m_subCompositorInterface = nullptr;
|
||||
m_relativePointerManagerInterface = nullptr;
|
||||
QVERIFY(connectionDiedSpy.wait());
|
||||
|
||||
// now the seat should be destroyed;
|
||||
|
|
|
@ -35,6 +35,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "shadow_interface.h"
|
||||
#include "blur_interface.h"
|
||||
#include "contrast_interface.h"
|
||||
#include "relativepointer_interface_p.h"
|
||||
#include "server_decoration_interface.h"
|
||||
#include "slide_interface.h"
|
||||
#include "shell_interface.h"
|
||||
|
@ -369,6 +370,18 @@ XdgShellInterface *Display::createXdgShell(const XdgShellInterfaceVersion &versi
|
|||
return x;
|
||||
}
|
||||
|
||||
RelativePointerManagerInterface *Display::createRelativePointerManager(const RelativePointerInterfaceVersion &version, QObject *parent)
|
||||
{
|
||||
RelativePointerManagerInterface *r = nullptr;
|
||||
switch (version) {
|
||||
case RelativePointerInterfaceVersion::UnstableV1:
|
||||
r = new RelativePointerManagerUnstableV1Interface(this, parent);
|
||||
break;
|
||||
}
|
||||
connect(this, &Display::aboutToTerminate, r, [r] { delete r; });
|
||||
return r;
|
||||
}
|
||||
|
||||
void Display::createShm()
|
||||
{
|
||||
Q_ASSERT(d->display);
|
||||
|
|
|
@ -74,6 +74,8 @@ class TextInputManagerInterface;
|
|||
class XdgShellV5Interface;
|
||||
enum class XdgShellInterfaceVersion;
|
||||
class XdgShellInterface;
|
||||
enum class RelativePointerInterfaceVersion;
|
||||
class RelativePointerManagerInterface;
|
||||
|
||||
/**
|
||||
* @brief Class holding the Wayland server display loop.
|
||||
|
@ -189,6 +191,14 @@ public:
|
|||
**/
|
||||
XdgShellInterface *createXdgShell(const XdgShellInterfaceVersion &version, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Creates the RelativePointerManagerInterface in interface @p version
|
||||
*
|
||||
* @returns The created manager object
|
||||
* @since 5.28
|
||||
**/
|
||||
RelativePointerManagerInterface *createRelativePointerManager(const RelativePointerInterfaceVersion &version, QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Gets the ClientConnection for the given @p client.
|
||||
* If there is no ClientConnection yet for the given @p client, it will be created.
|
||||
|
|
|
@ -20,6 +20,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "pointer_interface.h"
|
||||
#include "pointer_interface_p.h"
|
||||
#include "resource_p.h"
|
||||
#include "relativepointer_interface_p.h"
|
||||
#include "seat_interface.h"
|
||||
#include "display.h"
|
||||
#include "subcompositor_interface.h"
|
||||
|
@ -77,6 +78,16 @@ void PointerInterface::Private::sendLeave(SurfaceInterface *surface, quint32 ser
|
|||
}
|
||||
}
|
||||
|
||||
void PointerInterface::Private::registerRelativePointer(RelativePointerInterface *relativePointer)
|
||||
{
|
||||
relativePointers << relativePointer;
|
||||
QObject::connect(relativePointer, &QObject::destroyed, q,
|
||||
[this, relativePointer] {
|
||||
relativePointers.removeOne(relativePointer);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
namespace {
|
||||
static QPointF surfacePosition(SurfaceInterface *surface) {
|
||||
if (surface && surface->subSurface()) {
|
||||
|
@ -211,11 +222,28 @@ Cursor *PointerInterface::cursor() const
|
|||
return d->cursor;
|
||||
}
|
||||
|
||||
void PointerInterface::relativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds)
|
||||
{
|
||||
Q_D();
|
||||
if (d->relativePointers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (auto it = d->relativePointers.constBegin(), end = d->relativePointers.constEnd(); it != end; it++) {
|
||||
(*it)->relativeMotion(delta, deltaNonAccelerated, microseconds);
|
||||
}
|
||||
client()->flush();
|
||||
}
|
||||
|
||||
PointerInterface::Private *PointerInterface::d_func() const
|
||||
{
|
||||
return reinterpret_cast<Private*>(d.data());
|
||||
}
|
||||
|
||||
PointerInterface *PointerInterface::get(wl_resource *native)
|
||||
{
|
||||
return Private::get<PointerInterface>(native);
|
||||
}
|
||||
|
||||
Cursor::Private::Private(Cursor *q, PointerInterface *pointer)
|
||||
: pointer(pointer)
|
||||
, q(q)
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace Server
|
|||
{
|
||||
|
||||
class Cursor;
|
||||
class RelativePointerManagerUnstableV1Interface;
|
||||
class SeatInterface;
|
||||
class SurfaceInterface;
|
||||
|
||||
|
@ -55,6 +56,12 @@ public:
|
|||
**/
|
||||
Cursor *cursor() const;
|
||||
|
||||
/**
|
||||
* @returns The PointerInterface for the @p native resource.
|
||||
* @since 5.28
|
||||
**/
|
||||
static PointerInterface *get(wl_resource *native);
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* Signal emitted whenever the Cursor changes.
|
||||
|
@ -66,7 +73,9 @@ private:
|
|||
void buttonPressed(quint32 button, quint32 serial);
|
||||
void buttonReleased(quint32 button, quint32 serial);
|
||||
void axis(Qt::Orientation orientation, quint32 delta);
|
||||
void relativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds);
|
||||
friend class SeatInterface;
|
||||
friend class RelativePointerManagerUnstableV1Interface;
|
||||
explicit PointerInterface(SeatInterface *parent, wl_resource *parentResource);
|
||||
class Private;
|
||||
Private *d_func() const;
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace KWayland
|
|||
{
|
||||
namespace Server
|
||||
{
|
||||
class RelativePointerInterface;
|
||||
|
||||
class PointerInterface::Private : public Resource::Private
|
||||
{
|
||||
|
@ -39,10 +40,13 @@ public:
|
|||
QPointer<SurfaceInterface> focusedChildSurface;
|
||||
QMetaObject::Connection destroyConnection;
|
||||
Cursor *cursor = nullptr;
|
||||
QVector<RelativePointerInterface*> relativePointers;
|
||||
|
||||
void sendLeave(SurfaceInterface *surface, quint32 serial);
|
||||
void sendEnter(SurfaceInterface *surface, const QPointF &parentSurfacePosition, quint32 serial);
|
||||
|
||||
void registerRelativePointer(RelativePointerInterface *relativePointer);
|
||||
|
||||
private:
|
||||
PointerInterface *q_func() {
|
||||
return reinterpret_cast<PointerInterface *>(q);
|
||||
|
|
|
@ -846,6 +846,14 @@ quint32 SeatInterface::pointerButtonSerial(quint32 button) const
|
|||
return it.value();
|
||||
}
|
||||
|
||||
void SeatInterface::relativePointerMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds)
|
||||
{
|
||||
Q_D();
|
||||
if (d->globalPointer.focus.pointer && d->globalPointer.focus.surface) {
|
||||
d->globalPointer.focus.pointer->relativeMotion(delta, deltaNonAccelerated, microseconds);
|
||||
}
|
||||
}
|
||||
|
||||
void SeatInterface::keyPressed(quint32 key)
|
||||
{
|
||||
Q_D();
|
||||
|
|
|
@ -367,6 +367,42 @@ public:
|
|||
* @since 5.6
|
||||
**/
|
||||
bool hasImplicitPointerGrab(quint32 serial) const;
|
||||
|
||||
/**
|
||||
* A relative motion is in the same dimension as regular motion events,
|
||||
* except they do not represent an absolute position. For example,
|
||||
* moving a pointer from (x, y) to (x', y') would have the equivalent
|
||||
* relative motion (x' - x, y' - y). If a pointer motion caused the
|
||||
* absolute pointer position to be clipped by for example the edge of the
|
||||
* monitor, the relative motion is unaffected by the clipping and will
|
||||
* represent the unclipped motion.
|
||||
*
|
||||
* This method also contains non-accelerated motion deltas (@p deltaNonAccelerated).
|
||||
* The non-accelerated delta is, when applicable, the regular pointer motion
|
||||
* delta as it was before having applied motion acceleration and other
|
||||
* transformations such as normalization.
|
||||
*
|
||||
* Note that the non-accelerated delta does not represent 'raw' events as
|
||||
* they were read from some device. Pointer motion acceleration is device-
|
||||
* and configuration-specific and non-accelerated deltas and accelerated
|
||||
* deltas may have the same value on some devices.
|
||||
*
|
||||
* Relative motions are not coupled to wl_pointer.motion events (see @link{setPointerPos},
|
||||
* and can be sent in combination with such events, but also independently. There may
|
||||
* also be scenarios where wl_pointer.motion is sent, but there is no
|
||||
* relative motion. The order of an absolute and relative motion event
|
||||
* originating from the same physical motion is not guaranteed.
|
||||
*
|
||||
* Sending relative pointer events only makes sense if the RelativePointerManagerInterface
|
||||
* is created on the Display.
|
||||
*
|
||||
* @param delta Motion vector
|
||||
* @param deltaNonAccelerated non-accelerated motion vector
|
||||
* @param microseconds timestamp with microseconds granularity
|
||||
* @see setPointerPos
|
||||
* @since 5.28
|
||||
**/
|
||||
void relativePointerMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds);
|
||||
///@}
|
||||
|
||||
/**
|
||||
|
|
84
src/wayland/server/relativepointer_interface.cpp
Normal file
84
src/wayland/server/relativepointer_interface.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
/****************************************************************************
|
||||
Copyright 2016 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) version 3, or any
|
||||
later version accepted by the membership of KDE e.V. (or its
|
||||
successor approved by the membership of KDE e.V.), which shall
|
||||
act as a proxy defined in Section 6 of version 3 of the license.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "relativepointer_interface_p.h"
|
||||
|
||||
namespace KWayland
|
||||
{
|
||||
namespace Server
|
||||
{
|
||||
|
||||
RelativePointerManagerInterface::Private::Private(RelativePointerInterfaceVersion interfaceVersion, RelativePointerManagerInterface *q, Display *d, const wl_interface *interface, quint32 version)
|
||||
: Global::Private(d, interface, version)
|
||||
, interfaceVersion(interfaceVersion)
|
||||
, q(q)
|
||||
{
|
||||
}
|
||||
|
||||
RelativePointerManagerInterface::RelativePointerManagerInterface(Private *d, QObject *parent)
|
||||
: Global(d, parent)
|
||||
{
|
||||
}
|
||||
|
||||
RelativePointerManagerInterface::~RelativePointerManagerInterface() = default;
|
||||
|
||||
RelativePointerInterfaceVersion RelativePointerManagerInterface::interfaceVersion() const
|
||||
{
|
||||
Q_D();
|
||||
return d->interfaceVersion;
|
||||
}
|
||||
|
||||
RelativePointerManagerInterface::Private *RelativePointerManagerInterface::d_func() const
|
||||
{
|
||||
return reinterpret_cast<Private*>(d.data());
|
||||
}
|
||||
|
||||
RelativePointerInterface::Private::Private(RelativePointerInterface *q, Global *c, wl_resource *parentResource, const wl_interface *interface, const void *implementation)
|
||||
: Resource::Private(q, c, parentResource, interface, implementation)
|
||||
{
|
||||
}
|
||||
|
||||
RelativePointerInterface::Private::~Private()
|
||||
{
|
||||
if (resource) {
|
||||
wl_resource_destroy(resource);
|
||||
resource = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RelativePointerInterface::RelativePointerInterface(Private *p, QObject *parent)
|
||||
: Resource(p, parent)
|
||||
{
|
||||
}
|
||||
|
||||
RelativePointerInterface::~RelativePointerInterface() = default;
|
||||
|
||||
void RelativePointerInterface::relativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds)
|
||||
{
|
||||
Q_D();
|
||||
d->relativeMotion(delta, deltaNonAccelerated, microseconds);
|
||||
}
|
||||
|
||||
RelativePointerInterface::Private *RelativePointerInterface::d_func() const
|
||||
{
|
||||
return reinterpret_cast<Private*>(d.data());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
73
src/wayland/server/relativepointer_interface.h
Normal file
73
src/wayland/server/relativepointer_interface.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/****************************************************************************
|
||||
Copyright 2016 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) version 3, or any
|
||||
later version accepted by the membership of KDE e.V. (or its
|
||||
successor approved by the membership of KDE e.V.), which shall
|
||||
act as a proxy defined in Section 6 of version 3 of the license.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef KWAYLAND_SERVER_RELATIVE_POINTER_H
|
||||
#define KWAYLAND_SERVER_RELATIVE_POINTER_H
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#include <KWayland/Server/kwaylandserver_export.h>
|
||||
|
||||
namespace KWayland
|
||||
{
|
||||
namespace Server
|
||||
{
|
||||
|
||||
class Display;
|
||||
|
||||
enum class RelativePointerInterfaceVersion {
|
||||
/**
|
||||
* zwp_relative_pointer_manager_v1 and zwp_relative_pointer_v1
|
||||
**/
|
||||
UnstableV1
|
||||
};
|
||||
|
||||
/**
|
||||
* Manager object to create relative pointer interfaces.
|
||||
*
|
||||
* Once created the interaction happens through the SeatInterface class
|
||||
* which automatically delegates relative motion events to the created relative pointer
|
||||
* interfaces.
|
||||
*
|
||||
* @see SeatInterface::relativePointerMotion
|
||||
* @since 5.28
|
||||
**/
|
||||
class KWAYLANDSERVER_EXPORT RelativePointerManagerInterface : public Global
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual ~RelativePointerManagerInterface();
|
||||
|
||||
/**
|
||||
* @returns The interface version used by this RelativePointerManagerInterface
|
||||
**/
|
||||
RelativePointerInterfaceVersion interfaceVersion() const;
|
||||
|
||||
protected:
|
||||
class Private;
|
||||
explicit RelativePointerManagerInterface(Private *d, QObject *parent = nullptr);
|
||||
|
||||
private:
|
||||
Private *d_func() const;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
100
src/wayland/server/relativepointer_interface_p.h
Normal file
100
src/wayland/server/relativepointer_interface_p.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/****************************************************************************
|
||||
Copyright 2016 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) version 3, or any
|
||||
later version accepted by the membership of KDE e.V. (or its
|
||||
successor approved by the membership of KDE e.V.), which shall
|
||||
act as a proxy defined in Section 6 of version 3 of the license.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef KWAYLAND_SERVER_RELATIVEPOINTER_INTERFACE_P_H
|
||||
#define KWAYLAND_SERVER_RELATIVEPOINTER_INTERFACE_P_H
|
||||
#include "relativepointer_interface.h"
|
||||
#include "resource_p.h"
|
||||
#include "global_p.h"
|
||||
|
||||
|
||||
namespace KWayland
|
||||
{
|
||||
namespace Server
|
||||
{
|
||||
|
||||
class RelativePointerManagerInterface::Private : public Global::Private
|
||||
{
|
||||
public:
|
||||
RelativePointerInterfaceVersion interfaceVersion;
|
||||
|
||||
protected:
|
||||
Private(RelativePointerInterfaceVersion interfaceVersion, RelativePointerManagerInterface *q, Display *d, const wl_interface *interface, quint32 version);
|
||||
RelativePointerManagerInterface *q;
|
||||
};
|
||||
|
||||
class RelativePointerManagerUnstableV1Interface : public RelativePointerManagerInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RelativePointerManagerUnstableV1Interface(Display *display, QObject *parent = nullptr);
|
||||
virtual ~RelativePointerManagerUnstableV1Interface();
|
||||
|
||||
private:
|
||||
class Private;
|
||||
};
|
||||
|
||||
class RelativePointerInterface : public Resource
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual ~RelativePointerInterface();
|
||||
void relativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds);
|
||||
|
||||
protected:
|
||||
class Private;
|
||||
explicit RelativePointerInterface(Private *p, QObject *parent = nullptr);
|
||||
|
||||
private:
|
||||
Private *d_func() const;
|
||||
};
|
||||
|
||||
class RelativePointerInterface::Private : public Resource::Private
|
||||
{
|
||||
public:
|
||||
~Private();
|
||||
virtual void relativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds) = 0;
|
||||
|
||||
protected:
|
||||
Private(RelativePointerInterface *q, Global *c, wl_resource *parentResource, const wl_interface *interface, const void *implementation);
|
||||
|
||||
private:
|
||||
RelativePointerInterface *q_func() {
|
||||
return reinterpret_cast<RelativePointerInterface *>(q);
|
||||
}
|
||||
};
|
||||
|
||||
class RelativePointerUnstableV1Interface : public RelativePointerInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual ~RelativePointerUnstableV1Interface();
|
||||
|
||||
private:
|
||||
explicit RelativePointerUnstableV1Interface(RelativePointerManagerUnstableV1Interface *parent, wl_resource *parentResource);
|
||||
friend class RelativePointerManagerUnstableV1Interface;
|
||||
|
||||
class Private;
|
||||
Private *d_func() const;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
160
src/wayland/server/relativepointer_interface_v1.cpp
Normal file
160
src/wayland/server/relativepointer_interface_v1.cpp
Normal file
|
@ -0,0 +1,160 @@
|
|||
/****************************************************************************
|
||||
Copyright 2016 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) version 3, or any
|
||||
later version accepted by the membership of KDE e.V. (or its
|
||||
successor approved by the membership of KDE e.V.), which shall
|
||||
act as a proxy defined in Section 6 of version 3 of the license.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "relativepointer_interface_p.h"
|
||||
#include "display.h"
|
||||
#include "pointer_interface_p.h"
|
||||
#include <wayland-relativepointer-unstable-v1-server-protocol.h>
|
||||
#include <QSizeF>
|
||||
|
||||
namespace KWayland
|
||||
{
|
||||
namespace Server
|
||||
{
|
||||
|
||||
class RelativePointerManagerUnstableV1Interface::Private : public RelativePointerManagerInterface::Private
|
||||
{
|
||||
public:
|
||||
Private(RelativePointerManagerUnstableV1Interface *q, Display *d);
|
||||
|
||||
private:
|
||||
void bind(wl_client *client, uint32_t version, uint32_t id) override;
|
||||
|
||||
static void unbind(wl_resource *resource);
|
||||
static Private *cast(wl_resource *r) {
|
||||
return reinterpret_cast<Private*>(wl_resource_get_user_data(r));
|
||||
}
|
||||
|
||||
static void destroyCallback(wl_client *client, wl_resource *resource);
|
||||
static void getRelativePointerCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * pointer);
|
||||
|
||||
RelativePointerManagerUnstableV1Interface *q;
|
||||
|
||||
static const struct zwp_relative_pointer_manager_v1_interface s_interface;
|
||||
static const quint32 s_version;
|
||||
};
|
||||
|
||||
const quint32 RelativePointerManagerUnstableV1Interface::Private::s_version = 1;
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
const struct zwp_relative_pointer_manager_v1_interface RelativePointerManagerUnstableV1Interface::Private::s_interface = {
|
||||
destroyCallback,
|
||||
getRelativePointerCallback
|
||||
};
|
||||
#endif
|
||||
|
||||
void RelativePointerManagerUnstableV1Interface::Private::destroyCallback(wl_client *client, wl_resource *resource)
|
||||
{
|
||||
Q_UNUSED(client)
|
||||
wl_resource_destroy(resource);
|
||||
}
|
||||
|
||||
void RelativePointerManagerUnstableV1Interface::Private::getRelativePointerCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource *pointer)
|
||||
{
|
||||
PointerInterface *p = PointerInterface::get(pointer);
|
||||
if (!p) {
|
||||
// TODO: raise error?
|
||||
return;
|
||||
}
|
||||
auto m = cast(resource);
|
||||
auto *r = new RelativePointerUnstableV1Interface(m->q, resource);
|
||||
r->d->create(m->display->getConnection(client), version, id);
|
||||
p->d_func()->registerRelativePointer(r);
|
||||
}
|
||||
|
||||
RelativePointerManagerUnstableV1Interface::Private::Private(RelativePointerManagerUnstableV1Interface *q, Display *d)
|
||||
: RelativePointerManagerInterface::Private(RelativePointerInterfaceVersion::UnstableV1, q, d, &zwp_relative_pointer_manager_v1_interface, s_version)
|
||||
, q(q)
|
||||
{
|
||||
}
|
||||
|
||||
void RelativePointerManagerUnstableV1Interface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
|
||||
{
|
||||
auto c = display->getConnection(client);
|
||||
wl_resource *resource = c->createResource(&zwp_relative_pointer_manager_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 RelativePointerManagerUnstableV1Interface::Private::unbind(wl_resource *resource)
|
||||
{
|
||||
Q_UNUSED(resource)
|
||||
// TODO: implement?
|
||||
}
|
||||
|
||||
RelativePointerManagerUnstableV1Interface::RelativePointerManagerUnstableV1Interface(Display *display, QObject *parent)
|
||||
: RelativePointerManagerInterface(new Private(this, display), parent)
|
||||
{
|
||||
}
|
||||
|
||||
RelativePointerManagerUnstableV1Interface::~RelativePointerManagerUnstableV1Interface() = default;
|
||||
|
||||
class RelativePointerUnstableV1Interface::Private : public RelativePointerInterface::Private
|
||||
{
|
||||
public:
|
||||
Private(RelativePointerUnstableV1Interface *q, RelativePointerManagerUnstableV1Interface *c, wl_resource *parentResource);
|
||||
~Private();
|
||||
void relativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds) override;
|
||||
|
||||
private:
|
||||
RelativePointerUnstableV1Interface *q_func() {
|
||||
return reinterpret_cast<RelativePointerUnstableV1Interface *>(q);
|
||||
}
|
||||
|
||||
static const struct zwp_relative_pointer_v1_interface s_interface;
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
const struct zwp_relative_pointer_v1_interface RelativePointerUnstableV1Interface::Private::s_interface = {
|
||||
resourceDestroyedCallback
|
||||
};
|
||||
#endif
|
||||
|
||||
RelativePointerUnstableV1Interface::Private::Private(RelativePointerUnstableV1Interface *q, RelativePointerManagerUnstableV1Interface *c, wl_resource *parentResource)
|
||||
: RelativePointerInterface::Private(q, c, parentResource, &zwp_relative_pointer_v1_interface, &s_interface)
|
||||
{
|
||||
}
|
||||
|
||||
RelativePointerUnstableV1Interface::Private::~Private() = default;
|
||||
|
||||
void RelativePointerUnstableV1Interface::Private::relativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds)
|
||||
{
|
||||
if (!resource) {
|
||||
return;
|
||||
}
|
||||
zwp_relative_pointer_v1_send_relative_motion(resource, (microseconds >> 32), microseconds,
|
||||
wl_fixed_from_double(delta.width()),
|
||||
wl_fixed_from_double(delta.height()),
|
||||
wl_fixed_from_double(deltaNonAccelerated.width()),
|
||||
wl_fixed_from_double(deltaNonAccelerated.height()));
|
||||
}
|
||||
|
||||
RelativePointerUnstableV1Interface::RelativePointerUnstableV1Interface(RelativePointerManagerUnstableV1Interface *parent, wl_resource *parentResource)
|
||||
: RelativePointerInterface(new Private(this, parent, parentResource))
|
||||
{
|
||||
}
|
||||
|
||||
RelativePointerUnstableV1Interface::~RelativePointerUnstableV1Interface() = default;
|
||||
|
||||
}
|
||||
}
|
|
@ -47,3 +47,5 @@ zwp_text_input_manager_v2;TextInputManagerUnstableV2
|
|||
xdg_shell;XdgShellV5
|
||||
xdg_surface;XdgSurfaceV5
|
||||
xdg_popup;XdgPopupV5
|
||||
zwp_relative_pointer_manager_v1;RelativePointerManagerUnstableV1
|
||||
zwp_relative_pointer_v1;RelativePointerUnstableV1
|
||||
|
|
Loading…
Reference in a new issue