Merge gesture structs/enums

- Now only 1 GestureDirection enum
- Now only 1 registerGesture() call
- The 4 kinds of gesture (Pinch/Swipe) and (Touchpad/Touchscreen) in globalshortcuts.h/cpp are merged into 1 GestureShortcut
- Change from range to set of finger counts in gestures

No behavior should change, just a refactor.
This commit is contained in:
Eric Edlund 2022-07-03 20:09:23 -04:00
parent fe1f720307
commit d29c7a6c2b
19 changed files with 275 additions and 752 deletions

View file

@ -24,6 +24,7 @@ set(testVirtualDesktops_SRCS
add_executable(testVirtualDesktops ${testVirtualDesktops_SRCS})
target_link_libraries(testVirtualDesktops
kwineffects
kwin
Qt::Test
@ -169,6 +170,7 @@ set(testGestures_SRCS
add_executable(testGestures ${testGestures_SRCS})
target_link_libraries(testGestures
kwineffects
Qt::Test
)

View file

@ -378,7 +378,7 @@ void TouchInputTest::testGestureDetection()
qWarning() << "progress callback!" << progress;
};
QAction action;
input()->forceRegisterTouchscreenSwipeShortcut(SwipeDirection::Right, 3, &action, callback);
input()->forceRegisterTouchscreenSwipeShortcut(GestureDirection::Right, 3, &action, callback);
// verify that gestures are detected

View file

@ -19,16 +19,6 @@ class GestureTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testSwipeMinFinger_data();
void testSwipeMinFinger();
void testPinchMinFinger_data();
void testPinchMinFinger();
void testSwipeMaxFinger_data();
void testSwipeMaxFinger();
void testPinchMaxFinger_data();
void testPinchMaxFinger();
void testSwipeDirection_data();
void testSwipeDirection();
void testPinchDirection_data();
@ -46,10 +36,6 @@ private Q_SLOTS:
void testStartGeometry();
// swipe and pinch
void testSetMinimumDelta();
void testMinimumDeltaReached_data();
void testMinimumDeltaReached();
void testMinimumScaleDelta();
void testUnregisterSwipeCancels();
void testUnregisterPinchCancels();
void testDeleteSwipeCancels();
@ -59,10 +45,8 @@ private Q_SLOTS:
void testSwipeUpdateTrigger();
// both
void testSwipeMinFingerStart_data();
void testSwipeMinFingerStart();
void testSwipeMaxFingerStart_data();
void testSwipeMaxFingerStart();
void testSwipeFingerCount_data();
void testSwipeFingerCount();
void testNotEmitCallbacksBeforeDirectionDecided();
// swipe only
@ -70,142 +54,46 @@ private Q_SLOTS:
void testSwipeGeometryStart();
};
void GestureTest::testSwipeMinFinger_data()
{
QTest::addColumn<uint>("count");
QTest::addColumn<uint>("expectedCount");
QTest::newRow("0") << 0u << 0u;
QTest::newRow("1") << 1u << 1u;
QTest::newRow("10") << 10u << 10u;
}
void GestureTest::testSwipeMinFinger()
{
SwipeGesture swipeGesture;
QCOMPARE(swipeGesture.minimumFingerCountIsRelevant(), false);
QCOMPARE(swipeGesture.minimumFingerCount(), 0u);
QFETCH(uint, count);
swipeGesture.setMinimumFingerCount(count);
QCOMPARE(swipeGesture.minimumFingerCountIsRelevant(), true);
QTEST(swipeGesture.minimumFingerCount(), "expectedCount");
swipeGesture.setMinimumFingerCount(0);
QCOMPARE(swipeGesture.minimumFingerCountIsRelevant(), true);
QCOMPARE(swipeGesture.minimumFingerCount(), 0u);
}
void GestureTest::testPinchMinFinger_data()
{
QTest::addColumn<uint>("count");
QTest::addColumn<uint>("expectedCount");
QTest::newRow("0") << 0u << 0u;
QTest::newRow("1") << 1u << 1u;
QTest::newRow("10") << 10u << 10u;
}
void GestureTest::testPinchMinFinger()
{
PinchGesture pinchGesture;
QCOMPARE(pinchGesture.minimumFingerCountIsRelevant(), false);
QCOMPARE(pinchGesture.minimumFingerCount(), 0u);
QFETCH(uint, count);
pinchGesture.setMinimumFingerCount(count);
QCOMPARE(pinchGesture.minimumFingerCountIsRelevant(), true);
QTEST(pinchGesture.minimumFingerCount(), "expectedCount");
pinchGesture.setMinimumFingerCount(0);
QCOMPARE(pinchGesture.minimumFingerCountIsRelevant(), true);
QCOMPARE(pinchGesture.minimumFingerCount(), 0u);
}
void GestureTest::testSwipeMaxFinger_data()
{
QTest::addColumn<uint>("count");
QTest::addColumn<uint>("expectedCount");
QTest::newRow("0") << 0u << 0u;
QTest::newRow("1") << 1u << 1u;
QTest::newRow("10") << 10u << 10u;
}
void GestureTest::testSwipeMaxFinger()
{
SwipeGesture gesture;
QCOMPARE(gesture.maximumFingerCountIsRelevant(), false);
QCOMPARE(gesture.maximumFingerCount(), 0u);
QFETCH(uint, count);
gesture.setMaximumFingerCount(count);
QCOMPARE(gesture.maximumFingerCountIsRelevant(), true);
QTEST(gesture.maximumFingerCount(), "expectedCount");
gesture.setMaximumFingerCount(0);
QCOMPARE(gesture.maximumFingerCountIsRelevant(), true);
QCOMPARE(gesture.maximumFingerCount(), 0u);
}
void GestureTest::testPinchMaxFinger_data()
{
QTest::addColumn<uint>("count");
QTest::addColumn<uint>("expectedCount");
QTest::newRow("0") << 0u << 0u;
QTest::newRow("1") << 1u << 1u;
QTest::newRow("10") << 10u << 10u;
}
void GestureTest::testPinchMaxFinger()
{
PinchGesture gesture;
QCOMPARE(gesture.maximumFingerCountIsRelevant(), false);
QCOMPARE(gesture.maximumFingerCount(), 0u);
QFETCH(uint, count);
gesture.setMaximumFingerCount(count);
QCOMPARE(gesture.maximumFingerCountIsRelevant(), true);
QTEST(gesture.maximumFingerCount(), "expectedCount");
gesture.setMaximumFingerCount(0);
QCOMPARE(gesture.maximumFingerCountIsRelevant(), true);
QCOMPARE(gesture.maximumFingerCount(), 0u);
}
void GestureTest::testSwipeDirection_data()
{
QTest::addColumn<KWin::SwipeGesture::Direction>("swipe_direction");
QTest::addColumn<GestureDirection>("swipe_direction");
QTest::newRow("Up") << KWin::SwipeGesture::Direction::Up;
QTest::newRow("Left") << KWin::SwipeGesture::Direction::Left;
QTest::newRow("Right") << KWin::SwipeGesture::Direction::Right;
QTest::newRow("Down") << KWin::SwipeGesture::Direction::Down;
QTest::newRow("Up") << GestureDirection::Up;
QTest::newRow("Left") << GestureDirection::Left;
QTest::newRow("Right") << GestureDirection::Right;
QTest::newRow("Down") << GestureDirection::Down;
}
void GestureTest::testSwipeDirection()
{
SwipeGesture gesture;
QCOMPARE(gesture.direction(), SwipeGesture::Direction::Down);
QFETCH(KWin::SwipeGesture::Direction, swipe_direction);
QCOMPARE(gesture.direction(), GestureDirection::Down);
QFETCH(GestureDirection, swipe_direction);
gesture.setDirection(swipe_direction);
QCOMPARE(gesture.direction(), swipe_direction);
// back to down
gesture.setDirection(SwipeGesture::Direction::Down);
QCOMPARE(gesture.direction(), SwipeGesture::Direction::Down);
gesture.setDirection(GestureDirection::Down);
QCOMPARE(gesture.direction(), GestureDirection::Down);
}
void GestureTest::testPinchDirection_data()
{
QTest::addColumn<KWin::PinchGesture::Direction>("pinch_direction");
QTest::addColumn<GestureDirection>("pinch_direction");
QTest::newRow("Contracting") << KWin::PinchGesture::Direction::Contracting;
QTest::newRow("Expanding") << KWin::PinchGesture::Direction::Expanding;
QTest::newRow("Contracting") << GestureDirection::Contracting;
QTest::newRow("Expanding") << GestureDirection::Expanding;
}
void GestureTest::testPinchDirection()
{
PinchGesture gesture;
QCOMPARE(gesture.direction(), PinchGesture::Direction::Expanding);
QFETCH(KWin::PinchGesture::Direction, pinch_direction);
QCOMPARE(gesture.direction(), GestureDirection::Expanding);
QFETCH(GestureDirection, pinch_direction);
gesture.setDirection(pinch_direction);
QCOMPARE(gesture.direction(), pinch_direction);
// back to down
gesture.setDirection(PinchGesture::Direction::Expanding);
QCOMPARE(gesture.direction(), PinchGesture::Direction::Expanding);
gesture.setDirection(GestureDirection::Expanding);
QCOMPARE(gesture.direction(), GestureDirection::Expanding);
}
void GestureTest::testMinimumX_data()
@ -302,127 +190,6 @@ void GestureTest::testStartGeometry()
QCOMPARE(gesture.maximumY(), 32);
}
void GestureTest::testSetMinimumDelta()
{
SwipeGesture swipeGesture;
QCOMPARE(swipeGesture.isMinimumDeltaRelevant(), false);
QCOMPARE(swipeGesture.minimumDelta(), QSizeF());
QCOMPARE(swipeGesture.minimumDeltaReached(QSizeF()), true);
swipeGesture.setMinimumDelta(QSizeF(2, 3));
QCOMPARE(swipeGesture.isMinimumDeltaRelevant(), true);
QCOMPARE(swipeGesture.minimumDelta(), QSizeF(2, 3));
QCOMPARE(swipeGesture.minimumDeltaReached(QSizeF()), false);
QCOMPARE(swipeGesture.minimumDeltaReached(QSizeF(2, 3)), true);
PinchGesture pinchGesture;
QCOMPARE(pinchGesture.isMinimumScaleDeltaRelevant(), false);
QCOMPARE(pinchGesture.minimumScaleDelta(), DEFAULT_UNIT_SCALE_DELTA);
QCOMPARE(pinchGesture.minimumScaleDeltaReached(1.25), true);
pinchGesture.setMinimumScaleDelta(.5);
QCOMPARE(pinchGesture.isMinimumScaleDeltaRelevant(), true);
QCOMPARE(pinchGesture.minimumScaleDelta(), .5);
QCOMPARE(pinchGesture.minimumScaleDeltaReached(1.24), false);
QCOMPARE(pinchGesture.minimumScaleDeltaReached(1.5), true);
}
void GestureTest::testMinimumDeltaReached_data()
{
QTest::addColumn<KWin::SwipeGesture::Direction>("direction");
QTest::addColumn<QSizeF>("minimumDelta");
QTest::addColumn<QSizeF>("delta");
QTest::addColumn<bool>("reached");
QTest::addColumn<qreal>("progress");
QTest::newRow("Up (more)") << KWin::SwipeGesture::Direction::Up << QSizeF(0, -30) << QSizeF(0, -40) << true << 1.0;
QTest::newRow("Up (exact)") << KWin::SwipeGesture::Direction::Up << QSizeF(0, -30) << QSizeF(0, -30) << true << 1.0;
QTest::newRow("Up (less)") << KWin::SwipeGesture::Direction::Up << QSizeF(0, -30) << QSizeF(0, -29) << false << 29.0 / 30.0;
QTest::newRow("Left (more)") << KWin::SwipeGesture::Direction::Left << QSizeF(-30, -30) << QSizeF(-40, 20) << true << 1.0;
QTest::newRow("Left (exact)") << KWin::SwipeGesture::Direction::Left << QSizeF(-30, -40) << QSizeF(-30, 0) << true << 1.0;
QTest::newRow("Left (less)") << KWin::SwipeGesture::Direction::Left << QSizeF(-30, -30) << QSizeF(-29, 0) << false << 29.0 / 30.0;
QTest::newRow("Right (more)") << KWin::SwipeGesture::Direction::Right << QSizeF(30, -30) << QSizeF(40, 20) << true << 1.0;
QTest::newRow("Right (exact)") << KWin::SwipeGesture::Direction::Right << QSizeF(30, -40) << QSizeF(30, 0) << true << 1.0;
QTest::newRow("Right (less)") << KWin::SwipeGesture::Direction::Right << QSizeF(30, -30) << QSizeF(29, 0) << false << 29.0 / 30.0;
QTest::newRow("Down (more)") << KWin::SwipeGesture::Direction::Down << QSizeF(0, 30) << QSizeF(0, 40) << true << 1.0;
QTest::newRow("Down (exact)") << KWin::SwipeGesture::Direction::Down << QSizeF(0, 30) << QSizeF(0, 30) << true << 1.0;
QTest::newRow("Down (less)") << KWin::SwipeGesture::Direction::Down << QSizeF(0, 30) << QSizeF(0, 29) << false << 29.0 / 30.0;
}
void GestureTest::testMinimumDeltaReached()
{
GestureRecognizer recognizer;
// swipe gesture
SwipeGesture gesture;
QFETCH(SwipeGesture::Direction, direction);
gesture.setDirection(direction);
QFETCH(QSizeF, minimumDelta);
gesture.setMinimumDelta(minimumDelta);
QFETCH(QSizeF, delta);
QFETCH(bool, reached);
QCOMPARE(gesture.minimumDeltaReached(delta), reached);
recognizer.registerSwipeGesture(&gesture);
QSignalSpy startedSpy(&gesture, &SwipeGesture::started);
QVERIFY(startedSpy.isValid());
QSignalSpy triggeredSpy(&gesture, &SwipeGesture::triggered);
QVERIFY(triggeredSpy.isValid());
QSignalSpy cancelledSpy(&gesture, &SwipeGesture::cancelled);
QVERIFY(cancelledSpy.isValid());
QSignalSpy progressSpy(&gesture, &SwipeGesture::progress);
QVERIFY(progressSpy.isValid());
recognizer.startSwipeGesture(1);
QCOMPARE(startedSpy.count(), 1);
QCOMPARE(triggeredSpy.count(), 0);
QCOMPARE(cancelledSpy.count(), 0);
QCOMPARE(progressSpy.count(), 0);
recognizer.updateSwipeGesture(delta);
QCOMPARE(startedSpy.count(), 1);
QCOMPARE(triggeredSpy.count(), 0);
QCOMPARE(cancelledSpy.count(), 0);
QCOMPARE(progressSpy.count(), 1);
QTEST(progressSpy.first().first().value<qreal>(), "progress");
recognizer.endSwipeGesture();
QCOMPARE(startedSpy.count(), 1);
QCOMPARE(progressSpy.count(), 1);
QCOMPARE(triggeredSpy.isEmpty(), !reached);
QCOMPARE(cancelledSpy.isEmpty(), reached);
}
void GestureTest::testMinimumScaleDelta()
{
// pinch gesture
PinchGesture gesture;
gesture.setDirection(PinchGesture::Direction::Contracting);
gesture.setMinimumScaleDelta(.5);
gesture.setMinimumFingerCount(3);
gesture.setMaximumFingerCount(4);
QCOMPARE(gesture.minimumScaleDeltaReached(1.25), false);
QCOMPARE(gesture.minimumScaleDeltaReached(1.5), true);
GestureRecognizer recognizer;
recognizer.registerPinchGesture(&gesture);
QSignalSpy startedSpy(&gesture, &PinchGesture::started);
QVERIFY(startedSpy.isValid());
QSignalSpy triggeredSpy(&gesture, &PinchGesture::triggered);
QVERIFY(triggeredSpy.isValid());
QSignalSpy cancelledSpy(&gesture, &PinchGesture::cancelled);
QVERIFY(cancelledSpy.isValid());
QSignalSpy progressSpy(&gesture, &PinchGesture::progress);
QVERIFY(progressSpy.isValid());
recognizer.startPinchGesture(4);
QCOMPARE(startedSpy.count(), 1);
QCOMPARE(triggeredSpy.count(), 0);
QCOMPARE(cancelledSpy.count(), 0);
QCOMPARE(progressSpy.count(), 0);
}
void GestureTest::testUnregisterSwipeCancels()
{
GestureRecognizer recognizer;
@ -484,19 +251,20 @@ void GestureTest::testDeleteSwipeCancels()
void GestureTest::testSwipeCancel_data()
{
QTest::addColumn<KWin::SwipeGesture::Direction>("direction");
QTest::addColumn<GestureDirection>("direction");
QTest::newRow("Up") << KWin::SwipeGesture::Direction::Up;
QTest::newRow("Left") << KWin::SwipeGesture::Direction::Left;
QTest::newRow("Right") << KWin::SwipeGesture::Direction::Right;
QTest::newRow("Down") << KWin::SwipeGesture::Direction::Down;
QTest::newRow("Up") << GestureDirection::Up;
QTest::newRow("Left") << GestureDirection::Left;
QTest::newRow("Right") << GestureDirection::Right;
QTest::newRow("Down") << GestureDirection::Down;
}
void GestureTest::testSwipeCancel()
{
GestureRecognizer recognizer;
std::unique_ptr<SwipeGesture> gesture(new SwipeGesture);
QFETCH(SwipeGesture::Direction, direction);
QFETCH(GestureDirection, direction);
gesture->setDirection(direction);
QSignalSpy startedSpy(gesture.get(), &SwipeGesture::started);
QVERIFY(startedSpy.isValid());
@ -516,20 +284,20 @@ void GestureTest::testSwipeCancel()
void GestureTest::testSwipeUpdateTrigger_data()
{
QTest::addColumn<KWin::SwipeGesture::Direction>("direction");
QTest::addColumn<GestureDirection>("direction");
QTest::addColumn<QSizeF>("delta");
QTest::newRow("Up") << KWin::SwipeGesture::Direction::Up << QSizeF(2, -3);
QTest::newRow("Left") << KWin::SwipeGesture::Direction::Left << QSizeF(-3, 1);
QTest::newRow("Right") << KWin::SwipeGesture::Direction::Right << QSizeF(20, -19);
QTest::newRow("Down") << KWin::SwipeGesture::Direction::Down << QSizeF(0, 50);
QTest::newRow("Up") << GestureDirection::Up << QSizeF(2, -3);
QTest::newRow("Left") << GestureDirection::Left << QSizeF(-3, 1);
QTest::newRow("Right") << GestureDirection::Right << QSizeF(20, -19);
QTest::newRow("Down") << GestureDirection::Down << QSizeF(0, 50);
}
void GestureTest::testSwipeUpdateTrigger()
{
GestureRecognizer recognizer;
SwipeGesture gesture;
QFETCH(SwipeGesture::Direction, direction);
QFETCH(GestureDirection, direction);
gesture.setDirection(direction);
QSignalSpy triggeredSpy(&gesture, &SwipeGesture::triggered);
@ -550,50 +318,22 @@ void GestureTest::testSwipeUpdateTrigger()
QCOMPARE(triggeredSpy.count(), 1);
}
void GestureTest::testSwipeMinFingerStart_data()
void GestureTest::testSwipeFingerCount_data()
{
QTest::addColumn<uint>("min");
QTest::addColumn<uint>("expected");
QTest::addColumn<uint>("count");
QTest::addColumn<bool>("started");
QTest::addColumn<bool>("started"); // Should it accept
QTest::newRow("same") << 1u << 1u << true;
QTest::newRow("less") << 2u << 1u << false;
QTest::newRow("more") << 1u << 2u << true;
QTest::newRow("acceptable") << 1u << 1u << true;
QTest::newRow("unacceptable") << 2u << 1u << false;
}
void GestureTest::testSwipeMinFingerStart()
void GestureTest::testSwipeFingerCount()
{
GestureRecognizer recognizer;
SwipeGesture gesture;
QFETCH(uint, min);
gesture.setMinimumFingerCount(min);
QSignalSpy startedSpy(&gesture, &SwipeGesture::started);
QVERIFY(startedSpy.isValid());
recognizer.registerSwipeGesture(&gesture);
QFETCH(uint, count);
recognizer.startSwipeGesture(count);
QTEST(!startedSpy.isEmpty(), "started");
}
void GestureTest::testSwipeMaxFingerStart_data()
{
QTest::addColumn<uint>("max");
QTest::addColumn<uint>("count");
QTest::addColumn<bool>("started");
QTest::newRow("same") << 1u << 1u << true;
QTest::newRow("less") << 2u << 1u << true;
QTest::newRow("more") << 1u << 2u << false;
}
void GestureTest::testSwipeMaxFingerStart()
{
GestureRecognizer recognizer;
SwipeGesture gesture;
QFETCH(uint, max);
gesture.setMaximumFingerCount(max);
QFETCH(uint, expected);
gesture.addFingerCount(expected);
QSignalSpy startedSpy(&gesture, &SwipeGesture::started);
QVERIFY(startedSpy.isValid());
@ -612,11 +352,11 @@ void GestureTest::testNotEmitCallbacksBeforeDirectionDecided()
SwipeGesture right;
PinchGesture expand;
PinchGesture contract;
up.setDirection(SwipeGesture::Direction::Up);
down.setDirection(SwipeGesture::Direction::Down);
right.setDirection(SwipeGesture::Direction::Right);
expand.setDirection(PinchGesture::Direction::Expanding);
contract.setDirection(PinchGesture::Direction::Contracting);
up.setDirection(GestureDirection::Up);
down.setDirection(GestureDirection::Down);
right.setDirection(GestureDirection::Right);
expand.setDirection(GestureDirection::Expanding);
contract.setDirection(GestureDirection::Contracting);
recognizer.registerSwipeGesture(&up);
recognizer.registerSwipeGesture(&down);
recognizer.registerSwipeGesture(&right);

View file

@ -32,21 +32,9 @@ void InputRedirection::registerAxisShortcut(Qt::KeyboardModifiers modifiers, Poi
Q_UNUSED(action)
}
void InputRedirection::registerTouchpadSwipeShortcut(SwipeDirection, uint fingerCount, QAction *)
{
Q_UNUSED(fingerCount)
}
void InputRedirection::registerRealtimeTouchpadSwipeShortcut(SwipeDirection, uint fingerCount, QAction *, std::function<void(qreal)> progressCallback)
{
Q_UNUSED(progressCallback)
Q_UNUSED(fingerCount)
}
void InputRedirection::registerTouchscreenSwipeShortcut(SwipeDirection, uint, QAction *, std::function<void(qreal)>)
void InputRedirection::registerGesture(GestureDeviceType, GestureDirection, uint, QAction *, std::function<void(qreal)>)
{
}
}
Q_DECLARE_METATYPE(Qt::Orientation)

View file

@ -816,29 +816,9 @@ void EffectsHandlerImpl::registerAxisShortcut(Qt::KeyboardModifiers modifiers, P
input()->registerAxisShortcut(modifiers, axis, action);
}
void EffectsHandlerImpl::registerRealtimeTouchpadSwipeShortcut(SwipeDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback)
void EffectsHandlerImpl::registerGesture(GestureDeviceType device, GestureDirection direction, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback)
{
input()->registerRealtimeTouchpadSwipeShortcut(dir, fingerCount, onUp, progressCallback);
}
void EffectsHandlerImpl::registerTouchpadSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action)
{
input()->registerTouchpadSwipeShortcut(direction, fingerCount, action);
}
void EffectsHandlerImpl::registerRealtimeTouchpadPinchShortcut(PinchDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback)
{
input()->registerRealtimeTouchpadPinchShortcut(dir, fingerCount, onUp, progressCallback);
}
void EffectsHandlerImpl::registerTouchpadPinchShortcut(PinchDirection direction, uint fingerCount, QAction *action)
{
input()->registerTouchpadPinchShortcut(direction, fingerCount, action);
}
void EffectsHandlerImpl::registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback)
{
input()->registerTouchscreenSwipeShortcut(direction, fingerCount, action, progressCallback);
input()->registerGesture(device, direction, fingerCount, onUp, progressCallback);
}
void *EffectsHandlerImpl::getProxy(QString name)

