From d23781d87a90ce113d2208f4fbabb461e49041e2 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Sun, 11 Sep 2022 13:14:02 +0300 Subject: [PATCH] Revert "Clarify interface and improve documentation in gesture" This reverts commit 6c0ed1480064af04d9d7859db1f1a243889f50a8. It was pushed with unreviewed changes and not fully resolved issues. --- autotests/test_gestures.cpp | 1 - src/effects/desktopgrid/desktopgrideffect.cpp | 1 - src/effects/overview/overvieweffect.cpp | 1 - src/effects/windowview/windowvieweffect.cpp | 1 - src/gestures.cpp | 130 ++++++++++-------- src/gestures.h | 58 ++++++-- src/globalshortcuts.cpp | 6 +- src/libkwineffects/kwinglobals.h | 8 +- 8 files changed, 126 insertions(+), 80 deletions(-) diff --git a/autotests/test_gestures.cpp b/autotests/test_gestures.cpp index 1900727f31..ebcd4d68f4 100644 --- a/autotests/test_gestures.cpp +++ b/autotests/test_gestures.cpp @@ -279,7 +279,6 @@ void GestureTest::testSwipeUpdateTrigger() SwipeGesture gesture; QFETCH(GestureDirection, direction); gesture.setDirection(direction); - gesture.setTriggerDelta(QSizeF(1, 1)); QSignalSpy triggeredSpy(&gesture, &SwipeGesture::triggered); QVERIFY(triggeredSpy.isValid()); diff --git a/src/effects/desktopgrid/desktopgrideffect.cpp b/src/effects/desktopgrid/desktopgrideffect.cpp index 577f5816ea..095beac581 100644 --- a/src/effects/desktopgrid/desktopgrideffect.cpp +++ b/src/effects/desktopgrid/desktopgrideffect.cpp @@ -62,7 +62,6 @@ DesktopGridEffect::DesktopGridEffect() }); effects->registerGesture(GestureDeviceType::Touchpad, GestureDirection::Up, 4, m_realtimeToggleAction, [this](qreal progress) { - progress = std::clamp(progress, 0.0, 1.0); if (!effects->hasActiveFullScreenEffect() || effects->activeFullScreenEffect() == this) { switch (m_status) { case Status::Inactive: diff --git a/src/effects/overview/overvieweffect.cpp b/src/effects/overview/overvieweffect.cpp index 5a5cd6c2fe..98f9e5a3ff 100644 --- a/src/effects/overview/overvieweffect.cpp +++ b/src/effects/overview/overvieweffect.cpp @@ -52,7 +52,6 @@ OverviewEffect::OverviewEffect() }); auto progressCallback = [this](qreal progress) { - progress = std::clamp(progress, 0.0, 1.1); if (!effects->hasActiveFullScreenEffect() || effects->activeFullScreenEffect() == this) { switch (m_status) { case Status::Inactive: diff --git a/src/effects/windowview/windowvieweffect.cpp b/src/effects/windowview/windowvieweffect.cpp index b07eaead12..749b609e3d 100644 --- a/src/effects/windowview/windowvieweffect.cpp +++ b/src/effects/windowview/windowvieweffect.cpp @@ -111,7 +111,6 @@ WindowViewEffect::WindowViewEffect() }); const auto gestureCallback = [this](qreal progress) { - progress = std::clamp(progress, 0.0, 1.1); if (!effects->hasActiveFullScreenEffect() || effects->activeFullScreenEffect() == this) { switch (m_status) { case Status::Inactive: diff --git a/src/gestures.cpp b/src/gestures.cpp index ce7351e9af..3dc4956b22 100644 --- a/src/gestures.cpp +++ b/src/gestures.cpp @@ -47,34 +47,17 @@ qreal SwipeGesture::getTriggerProgress(const QSizeF &delta) const return 1.0; } - qreal progress = 0.0; - - if (m_direction & GestureDirection::Up) { - qreal candidate = -delta.height() / m_triggerDelta.height(); - if (candidate > progress) { - progress = candidate; - } - } - if (m_direction & GestureDirection::Down) { - qreal candidate = delta.height() / m_triggerDelta.height(); - if (candidate > progress) { - progress = candidate; - } - } - if (m_direction & GestureDirection::Left) { - qreal candidate = -delta.width() / m_triggerDelta.width(); - if (candidate > progress) { - progress = candidate; - } - } - if (m_direction & GestureDirection::Right) { - qreal candidate = delta.width() / m_triggerDelta.width(); - if (candidate > progress) { - progress = candidate; - } + if (m_direction.testFlag(GestureDirection::DirectionlessSwipe)) { + return std::min(std::hypot(delta.width(), delta.height()) / m_triggerDelta.width(), 1.0); } - return std::clamp(progress, 0.0, 1.0); + if (m_direction & GestureDirection::VerticalAxis) { + return std::min(std::abs(delta.height()) / std::abs(m_triggerDelta.height()), 1.0); + } else if (m_direction & GestureDirection::HorizontalAxis) { + return std::min(std::abs(delta.width()) / std::abs(m_triggerDelta.width()), 1.0); + } + + return 1.0; } bool SwipeGesture::triggerDeltaReached(const QSizeF &delta) const @@ -184,12 +167,13 @@ int GestureRecognizer::startSwipeGesture(uint fingerCount, const QPointF &startP } // Only add gestures who's direction aligns with current swipe axis - if (m_currentSwipeAxis == Axis::Vertical) { - if (!(gesture->direction() & (GestureDirection::Up | GestureDirection::Down))) { + if (gesture->direction().testFlag(GestureDirection::DirectionlessSwipe)) { + } else if (gesture->direction() & GestureDirection::VerticalAxis) { + if (m_currentSwipeAxis == Axis::Horizontal) { continue; } - } else if (m_currentSwipeAxis == Axis::Horizontal) { - if (!(gesture->direction() & (GestureDirection::Left | GestureDirection::Right))) { + } else if (gesture->direction() & GestureDirection::HorizontalAxis) { + if (m_currentSwipeAxis == Axis::Vertical) { continue; } } @@ -266,9 +250,36 @@ void GestureRecognizer::updateSwipeGesture(const QSizeF &delta) Q_EMIT g->triggerProgress(g->getTriggerProgress(m_currentDelta)); Q_EMIT g->semanticProgress(g->getSemanticProgress(m_currentDelta), g->direction()); Q_EMIT g->pixelDelta(m_currentDelta, g->direction()); + Q_EMIT g->semanticDelta(g->getSemanticDelta(m_currentDelta), g->direction()); + if (!g->direction().testFlag(GestureDirection::DirectionlessSwipe)) { + Q_EMIT g->semanticProgressAxis(g->getSemanticAxisProgress(m_currentDelta), g->direction()); + } + Q_EMIT g->swipePixelVector(QVector2D(m_currentDelta.width(), m_currentDelta.height())); } } +bool GestureRecognizer::mutuallyExclusive(GestureDirections currentDir, GestureDirections gestureDir) +{ + if (currentDir == gestureDir) { + return false; + } + if (gestureDir.testFlag(GestureDirection::DirectionlessSwipe)) { + return false; + } + + if (currentDir & GestureDirection::VerticalAxis) { + if (gestureDir.testFlag(GestureDirection::VerticalAxis)) { + return false; + } + } else if (currentDir & GestureDirection::HorizontalAxis) { + if (gestureDir.testFlag(GestureDirection::HorizontalAxis)) { + return false; + } + } + + return true; +} + void GestureRecognizer::cancelActiveGestures() { for (auto g : qAsConst(m_activeSwipeGestures)) { @@ -363,6 +374,7 @@ void GestureRecognizer::updatePinchGesture(qreal scale, qreal angleDelta, const for (PinchGesture *g : std::as_const(m_activePinchGestures)) { Q_EMIT g->triggerProgress(g->getTriggerProgress(scale)); Q_EMIT g->semanticProgress(g->getSemanticProgress(scale), g->direction()); + Q_EMIT g->semanticProgressAxis(g->getSemanticAxisProgress(scale), g->direction()); } } @@ -461,7 +473,6 @@ QSizeF SwipeGesture::triggerDelta() const void SwipeGesture::setTriggerDelta(const QSizeF &delta) { - Q_ASSERT(delta.width() >= 0 && delta.height() >= 0); m_triggerDelta = delta; m_triggerDeltaRelevant = true; } @@ -492,36 +503,25 @@ int GestureRecognizer::startSwipeGesture(uint fingerCount) return startSwipeGesture(fingerCount, QPointF(), StartPositionBehavior::Irrelevant); } +QSizeF SwipeGesture::getSemanticDelta(const QSizeF &delta) const +{ + QSizeF d = QSizeF(); + d.setWidth(delta.width() / m_unitDelta); + d.setHeight(delta.height() / m_unitDelta); + return d; +} + qreal SwipeGesture::getSemanticProgress(const QSizeF &delta) const { - qreal progress = 0; - - if (direction() & GestureDirection::Up) { - qreal val = -delta.height() / m_unitDelta; - if (val > progress) { - progress = val; - } - } - if (direction() & GestureDirection::Down) { - qreal val = delta.height() / m_unitDelta; - if (val > progress) { - progress = val; - } - } - if (direction() & GestureDirection::Left) { - qreal val = -delta.width() / m_unitDelta; - if (val > progress) { - progress = val; - } - } - if (direction() & GestureDirection::Right) { - qreal val = delta.width() / m_unitDelta; - if (val > progress) { - progress = val; - } + if (m_direction.testFlag(GestureDirection::DirectionlessSwipe)) { + return std::hypot(delta.width(), delta.height()) / m_unitDelta; + } else if (m_direction & GestureDirection::VerticalAxis) { + return std::abs(delta.height()) / m_unitDelta; + } else if (m_direction & GestureDirection::HorizontalAxis) { + return std::abs(delta.width()) / m_unitDelta; } - return progress; + return 1.0; } qreal PinchGesture::getSemanticProgress(const qreal scale) const @@ -529,6 +529,22 @@ qreal PinchGesture::getSemanticProgress(const qreal scale) const return std::max(std::abs(1 - scale) / m_unitScaleDelta, 0.0); } +qreal SwipeGesture::getSemanticAxisProgress(const QSizeF &delta) const +{ + if (m_direction & GestureDirection::VerticalAxis) { + return delta.height() / m_unitDelta; + } else if (m_direction & GestureDirection::HorizontalAxis) { + return delta.width() / m_unitDelta; + } + + return 1.0; +} + +qreal PinchGesture::getSemanticAxisProgress(const qreal scale) const +{ + return (scale - 1) / m_unitScaleDelta; +} + int GestureRecognizer::startSwipeGesture(const QPointF &startPos) { return startSwipeGesture(1, startPos, StartPositionBehavior::Relevant); diff --git a/src/gestures.h b/src/gestures.h index 987066ee7c..2070585e5e 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -27,7 +27,7 @@ static const QSet DEFAULT_VALID_FINGER_COUNTS = {1, 2, 3, 4, 5, 6, 7, 8, 9 /** * This is the amount of change for 1 unit of change, like switch by 1 desktop. */ -static const qreal DEFAULT_UNIT_DELTA = 200; // Pixels +static const qreal DEFAULT_UNIT_DELTA = 400; // Pixels static const qreal DEFAULT_UNIT_SCALE_DELTA = .2; // 20% class Gesture : public QObject @@ -74,7 +74,7 @@ Q_SIGNALS: */ void cancelled(); /** - * Progress towards the minimum threshold to trigger. [0, 1] + * Progress towards the minimum threshold to trigger */ void triggerProgress(qreal); /** @@ -84,6 +84,13 @@ Q_SIGNALS: * It can be more than 1, indicating an action should happen more than once. */ void semanticProgress(qreal, GestureDirections); + /** + * Like semantic progress except [-1, 1] and + * it captures both of something + * example: Up and Down (VerticalAxis), Contracting and Expanding (BiDirectionalPinch) + * Positive values are Up, Right and Expanding + */ + void semanticProgressAxis(qreal, GestureDirections); private: QSet m_validFingerCounts = DEFAULT_VALID_FINGER_COUNTS; @@ -111,19 +118,10 @@ public: bool maximumYIsRelevant() const; void setStartGeometry(const QRect &geometry); - /** - * In pixels - */ QSizeF triggerDelta() const; void setTriggerDelta(const QSizeF &delta); bool isTriggerDeltaRelevant() const; - /** - * Returns the progress [0, 1] of the gesture - * being triggered. Picks the largest possible value - * considering each direction available to the - * gesture. - */ qreal getTriggerProgress(const QSizeF &delta) const; bool triggerDeltaReached(const QSizeF &delta) const; @@ -136,6 +134,17 @@ public: * that the action should be done more times. */ qreal getSemanticProgress(const QSizeF &delta) const; + /** + * Like the last one, except [-1, 1] + * Positive values are Up and Right + */ + qreal getSemanticAxisProgress(const QSizeF &delta) const; + /** + * A two dimensional semantic delta. + * [-1, 1] on each axis. + * Positive is Up and Right + */ + QSizeF getSemanticDelta(const QSizeF &delta) const; Q_SIGNALS: /** @@ -143,6 +152,17 @@ Q_SIGNALS: * started to where it is now. */ void pixelDelta(const QSizeF &delta, GestureDirections); + /** + * A 2d coordinate giving the semantic axis delta + * [-1, 1] on both horizontal and vertical axes. + */ + void semanticDelta(const QSizeF &delta, GestureDirections); + /** + * GIves a 2d vector of pointing from + * where the gesture started to where + * it is now. + */ + void swipePixelVector(const QVector2D &vector); private: bool m_minimumXRelevant = false; @@ -174,9 +194,6 @@ public: void setTriggerScaleDelta(const qreal &scaleDelta); bool isTriggerScaleDeltaRelevant() const; - /** - * [0, 1] - */ qreal getTriggerProgress(const qreal &scaleDelta) const; bool triggerScaleDeltaReached(const qreal &scaleDelta) const; @@ -189,6 +206,18 @@ public: * that the action should be done more times. */ qreal getSemanticProgress(const qreal scale) const; + /** + * Like the last one, except [-1, 1] + * Positive is expanding. + * Positive values are Expanding + */ + qreal getSemanticAxisProgress(const qreal scale) const; + +Q_SIGNALS: + /** + * The progress is reported in [0.0,1.0] + */ + void triggerProgress(qreal); private: bool m_triggerScaleDeltaRelevant = false; @@ -222,6 +251,7 @@ public: private: void cancelActiveGestures(); + bool mutuallyExclusive(GestureDirections d, GestureDirections gestureDir); enum class StartPositionBehavior { Relevant, Irrelevant, diff --git a/src/globalshortcuts.cpp b/src/globalshortcuts.cpp index dc9b4bf321..273d0c77c9 100644 --- a/src/globalshortcuts.cpp +++ b/src/globalshortcuts.cpp @@ -131,14 +131,14 @@ void GlobalShortcutsManager::registerGesture(GestureDeviceType device, GestureDi std::unique_ptr gesture = std::make_unique(); gesture->addFingerCount(fingerCount); gesture->setTriggerDelta(QSizeF(200, 200)); - connect(gesture.get(), &SwipeGesture::semanticProgress, progressCallback); + connect(gesture.get(), &SwipeGesture::triggerProgress, 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 gesture = std::make_unique(); gesture->addFingerCount(fingerCount); - connect(gesture.get(), &PinchGesture::semanticProgress, progressCallback); + connect(gesture.get(), &PinchGesture::triggerProgress, 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); @@ -154,7 +154,7 @@ void GlobalShortcutsManager::forceRegisterTouchscreenSwipe(QAction *onUp, std::f gesture->addFingerCount(fingerCount); gesture->setDirection(direction); gesture->setTriggerDelta(QSizeF(200, 200)); - connect(gesture.get(), &SwipeGesture::semanticProgress, progressCallback); + connect(gesture.get(), &SwipeGesture::triggerProgress, progressCallback); connect(gesture.get(), &Gesture::triggered, onUp, &QAction::trigger, Qt::QueuedConnection); connect(gesture.get(), &Gesture::cancelled, onUp, &QAction::trigger, Qt::QueuedConnection); GestureShortcut gestureShortcut{GestureDeviceType::Touchscreen, direction}; diff --git a/src/libkwineffects/kwinglobals.h b/src/libkwineffects/kwinglobals.h index a84cef0626..89133d4cb5 100644 --- a/src/libkwineffects/kwinglobals.h +++ b/src/libkwineffects/kwinglobals.h @@ -232,18 +232,22 @@ enum class GestureDirection { Right = 1 << 4, Expanding = 1 << 5, Contracting = 1 << 6, + VerticalAxis = Up | Down, // Up is positive values + HorizontalAxis = Left | Right, // Right is positive + DirectionlessSwipe = Left | Right | Up | Down, // Positive is Up/Right + BiDirectionalPinch = Expanding | Contracting, // Positive is Expanding }; Q_DECLARE_FLAGS(GestureDirections, GestureDirection) Q_DECLARE_OPERATORS_FOR_FLAGS(GestureDirections) Q_DECLARE_METATYPE(GestureDirection) -inline bool isSwipeDirection(GestureDirections d) +static bool isSwipeDirection(GestureDirections d) { return d & (GestureDirection::Up | GestureDirection::Down | GestureDirection::Left | GestureDirection::Right); } -inline bool isPinchDirection(GestureDirections d) +static bool isPinchDirection(GestureDirections d) { return d & (GestureDirection::Contracting | GestureDirection::Expanding); }