File indexing completed on 2024-11-10 04:58:09

0001 /*
0002     SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include <QGuiApplication>
0008 #include <QQuickItem>
0009 #include <QQuickView>
0010 
0011 #include <KWayland/Client/connection_thread.h>
0012 #include <KWayland/Client/pointer.h>
0013 #include <KWayland/Client/pointergestures.h>
0014 #include <KWayland/Client/registry.h>
0015 #include <KWayland/Client/seat.h>
0016 
0017 using namespace KWayland::Client;
0018 
0019 class PinchGesture : public QQuickItem
0020 {
0021     Q_OBJECT
0022     Q_PROPERTY(qreal scale READ scale NOTIFY scaleChanged)
0023     Q_PROPERTY(qreal progressScale READ progressScale NOTIFY progressScaleChanged)
0024 
0025 public:
0026     explicit PinchGesture(QQuickItem *parent = nullptr);
0027     ~PinchGesture() override;
0028 
0029     qreal scale() const
0030     {
0031         return m_scale;
0032     }
0033 
0034     qreal progressScale() const
0035     {
0036         return m_progressScale;
0037     }
0038 
0039 protected:
0040     void componentComplete() override;
0041 
0042 Q_SIGNALS:
0043     void progressScaleChanged();
0044 
0045 private:
0046     void initWayland();
0047     void setupGesture();
0048 
0049     Pointer *m_pointer = nullptr;
0050     PointerGestures *m_pointerGestures = nullptr;
0051     PointerPinchGesture *m_gesture = nullptr;
0052 
0053     qreal m_scale = 1.0;
0054     qreal m_progressScale = 1.0;
0055 };
0056 
0057 PinchGesture::PinchGesture(QQuickItem *parent)
0058     : QQuickItem(parent)
0059 {
0060 }
0061 
0062 PinchGesture::~PinchGesture() = default;
0063 
0064 void PinchGesture::componentComplete()
0065 {
0066     QQuickItem::componentComplete();
0067     initWayland();
0068 }
0069 
0070 void PinchGesture::initWayland()
0071 {
0072     auto c = ConnectionThread::fromApplication(this);
0073     Registry *r = new Registry(c);
0074     r->create(c);
0075 
0076     connect(r, &Registry::interfacesAnnounced, this,
0077             [this, r] {
0078                 const auto gi = r->interface(Registry::Interface::PointerGesturesUnstableV1);
0079                 if (gi.name == 0) {
0080                     return;
0081                 }
0082                 m_pointerGestures = r->createPointerGestures(gi.name, gi.version, this);
0083 
0084                 // now create seat
0085                 const auto si = r->interface(Registry::Interface::Seat);
0086                 if (si.name == 0) {
0087                     return;
0088                 }
0089                 auto seat = r->createSeat(si.name, si.version, this);
0090                 connect(seat, &Seat::hasKeyboardChanged, this,
0091                         [this, seat](bool hasPointer) {
0092                             if (hasPointer) {
0093                                 m_pointer = seat->createPointer(this);
0094                                 setupGesture();
0095                             } else {
0096                                 delete m_pointer;
0097                                 delete m_gesture;
0098                                 m_pointer = nullptr;
0099                                 m_gesture = nullptr;
0100                             }
0101                         });
0102             });
0103 
0104     r->setup();
0105     c->roundtrip();
0106 }
0107 
0108 void PinchGesture::setupGesture()
0109 {
0110     if (m_gesture || !m_pointerGestures || !m_pointer) {
0111         return;
0112     }
0113     m_gesture = m_pointerGestures->createPinchGesture(m_pointer, this);
0114     connect(m_gesture, &PointerPinchGesture::updated, this,
0115             [this](const QSizeF &delta, qreal scale) {
0116                 m_progressScale = scale;
0117                 Q_EMIT progressScaleChanged();
0118             });
0119     connect(m_gesture, &PointerPinchGesture::ended, this,
0120             [this] {
0121                 m_scale = m_scale * m_progressScale;
0122                 m_progressScale = 1.0;
0123                 Q_EMIT scaleChanged();
0124                 Q_EMIT progressScaleChanged();
0125             });
0126     connect(m_gesture, &PointerPinchGesture::cancelled, this,
0127             [this] {
0128                 m_progressScale = 1.0;
0129                 Q_EMIT progressScaleChanged();
0130             });
0131 }
0132 
0133 int main(int argc, char *argv[])
0134 {
0135     qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("wayland"));
0136     QGuiApplication app(argc, argv);
0137 
0138     qmlRegisterType<PinchGesture>("org.kde.kwin.tests", 1, 0, "PinchGesture");
0139 
0140     QQuickView view;
0141     view.setSource(QUrl::fromLocalFile(QStringLiteral(DIR) + QStringLiteral("/pointergesturestest.qml")));
0142 
0143     view.show();
0144 
0145     return app.exec();
0146 }
0147 
0148 #include "pointergesturestest.moc"