View file

@ -104,11 +104,8 @@ public:
void registerGlobalShortcut(const QKeySequence &shortcut, QAction *action) override;
void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action) override;
void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action) override;
void registerRealtimeTouchpadSwipeShortcut(SwipeDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback) override;
void registerTouchpadSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action) override;
void registerRealtimeTouchpadPinchShortcut(PinchDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback) override;
void registerTouchpadPinchShortcut(PinchDirection direction, uint fingerCount, QAction *action) override;
void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback) override;
void registerGesture(GestureDeviceType device, GestureDirection direction, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback) override;
void *getProxy(QString name) override;
void startMousePolling() override;
void stopMousePolling() override;

View file

@ -61,7 +61,7 @@ DesktopGridEffect::DesktopGridEffect()
}
});
effects->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Up, 4, m_realtimeToggleAction, [this](qreal progress) {
effects->registerGesture(GestureDeviceType::Touchpad, GestureDirection::Up, 4, m_realtimeToggleAction, [this](qreal progress) {
if (!effects->hasActiveFullScreenEffect() || effects->activeFullScreenEffect() == this) {
switch (m_status) {
case Status::Inactive:

View file

@ -66,8 +66,8 @@ OverviewEffect::OverviewEffect()
}
};
effects->registerRealtimeTouchpadPinchShortcut(PinchDirection::Contracting, 4, m_realtimeToggleAction, progressCallback);
effects->registerTouchscreenSwipeShortcut(SwipeDirection::Up, 3, m_realtimeToggleAction, progressCallback);
effects->registerGesture(GestureDeviceType::Touchpad, GestureDirection::Contracting, 4, m_realtimeToggleAction, progressCallback);
effects->registerGesture(GestureDeviceType::Touchscreen, GestureDirection::Up, 3, m_realtimeToggleAction, progressCallback);
connect(effects, &EffectsHandler::screenAboutToLock, this, &OverviewEffect::realDeactivate);

View file

@ -125,8 +125,8 @@ WindowViewEffect::WindowViewEffect()
}
}
};
effects->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Down, 4, m_realtimeToggleAction, gestureCallback);
effects->registerTouchscreenSwipeShortcut(SwipeDirection::Down, 3, m_realtimeToggleAction, gestureCallback);
effects->registerGesture(GestureDeviceType::Touchpad, GestureDirection::Down, 4, m_realtimeToggleAction, gestureCallback);
effects->registerGesture(GestureDeviceType::Touchscreen, GestureDirection::Down, 3, m_realtimeToggleAction, gestureCallback);
reconfigure(ReconfigureAll);
}

