File indexing completed on 2024-09-15 12:58:36
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2017 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #pragma once 0010 0011 #include <kwin_export.h> 0012 0013 #include <QMap> 0014 #include <QObject> 0015 #include <QPointF> 0016 #include <QVector> 0017 0018 namespace KWin 0019 { 0020 /* 0021 * Everytime the scale of the gesture changes by this much, the callback changes by 1. 0022 * This is the amount of change for 1 unit of change, like switch by 1 desktop. 0023 * */ 0024 static const qreal DEFAULT_UNIT_SCALE_DELTA = .2; // 20% 0025 0026 class Gesture : public QObject 0027 { 0028 Q_OBJECT 0029 public: 0030 ~Gesture() override; 0031 0032 protected: 0033 explicit Gesture(QObject *parent); 0034 0035 Q_SIGNALS: 0036 /** 0037 * Matching of a gesture started and this Gesture might match. 0038 * On further evaluation either the signal @ref triggered or 0039 * @ref cancelled will get emitted. 0040 */ 0041 void started(); 0042 /** 0043 * Gesture matching ended and this Gesture matched. 0044 */ 0045 void triggered(); 0046 /** 0047 * This Gesture no longer matches. 0048 */ 0049 void cancelled(); 0050 }; 0051 0052 class SwipeGesture : public Gesture 0053 { 0054 Q_OBJECT 0055 public: 0056 enum class Direction { 0057 Down, 0058 Left, 0059 Up, 0060 Right, 0061 }; 0062 0063 explicit SwipeGesture(QObject *parent = nullptr); 0064 ~SwipeGesture() override; 0065 0066 bool minimumFingerCountIsRelevant() const; 0067 void setMinimumFingerCount(uint count); 0068 uint minimumFingerCount() const; 0069 0070 bool maximumFingerCountIsRelevant() const; 0071 void setMaximumFingerCount(uint count); 0072 uint maximumFingerCount() const; 0073 0074 Direction direction() const; 0075 void setDirection(Direction direction); 0076 0077 void setMinimumX(int x); 0078 int minimumX() const; 0079 bool minimumXIsRelevant() const; 0080 void setMinimumY(int y); 0081 int minimumY() const; 0082 bool minimumYIsRelevant() const; 0083 0084 void setMaximumX(int x); 0085 int maximumX() const; 0086 bool maximumXIsRelevant() const; 0087 void setMaximumY(int y); 0088 int maximumY() const; 0089 bool maximumYIsRelevant() const; 0090 void setStartGeometry(const QRect &geometry); 0091 0092 QPointF minimumDelta() const; 0093 void setMinimumDelta(const QPointF &delta); 0094 bool isMinimumDeltaRelevant() const; 0095 0096 qreal deltaToProgress(const QPointF &delta) const; 0097 bool minimumDeltaReached(const QPointF &delta) const; 0098 0099 Q_SIGNALS: 0100 /** 0101 * The progress of the gesture if a minimumDelta is set. 0102 * The progress is reported in [0.0,1.0] 0103 */ 0104 void progress(qreal); 0105 0106 /** 0107 * The progress in actual pixel distance traveled by the fingers 0108 */ 0109 void deltaProgress(const QPointF &delta); 0110 0111 private: 0112 bool m_minimumFingerCountRelevant = false; 0113 uint m_minimumFingerCount = 0; 0114 bool m_maximumFingerCountRelevant = false; 0115 uint m_maximumFingerCount = 0; 0116 Direction m_direction = Direction::Down; 0117 bool m_minimumXRelevant = false; 0118 int m_minimumX = 0; 0119 bool m_minimumYRelevant = false; 0120 int m_minimumY = 0; 0121 bool m_maximumXRelevant = false; 0122 int m_maximumX = 0; 0123 bool m_maximumYRelevant = false; 0124 int m_maximumY = 0; 0125 bool m_minimumDeltaRelevant = false; 0126 QPointF m_minimumDelta; 0127 }; 0128 0129 class PinchGesture : public Gesture 0130 { 0131 Q_OBJECT 0132 public: 0133 enum class Direction { 0134 Expanding, 0135 Contracting, 0136 }; 0137 0138 explicit PinchGesture(QObject *parent = nullptr); 0139 ~PinchGesture() override; 0140 0141 bool minimumFingerCountIsRelevant() const; 0142 void setMinimumFingerCount(uint count); 0143 uint minimumFingerCount() const; 0144 0145 bool maximumFingerCountIsRelevant() const; 0146 void setMaximumFingerCount(uint count); 0147 uint maximumFingerCount() const; 0148 0149 Direction direction() const; 0150 void setDirection(Direction direction); 0151 0152 qreal minimumScaleDelta() const; 0153 0154 /** 0155 * scaleDelta is the % scale difference needed to trigger 0156 * 0.25 will trigger when scale reaches 0.75 or 1.25 0157 */ 0158 void setMinimumScaleDelta(const qreal &scaleDelta); 0159 bool isMinimumScaleDeltaRelevant() const; 0160 0161 qreal scaleDeltaToProgress(const qreal &scaleDelta) const; 0162 bool minimumScaleDeltaReached(const qreal &scaleDelta) const; 0163 0164 Q_SIGNALS: 0165 /** 0166 * The progress of the gesture if a minimumDelta is set. 0167 * The progress is reported in [0.0,1.0] 0168 */ 0169 void progress(qreal); 0170 0171 private: 0172 bool m_minimumFingerCountRelevant = false; 0173 uint m_minimumFingerCount = 0; 0174 bool m_maximumFingerCountRelevant = false; 0175 uint m_maximumFingerCount = 0; 0176 Direction m_direction = Direction::Expanding; 0177 bool m_minimumScaleDeltaRelevant = false; 0178 qreal m_minimumScaleDelta = DEFAULT_UNIT_SCALE_DELTA; 0179 }; 0180 0181 class KWIN_EXPORT GestureRecognizer : public QObject 0182 { 0183 Q_OBJECT 0184 public: 0185 GestureRecognizer(QObject *parent = nullptr); 0186 ~GestureRecognizer() override; 0187 0188 void registerSwipeGesture(SwipeGesture *gesture); 0189 void unregisterSwipeGesture(SwipeGesture *gesture); 0190 void registerPinchGesture(PinchGesture *gesture); 0191 void unregisterPinchGesture(PinchGesture *gesture); 0192 0193 int startSwipeGesture(uint fingerCount); 0194 int startSwipeGesture(const QPointF &startPos); 0195 0196 void updateSwipeGesture(const QPointF &delta); 0197 void cancelSwipeGesture(); 0198 void endSwipeGesture(); 0199 0200 int startPinchGesture(uint fingerCount); 0201 void updatePinchGesture(qreal scale, qreal angleDelta, const QPointF &posDelta); 0202 void cancelPinchGesture(); 0203 void endPinchGesture(); 0204 0205 private: 0206 void cancelActiveGestures(); 0207 enum class StartPositionBehavior { 0208 Relevant, 0209 Irrelevant, 0210 }; 0211 enum class Axis { 0212 Horizontal, 0213 Vertical, 0214 None, 0215 }; 0216 int startSwipeGesture(uint fingerCount, const QPointF &startPos, StartPositionBehavior startPosBehavior); 0217 QVector<SwipeGesture *> m_swipeGestures; 0218 QVector<PinchGesture *> m_pinchGestures; 0219 QVector<SwipeGesture *> m_activeSwipeGestures; 0220 QVector<PinchGesture *> m_activePinchGestures; 0221 QMap<Gesture *, QMetaObject::Connection> m_destroyConnections; 0222 0223 QPointF m_currentDelta = QPointF(0, 0); 0224 qreal m_currentScale = 1; // For Pinch Gesture recognition 0225 uint m_currentFingerCount = 0; 0226 Axis m_currentSwipeAxis = Axis::None; 0227 }; 0228 0229 } 0230 0231 Q_DECLARE_METATYPE(KWin::SwipeGesture::Direction) 0232 Q_DECLARE_METATYPE(KWin::PinchGesture::Direction)