diff --git a/platform.h b/platform.h --- a/platform.h +++ b/platform.h @@ -303,6 +303,15 @@ void touchCancel(); void touchFrame(); + void processSwipeGestureBegin(int fingerCount, quint32 time); + void processSwipeGestureUpdate(const QSizeF &delta, quint32 time); + void processSwipeGestureEnd(quint32 time); + void processSwipeGestureCancelled(quint32 time); + void processPinchGestureBegin(int fingerCount, quint32 time); + void processPinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time); + void processPinchGestureEnd(quint32 time); + void processPinchGestureCancelled(quint32 time); + Q_SIGNALS: void screensQueried(); void initFailed(); diff --git a/platform.cpp b/platform.cpp --- a/platform.cpp +++ b/platform.cpp @@ -261,6 +261,70 @@ input()->processTouchUp(id, time); } +void Platform::processSwipeGestureBegin(int fingerCount, quint32 time) +{ + if (!input()) { + return; + } + input()->pointer()->processSwipeGestureBegin(fingerCount, time); +} + +void Platform::processSwipeGestureUpdate(const QSizeF &delta, quint32 time) +{ + if (!input()) { + return; + } + input()->pointer()->processSwipeGestureUpdate(delta, time); +} + +void Platform::processSwipeGestureEnd(quint32 time) +{ + if (!input()) { + return; + } + input()->pointer()->processSwipeGestureEnd(time); +} + +void Platform::processSwipeGestureCancelled(quint32 time) +{ + if (!input()) { + return; + } + input()->pointer()->processSwipeGestureCancelled(time); +} + +void Platform::processPinchGestureBegin(int fingerCount, quint32 time) +{ + if (!input()) { + return; + } + input()->pointer()->processPinchGestureBegin(fingerCount, time); +} + +void Platform::processPinchGestureUpdate(qreal scale, qreal angleDelta, const QSizeF &delta, quint32 time) +{ + if (!input()) { + return; + } + input()->pointer()->processPinchGestureUpdate(scale, angleDelta, delta, time); +} + +void Platform::processPinchGestureEnd(quint32 time) +{ + if (!input()) { + return; + } + input()->pointer()->processPinchGestureEnd(time); +} + +void Platform::processPinchGestureCancelled(quint32 time) +{ + if (!input()) { + return; + } + input()->pointer()->processPinchGestureCancelled(time); +} + void Platform::repaint(const QRect &rect) { if (!Compositor::self()) { diff --git a/plugins/platforms/wayland/wayland_backend.h b/plugins/platforms/wayland/wayland_backend.h --- a/plugins/platforms/wayland/wayland_backend.h +++ b/plugins/platforms/wayland/wayland_backend.h @@ -49,6 +49,9 @@ class Keyboard; class Pointer; class PointerConstraints; +class PointerGestures; +class PointerSwipeGesture; +class PointerPinchGesture; class Registry; class Seat; class Shell; @@ -88,15 +91,24 @@ return m_pointer; } + void installGesturesInterface(KWayland::Client::PointerGestures *gesturesInterface) { + m_gesturesInterface = gesturesInterface; + setupPointerGestures(); + } + private: void destroyPointer(); void destroyKeyboard(); void destroyTouch(); + void setupPointerGestures(); KWayland::Client::Seat *m_seat; KWayland::Client::Pointer *m_pointer; KWayland::Client::Keyboard *m_keyboard; KWayland::Client::Touch *m_touch; KWayland::Client::Surface *m_cursor; + KWayland::Client::PointerGestures *m_gesturesInterface = nullptr; + KWayland::Client::PointerPinchGesture *m_pinchGesture = nullptr; + KWayland::Client::PointerSwipeGesture *m_swipeGesture = nullptr; uint32_t m_enteredSerial; WaylandBackend *m_backend; bool m_installCursor; diff --git a/plugins/platforms/wayland/wayland_backend.cpp b/plugins/platforms/wayland/wayland_backend.cpp --- a/plugins/platforms/wayland/wayland_backend.cpp +++ b/plugins/platforms/wayland/wayland_backend.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -120,6 +121,7 @@ [this](bool hasPointer) { if (hasPointer && !m_pointer) { m_pointer = m_seat->createPointer(this); + setupPointerGestures(); connect(m_pointer, &Pointer::entered, this, [this](quint32 serial) { m_enteredSerial = serial; @@ -219,6 +221,10 @@ void WaylandSeat::destroyPointer() { + delete m_pinchGesture; + m_pinchGesture = nullptr; + delete m_swipeGesture; + m_swipeGesture = nullptr; delete m_pointer; m_pointer = nullptr; } @@ -271,6 +277,61 @@ m_installCursor = install; } +void WaylandSeat::setupPointerGestures() +{ + if (!m_pointer || !m_gesturesInterface) { + return; + } + if (m_pinchGesture || m_swipeGesture) { + return; + } + m_pinchGesture = m_gesturesInterface->createPinchGesture(m_pointer, this); + m_swipeGesture = m_gesturesInterface->createSwipeGesture(m_pointer, this); + connect(m_pinchGesture, &PointerPinchGesture::started, m_backend, + [this] (quint32 serial, quint32 time) { + Q_UNUSED(serial); + m_backend->processPinchGestureBegin(m_pinchGesture->fingerCount(), time); + } + ); + connect(m_pinchGesture, &PointerPinchGesture::updated, m_backend, + [this] (const QSizeF &delta, qreal scale, qreal rotation, quint32 time) { + m_backend->processPinchGestureUpdate(scale, rotation, delta, time); + } + ); + connect(m_pinchGesture, &PointerPinchGesture::ended, m_backend, + [this] (quint32 serial, quint32 time) { + Q_UNUSED(serial) + m_backend->processPinchGestureEnd(time); + } + ); + connect(m_pinchGesture, &PointerPinchGesture::cancelled, m_backend, + [this] (quint32 serial, quint32 time) { + Q_UNUSED(serial) + m_backend->processPinchGestureCancelled(time); + } + ); + + connect(m_swipeGesture, &PointerSwipeGesture::started, m_backend, + [this] (quint32 serial, quint32 time) { + Q_UNUSED(serial) + m_backend->processSwipeGestureBegin(m_swipeGesture->fingerCount(), time); + } + ); + connect(m_swipeGesture, &PointerSwipeGesture::updated, m_backend, &Platform::processSwipeGestureUpdate); + connect(m_swipeGesture, &PointerSwipeGesture::ended, m_backend, + [this] (quint32 serial, quint32 time) { + Q_UNUSED(serial) + m_backend->processSwipeGestureEnd(time); + } + ); + connect(m_swipeGesture, &PointerSwipeGesture::cancelled, m_backend, + [this] (quint32 serial, quint32 time) { + Q_UNUSED(serial) + m_backend->processSwipeGestureCancelled(time); + } + ); +} + WaylandBackend::WaylandBackend(QObject *parent) : Platform(parent) , m_display(nullptr) @@ -355,6 +416,19 @@ } ); connect(m_registry, &Registry::interfacesAnnounced, this, &WaylandBackend::createSurface); + connect(m_registry, &Registry::interfacesAnnounced, this, + [this] { + if (!m_seat) { + return; + } + const auto gi = m_registry->interface(Registry::Interface::PointerGesturesUnstableV1); + if (gi.name == 0) { + return; + } + auto gesturesInterface = m_registry->createPointerGestures(gi.name, gi.version, m_seat.data()); + m_seat->installGesturesInterface(gesturesInterface); + } + ); if (!deviceIdentifier().isEmpty()) { m_connectionThreadObject->setSocketName(deviceIdentifier()); }