View file

@ -47,16 +47,13 @@ qreal SwipeGesture::deltaToProgress(const QSizeF &delta) const
return 1.0;
}
switch (m_direction) {
case Direction::Up:
case Direction::Down:
if (m_direction & (GestureDirection::Up | GestureDirection::Down)) {
return std::min(std::abs(delta.height()) / std::abs(m_minimumDelta.height()), 1.0);
case Direction::Left:
case Direction::Right:
} else if (m_direction & (GestureDirection::Left | GestureDirection::Right)) {
return std::min(std::abs(delta.width()) / std::abs(m_minimumDelta.width()), 1.0);
default:
Q_UNREACHABLE();
}
return 1.0;
}
bool SwipeGesture::minimumDeltaReached(const QSizeF &delta) const
@ -136,17 +133,11 @@ int GestureRecognizer::startSwipeGesture(uint fingerCount, const QPointF &startP
if (!m_activeSwipeGestures.isEmpty() || !m_activePinchGestures.isEmpty()) {
return 0;
}
int count = 0;
for (SwipeGesture *gesture : qAsConst(m_swipeGestures)) {
if (gesture->minimumFingerCountIsRelevant()) {
if (gesture->minimumFingerCount() > fingerCount) {
continue;
}
}
if (gesture->maximumFingerCountIsRelevant()) {
if (gesture->maximumFingerCount() < fingerCount) {
continue;
}
if (!gesture->isFingerCountAcceptable(fingerCount)) {
continue;
}
if (startPosBehavior == StartPositionBehavior::Relevant) {
if (gesture->minimumXIsRelevant()) {
@ -172,19 +163,14 @@ int GestureRecognizer::startSwipeGesture(uint fingerCount, const QPointF &startP
}
// Only add gestures who's direction aligns with current swipe axis
switch (gesture->direction()) {
case SwipeGesture::Direction::Up:
case SwipeGesture::Direction::Down:
if (gesture->direction() & (GestureDirection::Up | GestureDirection::Down)) {
if (m_currentSwipeAxis == Axis::Horizontal) {
continue;
}
break;
case SwipeGesture::Direction::Left:
case SwipeGesture::Direction::Right:
} else if (gesture->direction() & (GestureDirection::Left | GestureDirection::Right)) {
if (m_currentSwipeAxis == Axis::Vertical) {
continue;
}
break;
}
m_activeSwipeGestures << gesture;
@ -198,17 +184,17 @@ void GestureRecognizer::updateSwipeGesture(const QSizeF &delta)
{
m_currentDelta += delta;
SwipeGesture::Direction direction; // Overall direction
GestureDirection direction; // Overall direction
Axis swipeAxis;
// Pick an axis for gestures so horizontal ones don't change to vertical ones without lifting fingers
if (m_currentSwipeAxis == Axis::None) {
if (std::abs(m_currentDelta.width()) >= std::abs(m_currentDelta.height())) {
swipeAxis = Axis::Horizontal;
direction = m_currentDelta.width() < 0 ? SwipeGesture::Direction::Left : SwipeGesture::Direction::Right;
direction = m_currentDelta.width() < 0 ? GestureDirection::Left : GestureDirection::Right;
} else {
swipeAxis = Axis::Vertical;
direction = m_currentDelta.height() < 0 ? SwipeGesture::Direction::Up : SwipeGesture::Direction::Down;
direction = m_currentDelta.height() < 0 ? GestureDirection::Up : GestureDirection::Down;
}
if (std::abs(m_currentDelta.width()) >= 5 || std::abs(m_currentDelta.height()) >= 5) {
// only lock in a direction if the delta is big enough
@ -222,10 +208,10 @@ void GestureRecognizer::updateSwipeGesture(const QSizeF &delta)
// Find the current swipe direction
switch (swipeAxis) {
case Axis::Vertical:
direction = m_currentDelta.height() < 0 ? SwipeGesture::Direction::Up : SwipeGesture::Direction::Down;
direction = m_currentDelta.height() < 0 ? GestureDirection::Up : GestureDirection::Down;
break;
case Axis::Horizontal:
direction = m_currentDelta.width() < 0 ? SwipeGesture::Direction::Left : SwipeGesture::Direction::Right;
direction = m_currentDelta.width() < 0 ? GestureDirection::Left : GestureDirection::Right;
break;
default:
Q_UNREACHABLE();
@ -241,7 +227,7 @@ void GestureRecognizer::updateSwipeGesture(const QSizeF &delta)
for (auto it = m_activeSwipeGestures.begin(); it != m_activeSwipeGestures.end();) {
auto g = static_cast<SwipeGesture *>(*it);
if (g->direction() != direction) {
if (!(g->direction() & direction)) {
// If a gesture was started from a touchscreen border never cancel it
if (!g->minimumXIsRelevant() || !g->maximumXIsRelevant() || !g->minimumYIsRelevant() || !g->maximumYIsRelevant()) {
Q_EMIT g->cancelled();
@ -308,15 +294,8 @@ int GestureRecognizer::startPinchGesture(uint fingerCount)
return 0;
}
for (PinchGesture *gesture : qAsConst(m_pinchGestures)) {
if (gesture->minimumFingerCountIsRelevant()) {
if (gesture->minimumFingerCount() > fingerCount) {
continue;
}
}
if (gesture->maximumFingerCountIsRelevant()) {
if (gesture->maximumFingerCount() < fingerCount) {
continue;
}
if (!gesture->isFingerCountAcceptable(fingerCount)) {
continue;
}
// direction doesn't matter yet
@ -334,11 +313,11 @@ void GestureRecognizer::updatePinchGesture(qreal scale, qreal angleDelta, const
m_currentScale = scale;
// Determine the direction of the swipe
PinchGesture::Direction direction;
GestureDirection direction;
if (scale < 1) {
direction = PinchGesture::Direction::Contracting;
direction = GestureDirection::Contracting;
} else {
direction = PinchGesture::Direction::Expanding;
direction = GestureDirection::Expanding;
}
// Eliminate wrong gestures (takes two iterations)
@ -350,7 +329,7 @@ void GestureRecognizer::updatePinchGesture(qreal scale, qreal angleDelta, const
for (auto it = m_activePinchGestures.begin(); it != m_activePinchGestures.end();) {
auto g = static_cast<PinchGesture *>(*it);
if (g->direction() != direction) {
if (!(g->direction() & direction)) {
Q_EMIT g->cancelled();
it = m_activePinchGestures.erase(it);
continue;
@ -388,44 +367,12 @@ void GestureRecognizer::endPinchGesture() // because fingers up
m_currentSwipeAxis = Axis::None;
}
bool SwipeGesture::maximumFingerCountIsRelevant() const
{
return m_maximumFingerCountRelevant;
}
uint SwipeGesture::minimumFingerCount() const
{
return m_minimumFingerCount;
}
void SwipeGesture::setMinimumFingerCount(uint count)
{
m_minimumFingerCount = count;
m_minimumFingerCountRelevant = true;
}
bool SwipeGesture::minimumFingerCountIsRelevant() const
{
return m_minimumFingerCountRelevant;
}
void SwipeGesture::setMaximumFingerCount(uint count)
{
m_maximumFingerCount = count;
m_maximumFingerCountRelevant = true;
}
uint SwipeGesture::maximumFingerCount() const
{
return m_maximumFingerCount;
}
SwipeGesture::Direction SwipeGesture::direction() const
GestureDirections SwipeGesture::direction() const
{
return m_direction;
}
void SwipeGesture::setDirection(Direction direction)
void SwipeGesture::setDirection(GestureDirections direction)
{
m_direction = direction;
}
@ -510,44 +457,12 @@ bool SwipeGesture::isMinimumDeltaRelevant() const
return m_minimumDeltaRelevant;
}
bool PinchGesture::minimumFingerCountIsRelevant() const
{
return m_minimumFingerCountRelevant;
}
void PinchGesture::setMinimumFingerCount(uint count)
{
m_minimumFingerCount = count;
m_minimumFingerCountRelevant = true;
}
uint PinchGesture::minimumFingerCount() const
{
return m_minimumFingerCount;
}
bool PinchGesture::maximumFingerCountIsRelevant() const
{
return m_maximumFingerCountRelevant;
}
void PinchGesture::setMaximumFingerCount(uint count)
{
m_maximumFingerCount = count;
m_maximumFingerCountRelevant = true;
}
uint PinchGesture::maximumFingerCount() const
{
return m_maximumFingerCount;
}
PinchGesture::Direction PinchGesture::direction() const
GestureDirections PinchGesture::direction() const
{
return m_direction;
}
void PinchGesture::setDirection(Direction direction)
void PinchGesture::setDirection(GestureDirections direction)
{
m_direction = direction;
}
@ -578,4 +493,21 @@ int GestureRecognizer::startSwipeGesture(const QPointF &startPos)
return startSwipeGesture(1, startPos, StartPositionBehavior::Relevant);
}
void Gesture::addFingerCount(uint numFingers)
{
if (m_validFingerCounts == DEFAULT_VALID_FINGER_COUNTS) {
m_validFingerCounts.clear();
}
m_validFingerCounts.insert(numFingers);
}
bool Gesture::isFingerCountAcceptable(uint fingers) const
{
return m_validFingerCounts.contains(fingers);
}
QSet<uint> Gesture::acceptableFingerCounts() const
{
return m_validFingerCounts;
}
}

View file

@ -9,16 +9,20 @@
#ifndef KWIN_GESTURES_H
#define KWIN_GESTURES_H
#include "kwinglobals.h"
#include <kwin_export.h>
#include <QMap>
#include <QObject>
#include <QPointF>
#include <QSet>
#include <QSizeF>
#include <QVector>
namespace KWin
{
static const QSet<uint> DEFAULT_VALID_FINGER_COUNTS = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
/*
* Everytime the scale of the gesture changes by this much, the callback changes by 1.
* This is the amount of change for 1 unit of change, like switch by 1 desktop.
@ -31,6 +35,21 @@ class Gesture : public QObject
public:
~Gesture() override;
/**
* This gesture framework allows for one gesture to
* capture a range of fingers.
*
* This function adds an acceptable number of fingers
* to the set of finger counts this gesture can
* be identified by.
*
* By default, any number of fingers are accepted.
* (see DEFAULT_VALID_FINGER_COUNTS)
*/
void addFingerCount(uint numFingers);
bool isFingerCountAcceptable(uint fingers) const;
QSet<uint> acceptableFingerCounts() const;
protected:
explicit Gesture(QObject *parent);
@ -49,32 +68,20 @@ Q_SIGNALS:
* This Gesture no longer matches.
*/
void cancelled();
private:
QSet<uint> m_validFingerCounts = DEFAULT_VALID_FINGER_COUNTS;
};
class SwipeGesture : public Gesture
{
Q_OBJECT
public:
enum class Direction {
Down,
Left,
Up,
Right,
};
explicit SwipeGesture(QObject *parent = nullptr);
~SwipeGesture() override;
bool minimumFingerCountIsRelevant() const;
void setMinimumFingerCount(uint count);
uint minimumFingerCount() const;
bool maximumFingerCountIsRelevant() const;
void setMaximumFingerCount(uint count);
uint maximumFingerCount() const;
Direction direction() const;
void setDirection(Direction direction);
GestureDirections direction() const;
void setDirection(GestureDirections direction);
void setMinimumX(int x);
int minimumX() const;
@ -111,11 +118,7 @@ Q_SIGNALS:
void deltaProgress(const QSizeF &delta);
private:
bool m_minimumFingerCountRelevant = false;
uint m_minimumFingerCount = 0;
bool m_maximumFingerCountRelevant = false;
uint m_maximumFingerCount = 0;
Direction m_direction = Direction::Down;
GestureDirections m_direction = GestureDirection::Down;
bool m_minimumXRelevant = false;
int m_minimumX = 0;
bool m_minimumYRelevant = false;
@ -132,24 +135,11 @@ class PinchGesture : public Gesture
{
Q_OBJECT
public:
enum class Direction {
Expanding,
Contracting,
};
explicit PinchGesture(QObject *parent = nullptr);
~PinchGesture() override;
bool minimumFingerCountIsRelevant() const;
void setMinimumFingerCount(uint count);
uint minimumFingerCount() const;
bool maximumFingerCountIsRelevant() const;
void setMaximumFingerCount(uint count);
uint maximumFingerCount() const;
Direction direction() const;
void setDirection(Direction direction);
GestureDirections direction() const;
void setDirection(GestureDirections direction);
qreal minimumScaleDelta() const;
@ -171,11 +161,7 @@ Q_SIGNALS:
void progress(qreal);
private:
bool m_minimumFingerCountRelevant = false;
uint m_minimumFingerCount = 0;
bool m_maximumFingerCountRelevant = false;
uint m_maximumFingerCount = 0;
Direction m_direction = Direction::Expanding;
GestureDirections m_direction = GestureDirection::Expanding;
bool m_minimumScaleDeltaRelevant = false;
qreal m_minimumScaleDelta = DEFAULT_UNIT_SCALE_DELTA;
};
@ -230,7 +216,4 @@ private:
}
Q_DECLARE_METATYPE(KWin::SwipeGesture::Direction)
Q_DECLARE_METATYPE(KWin::PinchGesture::Direction)
#endif

View file

@ -27,52 +27,9 @@
namespace KWin
{
GlobalShortcut::GlobalShortcut(Shortcut &&sc, QAction *action)
: m_shortcut(sc)
: m_shortcut(std::move(sc))
, m_action(action)
{
static const QMap<SwipeDirection, SwipeGesture::Direction> swipeDirs = {
{SwipeDirection::Up, SwipeGesture::Direction::Up},
{SwipeDirection::Down, SwipeGesture::Direction::Down},
{SwipeDirection::Left, SwipeGesture::Direction::Left},
{SwipeDirection::Right, SwipeGesture::Direction::Right},
};
static const QMap<PinchDirection, PinchGesture::Direction> pinchDirs = {
{PinchDirection::Expanding, PinchGesture::Direction::Expanding},
{PinchDirection::Contracting, PinchGesture::Direction::Contracting}};
if (auto swipeGesture = std::get_if<SwipeShortcut>(&sc)) {
m_swipeGesture.reset(new SwipeGesture());
m_swipeGesture->setDirection(swipeDirs[swipeGesture->direction]);
m_swipeGesture->setMaximumFingerCount(swipeGesture->fingerCount);
m_swipeGesture->setMinimumFingerCount(swipeGesture->fingerCount);
QObject::connect(m_swipeGesture.get(), &SwipeGesture::triggered, m_action, &QAction::trigger, Qt::QueuedConnection);
} else if (auto rtSwipeGesture = std::get_if<RealtimeFeedbackSwipeShortcut>(&sc)) {
m_swipeGesture.reset(new SwipeGesture());
m_swipeGesture->setDirection(swipeDirs[rtSwipeGesture->direction]);
m_swipeGesture->setMinimumDelta(QSizeF(200, 200));
m_swipeGesture->setMaximumFingerCount(rtSwipeGesture->fingerCount);
m_swipeGesture->setMinimumFingerCount(rtSwipeGesture->fingerCount);
QObject::connect(m_swipeGesture.get(), &SwipeGesture::triggered, m_action, &QAction::trigger, Qt::QueuedConnection);
QObject::connect(m_swipeGesture.get(), &SwipeGesture::cancelled, m_action, &QAction::trigger, Qt::QueuedConnection);
QObject::connect(m_swipeGesture.get(), &SwipeGesture::progress, [cb = rtSwipeGesture->progressCallback](qreal v) {
cb(v);
});
} else if (auto pinchGesture = std::get_if<PinchShortcut>(&sc)) {
m_pinchGesture.reset(new PinchGesture());
m_pinchGesture->setDirection(pinchDirs[pinchGesture->direction]);
m_pinchGesture->setMaximumFingerCount(pinchGesture->fingerCount);
m_pinchGesture->setMinimumFingerCount(pinchGesture->fingerCount);
QObject::connect(m_pinchGesture.get(), &PinchGesture::triggered, m_action, &QAction::trigger, Qt::QueuedConnection);
} else if (auto rtPinchGesture = std::get_if<RealtimeFeedbackPinchShortcut>(&sc)) {
m_pinchGesture.reset(new PinchGesture());
m_pinchGesture->setDirection(pinchDirs[rtPinchGesture->direction]);
m_pinchGesture->setMaximumFingerCount(rtPinchGesture->fingerCount);
m_pinchGesture->setMinimumFingerCount(rtPinchGesture->fingerCount);
QObject::connect(m_pinchGesture.get(), &PinchGesture::triggered, m_action, &QAction::trigger, Qt::QueuedConnection);
QObject::connect(m_pinchGesture.get(), &PinchGesture::cancelled, m_action, &QAction::trigger, Qt::QueuedConnection);
QObject::connect(m_pinchGesture.get(), &PinchGesture::progress, [cb = rtPinchGesture->scaleCallback](qreal v) {
cb(v);
});
}
}
GlobalShortcut::~GlobalShortcut()
@ -94,16 +51,6 @@ const Shortcut &GlobalShortcut::shortcut() const
return m_shortcut;
}
SwipeGesture *GlobalShortcut::swipeGesture() const
{
return m_swipeGesture.get();
}
PinchGesture *GlobalShortcut::pinchGesture() const
{
return m_pinchGesture.get();
}
GlobalShortcutsManager::GlobalShortcutsManager(QObject *parent)
: QObject(parent)
, m_touchpadGestureRecognizer(new GestureRecognizer(this))
@ -141,7 +88,7 @@ void GlobalShortcutsManager::objectDeleted(QObject *object)
}
}
bool GlobalShortcutsManager::addIfNotExists(GlobalShortcut sc, DeviceType device)
bool GlobalShortcutsManager::addIfNotExists(GlobalShortcut sc, GestureDeviceType device)
{
for (const auto &cs : qAsConst(m_shortcuts)) {
if (sc.shortcut() == cs.shortcut()) {
@ -149,11 +96,15 @@ bool GlobalShortcutsManager::addIfNotExists(GlobalShortcut sc, DeviceType device
}
}
const auto &recognizer = device == DeviceType::Touchpad ? m_touchpadGestureRecognizer : m_touchscreenGestureRecognizer;
if (std::holds_alternative<SwipeShortcut>(sc.shortcut()) || std::holds_alternative<RealtimeFeedbackSwipeShortcut>(sc.shortcut())) {
recognizer->registerSwipeGesture(sc.swipeGesture());
} else if (std::holds_alternative<PinchShortcut>(sc.shortcut()) || std::holds_alternative<RealtimeFeedbackPinchShortcut>(sc.shortcut())) {
recognizer->registerPinchGesture(sc.pinchGesture());
// Register if GestureSHortcut
const auto &recognizer = device == GestureDeviceType::Touchpad ? m_touchpadGestureRecognizer : m_touchscreenGestureRecognizer;
if (std::holds_alternative<GestureShortcut>(sc.shortcut())) {
const GestureShortcut *shortcut = &std::get<GestureShortcut>(sc.shortcut());
if (shortcut->swipeGesture) {
recognizer->registerSwipeGesture(shortcut->swipeGesture.get());
} else {
recognizer->registerPinchGesture(shortcut->pinchGesture.get());
}
}
connect(sc.action(), &QAction::destroyed, this, &GlobalShortcutsManager::objectDeleted);
m_shortcuts.push_back(std::move(sc));
@ -170,41 +121,50 @@ void GlobalShortcutsManager::registerAxisShortcut(QAction *action, Qt::KeyboardM
addIfNotExists(GlobalShortcut(PointerAxisShortcut{modifiers, axis}, action));
}
void GlobalShortcutsManager::registerTouchpadSwipe(QAction *action, SwipeDirection direction, uint fingerCount)
void GlobalShortcutsManager::registerGesture(GestureDeviceType device, GestureDirection direction, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback)
{
addIfNotExists(GlobalShortcut(SwipeShortcut{DeviceType::Touchpad, direction, fingerCount}, action), DeviceType::Touchpad);
// Create and setup the GestureShortcut
GestureShortcut shortcut{device, direction};
if (isSwipeDirection(direction)) {
std::unique_ptr<SwipeGesture> gesture = std::make_unique<SwipeGesture>();
gesture->addFingerCount(fingerCount);
gesture->setDirection(direction);
gesture->setMinimumDelta(QSizeF(200, 200));
connect(gesture.get(), &SwipeGesture::progress, progressCallback);
connect(gesture.get(), &Gesture::triggered, onUp, &QAction::trigger, Qt::QueuedConnection);
connect(gesture.get(), &Gesture::cancelled, onUp, &QAction::trigger, Qt::QueuedConnection);
shortcut.swipeGesture = std::move(gesture);
} else if (isPinchDirection(direction)) {
std::unique_ptr<PinchGesture> gesture = std::make_unique<PinchGesture>();
gesture->addFingerCount(fingerCount);
gesture->setDirection(direction);
connect(gesture.get(), &PinchGesture::progress, progressCallback);
connect(gesture.get(), &Gesture::triggered, onUp, &QAction::trigger, Qt::QueuedConnection);
connect(gesture.get(), &Gesture::cancelled, onUp, &QAction::trigger, Qt::QueuedConnection);
shortcut.pinchGesture = std::move(gesture);
}
addIfNotExists(GlobalShortcut(std::move(shortcut), onUp), device);
}
void GlobalShortcutsManager::registerRealtimeTouchpadSwipe(QAction *action, std::function<void(qreal)> progressCallback, SwipeDirection direction, uint fingerCount)
void GlobalShortcutsManager::forceRegisterTouchscreenSwipe(QAction *onUp, std::function<void(qreal)> progressCallback, GestureDirection direction, uint fingerCount)
{
addIfNotExists(GlobalShortcut(RealtimeFeedbackSwipeShortcut{DeviceType::Touchpad, direction, progressCallback, fingerCount}, action), DeviceType::Touchpad);
}
std::unique_ptr<SwipeGesture> gesture = std::make_unique<SwipeGesture>();
gesture->addFingerCount(fingerCount);
gesture->setDirection(direction);
gesture->setMinimumDelta(QSizeF(200, 200));
connect(gesture.get(), &SwipeGesture::progress, progressCallback);
connect(gesture.get(), &Gesture::triggered, onUp, &QAction::trigger, Qt::QueuedConnection);
connect(gesture.get(), &Gesture::cancelled, onUp, &QAction::trigger, Qt::QueuedConnection);
void GlobalShortcutsManager::registerTouchpadPinch(QAction *action, PinchDirection direction, uint fingerCount)
{
addIfNotExists(GlobalShortcut(PinchShortcut{direction, fingerCount}, action), DeviceType::Touchpad);
}
void GlobalShortcutsManager::registerRealtimeTouchpadPinch(QAction *onUp, std::function<void(qreal)> progressCallback, PinchDirection direction, uint fingerCount)
{
addIfNotExists(GlobalShortcut(RealtimeFeedbackPinchShortcut{direction, progressCallback, fingerCount}, onUp), DeviceType::Touchpad);
}
void GlobalShortcutsManager::registerTouchscreenSwipe(QAction *action, std::function<void(qreal)> progressCallback, SwipeDirection direction, uint fingerCount)
{
addIfNotExists(GlobalShortcut(RealtimeFeedbackSwipeShortcut{DeviceType::Touchscreen, direction, progressCallback, fingerCount}, action), DeviceType::Touchscreen);
}
void GlobalShortcutsManager::forceRegisterTouchscreenSwipe(QAction *action, std::function<void(qreal)> progressCallback, SwipeDirection direction, uint fingerCount)
{
GlobalShortcut shortcut{RealtimeFeedbackSwipeShortcut{DeviceType::Touchscreen, direction, progressCallback, fingerCount}, action};
GlobalShortcut shortcut{GestureShortcut{GestureDeviceType::Touchscreen, direction, std::move(gesture)}, onUp};
const auto it = std::find_if(m_shortcuts.begin(), m_shortcuts.end(), [&shortcut](const auto &s) {
return shortcut.shortcut() == s.shortcut();
});
if (it != m_shortcuts.end()) {
m_shortcuts.erase(it);
}
m_touchscreenGestureRecognizer->registerSwipeGesture(shortcut.swipeGesture());
m_touchscreenGestureRecognizer->registerSwipeGesture(gesture.get());
connect(shortcut.action(), &QAction::destroyed, this, &GlobalShortcutsManager::objectDeleted);
m_shortcuts.push_back(std::move(shortcut));
}
@ -257,7 +217,7 @@ bool GlobalShortcutsManager::processKeyRelease(Qt::KeyboardModifiers mods, int k
}
template<typename ShortcutKind, typename... Args>
bool match(QVector<GlobalShortcut> &shortcuts, Args... args)
bool match(std::vector<GlobalShortcut> &shortcuts, Args... args)
{
for (auto &sc : shortcuts) {
if (std::holds_alternative<ShortcutKind>(sc.shortcut())) {
@ -281,36 +241,36 @@ bool GlobalShortcutsManager::processAxis(Qt::KeyboardModifiers mods, PointerAxis
return match<PointerAxisShortcut>(m_shortcuts, mods, axis);
}
void GlobalShortcutsManager::processSwipeStart(DeviceType device, uint fingerCount)
void GlobalShortcutsManager::processSwipeStart(GestureDeviceType device, uint fingerCount)
{
if (device == DeviceType::Touchpad) {
if (device == GestureDeviceType::Touchpad) {
m_touchpadGestureRecognizer->startSwipeGesture(fingerCount);
} else {
m_touchscreenGestureRecognizer->startSwipeGesture(fingerCount);
}
}
void GlobalShortcutsManager::processSwipeUpdate(DeviceType device, const QSizeF &delta)
void GlobalShortcutsManager::processSwipeUpdate(GestureDeviceType device, const QSizeF &delta)
{
if (device == DeviceType::Touchpad) {
if (device == GestureDeviceType::Touchpad) {
m_touchpadGestureRecognizer->updateSwipeGesture(delta);
} else {
m_touchscreenGestureRecognizer->updateSwipeGesture(delta);
}
}
void GlobalShortcutsManager::processSwipeCancel(DeviceType device)
void GlobalShortcutsManager::processSwipeCancel(GestureDeviceType device)
{
if (device == DeviceType::Touchpad) {
if (device == GestureDeviceType::Touchpad) {
m_touchpadGestureRecognizer->cancelSwipeGesture();
} else {
m_touchscreenGestureRecognizer->cancelSwipeGesture();
}
}
void GlobalShortcutsManager::processSwipeEnd(DeviceType device)
void GlobalShortcutsManager::processSwipeEnd(GestureDeviceType device)
{
if (device == DeviceType::Touchpad) {
if (device == GestureDeviceType::Touchpad) {
m_touchpadGestureRecognizer->endSwipeGesture();
} else {
m_touchscreenGestureRecognizer->endSwipeGesture();
@ -338,4 +298,13 @@ void GlobalShortcutsManager::processPinchEnd()
m_touchpadGestureRecognizer->endPinchGesture();
}
Gesture *GestureShortcut::gesture() const
{
if (swipeGesture != nullptr) {
return swipeGesture.get();
} else {
return pinchGesture.get();
}
}
} // namespace

View file

@ -9,6 +9,7 @@
#ifndef KWIN_GLOBALSHORTCUTS_H
#define KWIN_GLOBALSHORTCUTS_H
// KWin
#include "gestures.h"
#include <kwinglobals.h>
// Qt
#include <QKeySequence>
@ -22,14 +23,6 @@ class KGlobalAccelInterface;
namespace KWin
{
class GlobalShortcut;
class SwipeGesture;
class PinchGesture;
class GestureRecognizer;
enum class DeviceType {
Touchpad,
Touchscreen
};
/**
* @brief Manager for the global shortcut system inside KWin.
@ -65,16 +58,9 @@ public:
*/
void registerAxisShortcut(QAction *action, Qt::KeyboardModifiers modifiers, PointerAxisDirection axis);
void registerTouchpadSwipe(QAction *action, SwipeDirection direction, uint fingerCount = 4);
void registerGesture(GestureDeviceType device, GestureDirection direction, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback = nullptr);
void registerRealtimeTouchpadSwipe(QAction *onUp, std::function<void(qreal)> progressCallback, SwipeDirection direction, uint fingerCount = 4);
void registerTouchpadPinch(QAction *action, PinchDirection direction, uint fingerCount = 4);
void registerRealtimeTouchpadPinch(QAction *onUp, std::function<void(qreal)> progressCallback, PinchDirection direction, uint fingerCount = 4);
void registerTouchscreenSwipe(QAction *action, std::function<void(qreal)> progressCallback, SwipeDirection direction, uint fingerCount);
void forceRegisterTouchscreenSwipe(QAction *action, std::function<void(qreal)> progressCallback, SwipeDirection direction, uint fingerCount);
void forceRegisterTouchscreenSwipe(QAction *action, std::function<void(qreal)> progressCallback, GestureDirection direction, uint fingerCount);
/**
* @brief Processes a key event to decide whether a shortcut needs to be triggered.
@ -103,10 +89,10 @@ public:
*/
bool processAxis(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis);
void processSwipeStart(DeviceType device, uint fingerCount);
void processSwipeUpdate(DeviceType device, const QSizeF &delta);
void processSwipeCancel(DeviceType device);
void processSwipeEnd(DeviceType device);
void processSwipeStart(GestureDeviceType device, uint fingerCount);
void processSwipeUpdate(GestureDeviceType device, const QSizeF &delta);
void processSwipeCancel(GestureDeviceType device);
void processSwipeEnd(GestureDeviceType device);
void processPinchStart(uint fingerCount);
void processPinchUpdate(qreal scale, qreal angleDelta, const QSizeF &delta);
@ -120,9 +106,9 @@ public:
private:
void objectDeleted(QObject *object);
bool addIfNotExists(GlobalShortcut sc, DeviceType device = DeviceType::Touchpad);
bool addIfNotExists(GlobalShortcut sc, GestureDeviceType device = GestureDeviceType::Touchpad);
QVector<GlobalShortcut> m_shortcuts;
std::vector<GlobalShortcut> m_shortcuts;
std::unique_ptr<KGlobalAccelD> m_kglobalAccel;
KGlobalAccelInterface *m_kglobalAccelInterface = nullptr;
@ -156,54 +142,22 @@ struct PointerAxisShortcut
return axisModifiers == rhs.axisModifiers && axisDirection == rhs.axisDirection;
}
};
struct SwipeShortcut
struct GestureShortcut
{
DeviceType device;
SwipeDirection direction;
uint fingerCount;
bool operator==(const SwipeShortcut &rhs) const
{
return direction == rhs.direction && fingerCount == rhs.fingerCount && device == rhs.device;
}
};
struct RealtimeFeedbackSwipeShortcut
{
DeviceType device;
SwipeDirection direction;
std::function<void(qreal)> progressCallback;
uint fingerCount;
GestureDeviceType device;
GestureDirections direction;
template<typename T>
bool operator==(const T &rhs) const
Gesture *gesture() const;
std::unique_ptr<SwipeGesture> swipeGesture;
std::unique_ptr<PinchGesture> pinchGesture;
bool operator==(const GestureShortcut &shortcut) const
{
return direction == rhs.direction && fingerCount == rhs.fingerCount && device == rhs.device;
return device == shortcut.device && direction == shortcut.direction && gesture()->acceptableFingerCounts() == shortcut.gesture()->acceptableFingerCounts();
}
};
struct PinchShortcut
{
PinchDirection direction;
uint fingerCount;
bool operator==(const PinchShortcut &rhs) const
{
return direction == rhs.direction && fingerCount == rhs.fingerCount;
}
};
struct RealtimeFeedbackPinchShortcut
{
PinchDirection direction;
std::function<void(qreal)> scaleCallback;
uint fingerCount;
template<typename T>
bool operator==(const T &rhs) const
{
return direction == rhs.direction && fingerCount == rhs.fingerCount;
}
};
using Shortcut = std::variant<KeyboardShortcut, PointerButtonShortcut, PointerAxisShortcut, SwipeShortcut, RealtimeFeedbackSwipeShortcut, PinchShortcut, RealtimeFeedbackPinchShortcut>;
using Shortcut = std::variant<KeyboardShortcut, PointerButtonShortcut, PointerAxisShortcut, GestureShortcut>;
class GlobalShortcut
{
@ -211,15 +165,14 @@ public:
GlobalShortcut(Shortcut &&shortcut, QAction *action);
~GlobalShortcut();
GlobalShortcut(GlobalShortcut &&sc) = default;
GlobalShortcut &operator=(GlobalShortcut &&sc) = default;
void invoke() const;
QAction *action() const;
const Shortcut &shortcut() const;
SwipeGesture *swipeGesture() const;
PinchGesture *pinchGesture() const;
private:
std::shared_ptr<SwipeGesture> m_swipeGesture;
std::shared_ptr<PinchGesture> m_pinchGesture;
Shortcut m_shortcut = {};
QAction *m_action = nullptr;
};

View file

@ -1011,7 +1011,7 @@ public:
Q_UNUSED(time)
m_touchpadGestureFingerCount = fingerCount;
if (m_touchpadGestureFingerCount >= 3) {
input()->shortcuts()->processSwipeStart(DeviceType::Touchpad, fingerCount);
input()->shortcuts()->processSwipeStart(GestureDeviceType::Touchpad, fingerCount);
return true;
} else {
return false;
@ -1021,7 +1021,7 @@ public:
{
Q_UNUSED(time)
if (m_touchpadGestureFingerCount >= 3) {
input()->shortcuts()->processSwipeUpdate(DeviceType::Touchpad, delta);
input()->shortcuts()->processSwipeUpdate(GestureDeviceType::Touchpad, delta);
return true;
} else {
return false;
@ -1031,7 +1031,7 @@ public:
{
Q_UNUSED(time)
if (m_touchpadGestureFingerCount >= 3) {
input()->shortcuts()->processSwipeCancel(DeviceType::Touchpad);
input()->shortcuts()->processSwipeCancel(GestureDeviceType::Touchpad);
return true;
} else {
return false;
@ -1041,7 +1041,7 @@ public:
{
Q_UNUSED(time)
if (m_touchpadGestureFingerCount >= 3) {
input()->shortcuts()->processSwipeEnd(DeviceType::Touchpad);
input()->shortcuts()->processSwipeEnd(GestureDeviceType::Touchpad);
return true;
} else {
return false;
@ -1091,7 +1091,7 @@ public:
bool touchDown(qint32 id, const QPointF &pos, quint32 time) override
{
if (m_gestureTaken) {
input()->shortcuts()->processSwipeCancel(DeviceType::Touchscreen);
input()->shortcuts()->processSwipeCancel(GestureDeviceType::Touchscreen);
m_gestureCancelled = true;
return true;
} else {
@ -1125,7 +1125,7 @@ public:
m_syntheticCancel = true;
input()->processFilters(std::bind(&InputEventFilter::touchCancel, std::placeholders::_1));
m_syntheticCancel = false;
input()->shortcuts()->processSwipeStart(DeviceType::Touchscreen, m_touchPoints.count());
input()->shortcuts()->processSwipeStart(GestureDeviceType::Touchscreen, m_touchPoints.count());
return true;
}
}
@ -1146,7 +1146,7 @@ public:
auto &point = m_touchPoints[id];
const QPointF dist = pos - point;
const QSizeF delta = QSizeF(xfactor * dist.x(), yfactor * dist.y());
input()->shortcuts()->processSwipeUpdate(DeviceType::Touchscreen, 5 * delta / m_touchPoints.size());
input()->shortcuts()->processSwipeUpdate(GestureDeviceType::Touchscreen, 5 * delta / m_touchPoints.size());
point = pos;
return true;
}
@ -1159,7 +1159,7 @@ public:
m_touchPoints.remove(id);
if (m_gestureTaken) {
if (!m_gestureCancelled) {
input()->shortcuts()->processSwipeEnd(DeviceType::Touchscreen);
input()->shortcuts()->processSwipeEnd(GestureDeviceType::Touchscreen);
m_gestureCancelled = true;
}
m_gestureTaken &= m_touchPoints.count() > 0;
@ -3309,24 +3309,9 @@ void InputRedirection::registerAxisShortcut(Qt::KeyboardModifiers modifiers, Poi
m_shortcuts->registerAxisShortcut(action, modifiers, axis);
}
void InputRedirection::registerRealtimeTouchpadSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> cb)
void InputRedirection::registerGesture(GestureDeviceType device, GestureDirection direction, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback)
{
m_shortcuts->registerRealtimeTouchpadSwipe(action, cb, direction, fingerCount);
}
void InputRedirection::registerTouchpadSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action)
{
m_shortcuts->registerTouchpadSwipe(action, direction, fingerCount);
}
void InputRedirection::registerTouchpadPinchShortcut(PinchDirection direction, uint fingerCount, QAction *action)
{
m_shortcuts->registerTouchpadPinch(action, direction, fingerCount);
}
void InputRedirection::registerRealtimeTouchpadPinchShortcut(PinchDirection direction, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback)
{
m_shortcuts->registerRealtimeTouchpadPinch(onUp, progressCallback, direction, fingerCount);
m_shortcuts->registerGesture(device, direction, fingerCount, onUp, progressCallback);
}
void InputRedirection::registerGlobalAccel(KGlobalAccelInterface *interface)
@ -3334,12 +3319,7 @@ void InputRedirection::registerGlobalAccel(KGlobalAccelInterface *interface)
m_shortcuts->setKGlobalAccelInterface(interface);
}
void InputRedirection::registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback)
{
m_shortcuts->registerTouchscreenSwipe(action, progressCallback, direction, fingerCount);
}
void InputRedirection::forceRegisterTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback)
void InputRedirection::forceRegisterTouchscreenSwipeShortcut(GestureDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback)
{
m_shortcuts->forceRegisterTouchscreenSwipe(action, progressCallback, direction, fingerCount);
}

View file

@ -136,14 +136,9 @@ public:
void registerShortcut(const QKeySequence &shortcut, QAction *action, T *receiver, Slot slot);
void registerPointerShortcut(Qt::KeyboardModifiers modifiers, Qt::MouseButton pointerButtons, QAction *action);
void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action);
void registerTouchpadSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action);
void registerRealtimeTouchpadSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback);
void registerTouchpadPinchShortcut(PinchDirection direction, uint fingerCount, QAction *action);
void registerRealtimeTouchpadPinchShortcut(PinchDirection direction, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback);
void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback);
void forceRegisterTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback);
void registerGesture(GestureDeviceType device, GestureDirection direction, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback);
void forceRegisterTouchscreenSwipeShortcut(GestureDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback);
void registerGlobalAccel(KGlobalAccelInterface *interface);
bool supportsPointerWarping() const;
void warpPointer(const QPointF &pos);

View file

@ -887,28 +887,14 @@ public:
virtual void registerAxisShortcut(Qt::KeyboardModifiers modifiers, PointerAxisDirection axis, QAction *action) = 0;
/**
* @brief Registers a global touchpad swipe gesture shortcut with the provided @p action.
* @brief Registers a global gesture shortcut with the provided @p action.
*
* @param direction The direction for the swipe
* @param action The action which gets triggered when the gesture triggers
* @since 5.10
* @param device The device for the gesture
* @param direction The direction of the gesture
* @param action The action which gets triggered when the gesture is released
* @since 5.26
*/
virtual void registerTouchpadSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action) = 0;
virtual void registerRealtimeTouchpadSwipeShortcut(SwipeDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback) = 0;
virtual void registerRealtimeTouchpadPinchShortcut(PinchDirection dir, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback) = 0;
virtual void registerTouchpadPinchShortcut(PinchDirection direction, uint fingerCount, QAction *action) = 0;
/**
* @brief Registers a global touchscreen swipe gesture shortcut with the provided @p action.
*
* @param direction The direction for the swipe
* @param action The action which gets triggered when the gesture triggers
* @since 5.25
*/
virtual void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function<void(qreal)> progressCallback) = 0;
virtual void registerGesture(GestureDeviceType device, GestureDirection direction, uint fingerCount, QAction *onUp, std::function<void(qreal)> progressCallback = nullptr) = 0;
/**
* Retrieve the proxy class for an effect if it has one. Will return NULL if

View file

@ -13,6 +13,7 @@
#include <QCoreApplication>
#include <QImage>
#include <QPoint>
#include <QSet>
#include <QVariant>
#include <kwin_export.h>
@ -116,20 +117,11 @@ enum PointerAxisDirection {
};
/**
* @brief Directions for swipe gestures
* @since 5.10
* @brief What device is this gesture using?
*/
enum class SwipeDirection {
Invalid,
Down,
Left,
Up,
Right,
};
enum class PinchDirection {
Expanding,
Contracting
enum class GestureDeviceType {
Touchpad,
Touchscreen
};
/**
@ -229,6 +221,33 @@ inline KWIN_EXPORT QRect infiniteRegion()
} // namespace
/**
* @brief Directions for gestures
* @since 5.25
*/
enum class GestureDirection {
Up = 1 << 1,
Down = 1 << 2,
Left = 1 << 3,
Right = 1 << 4,
Expanding = 1 << 5,
Contracting = 1 << 6,
};
Q_DECLARE_FLAGS(GestureDirections, GestureDirection)
Q_DECLARE_OPERATORS_FOR_FLAGS(GestureDirections)
Q_DECLARE_METATYPE(GestureDirection)
static bool isSwipeDirection(GestureDirections d)
{
return d & (GestureDirection::Up | GestureDirection::Down | GestureDirection::Left | GestureDirection::Right);
}
static bool isPinchDirection(GestureDirections d)
{
return d & (GestureDirection::Contracting | GestureDirection::Expanding);
}
Q_DECLARE_METATYPE(std::chrono::nanoseconds)
#define KWIN_SINGLETON_VARIABLE(ClassName, variableName) \

View file

@ -101,8 +101,7 @@ Edge::Edge(ScreenEdges *parent)
, m_output(nullptr)
, m_gesture(new SwipeGesture(this))
{
m_gesture->setMinimumFingerCount(1);
m_gesture->setMaximumFingerCount(1);
m_gesture->addFingerCount(1);
connect(
m_gesture, &Gesture::triggered, this, [this]() {
stopApproaching();
@ -713,16 +712,16 @@ void Edge::setBorder(ElectricBorder border)
m_border = border;
switch (m_border) {
case ElectricTop:
m_gesture->setDirection(SwipeGesture::Direction::Down);
m_gesture->setDirection(GestureDirection::Down);
break;
case ElectricRight:
m_gesture->setDirection(SwipeGesture::Direction::Left);
m_gesture->setDirection(GestureDirection::Left);
break;
case ElectricBottom:
m_gesture->setDirection(SwipeGesture::Direction::Up);
m_gesture->setDirection(GestureDirection::Up);
break;
case ElectricLeft:
m_gesture->setDirection(SwipeGesture::Direction::Right);
m_gesture->setDirection(GestureDirection::Right);
break;
default:
break;

View file

@ -821,24 +821,24 @@ void VirtualDesktopManager::initShortcuts()
Q_EMIT currentChanging(current(), m_currentDesktopOffset);
}
};
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Left, 3, m_swipeGestureReleasedX.get(), left);
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Right, 3, m_swipeGestureReleasedX.get(), right);
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Left, 4, m_swipeGestureReleasedX.get(), left);
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Right, 4, m_swipeGestureReleasedX.get(), right);
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Down, 3, m_swipeGestureReleasedY.get(), [this](qreal cb) {
input()->registerGesture(GestureDeviceType::Touchpad, GestureDirection::Left, 3, m_swipeGestureReleasedX.get(), left);
input()->registerGesture(GestureDeviceType::Touchpad, GestureDirection::Right, 3, m_swipeGestureReleasedX.get(), right);
input()->registerGesture(GestureDeviceType::Touchpad, GestureDirection::Left, 4, m_swipeGestureReleasedX.get(), left);
input()->registerGesture(GestureDeviceType::Touchpad, GestureDirection::Right, 4, m_swipeGestureReleasedX.get(), right);
input()->registerGesture(GestureDeviceType::Touchpad, GestureDirection::Down, 3, m_swipeGestureReleasedY.get(), [this](qreal cb) {
if (grid().height() > 1) {
m_currentDesktopOffset.setY(-cb);
Q_EMIT currentChanging(current(), m_currentDesktopOffset);
}
});
input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Up, 3, m_swipeGestureReleasedY.get(), [this](qreal cb) {
input()->registerGesture(GestureDeviceType::Touchpad, GestureDirection::Up, 3, m_swipeGestureReleasedY.get(), [this](qreal cb) {
if (grid().height() > 1) {
m_currentDesktopOffset.setY(cb);
Q_EMIT currentChanging(current(), m_currentDesktopOffset);
}
});
input()->registerTouchscreenSwipeShortcut(SwipeDirection::Left, 3, m_swipeGestureReleasedX.get(), left);
input()->registerTouchscreenSwipeShortcut(SwipeDirection::Right, 3, m_swipeGestureReleasedX.get(), right);
input()->registerGesture(GestureDeviceType::Touchscreen, GestureDirection::Left, 3, m_swipeGestureReleasedX.get(), left);
input()->registerGesture(GestureDeviceType::Touchscreen, GestureDirection::Right, 3, m_swipeGestureReleasedX.get(), right);
// axis events
input()->registerAxisShortcut(Qt::ControlModifier | Qt::AltModifier, PointerAxisDown,