From b7dad0ab3b550669e5f8411ae2b20a3c66f166bb Mon Sep 17 00:00:00 2001 From: taj-ny <79316397+taj-ny@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:07:48 +0200 Subject: [PATCH] libgestures: replace gesture->triggerOneActionOnly with action->blockOtheractions closes #17 --- docs/configuration.md | 6 ++-- docs/example_gestures.md | 3 +- src/kwin/config/config.cpp | 3 +- .../libgestures/actions/action.cpp | 10 ++++++ src/libgestures/libgestures/actions/action.h | 8 +++++ .../libgestures/gestures/gesture.cpp | 31 +++++++++++-------- .../libgestures/gestures/gesture.h | 12 +++---- .../gestures/test_gesturerecognizer.cpp | 23 ++++++-------- .../gestures/test_gesturerecognizer.h | 1 - 9 files changed, 56 insertions(+), 41 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 0220294..6fa634e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -14,8 +14,7 @@ See [example_gestures.md](example_gestures.md) for examples. - **Fingers** (int) - Number of fingers required to trigger this gesture.
Sets **MinimumFingers** and **MaximumFingers**.
Minimum value: **2** for hold and pinch gestures, **3** for swipe.
Default: **none** - **MinimumFingers** (int) - Minimum number of fingers required to trigger this gesture.
See **Fingers** for accepted values.
Default: **none** - **MaximumFingers** (int) - Maximum number of fingers required to trigger this gesture.
See **Fingers** for accepted values.
Default: **none** - - **TriggerWhenThresholdReached** (bool) - Whether to trigger the gesture immediately after the specified threshold is reached.
Default: **false** - - **TriggerOneActionOnly** (bool) - Whether to trigger only the first action that satisfies a condition.
Default: **false**
  + - **TriggerWhenThresholdReached** (bool) - Whether to trigger the gesture immediately after the specified threshold is reached.
Default: **false**  - **[Hold]** - Configuration for hold gestures. - **Threshold** (int) - In milliseconds.
Default: **0** - **[Pinch]** - Configuration for pinch gestures. @@ -44,7 +43,8 @@ See [example_gestures.md](example_gestures.md) for examples. - ``Command`` - Run a command. - ``GlobalShortcut`` - Invoke a global shortcut. - ``KeySequence`` - Send keystrokes. - - **RepeatInterval** (int/float) - Whether and how often this action should repeat.
Can be negative for all gestures except hold.
Default: **0 (no repeating)**
  + - **RepeatInterval** (int/float) - Whether and how often this action should repeat.
Can be negative for all gestures except hold.
Default: **0 (no repeating)** + - **BlockOtherActions** (bool) - Whether this action should block other actions if triggered.
Default: **false**
  - **[Command]** - Configuration for the GlobalShortcut action. - **Command** (string) - The command to run.
Default: **none** - **[GlobalShortcut]** - Configuration for the GlobalShortcut action. diff --git a/docs/example_gestures.md b/docs/example_gestures.md index 9c55b97..2777b64 100644 --- a/docs/example_gestures.md +++ b/docs/example_gestures.md @@ -102,7 +102,7 @@ Command=pactl set-sink-volume @DEFAULT_SINK@ +5% [Gestures][Touchpad][4] Type=Swipe Fingers=4 -TriggerWhenThresholdReached=false +TriggerWhenThresholdReached=true [Gestures][Touchpad][4][Swipe] Direction=Down @@ -123,6 +123,7 @@ Type=GlobalShortcut [Gestures][Touchpad][4][Actions][1][Conditions][0] WindowState=Maximized +BlockOtherActions=true # Prevent the minimize window action from triggering during the same gesture [Gestures][Touchpad][4][Actions][1][GlobalShortcut] Component=kwin diff --git a/src/kwin/config/config.cpp b/src/kwin/config/config.cpp index ac9d979..ca24e95 100644 --- a/src/kwin/config/config.cpp +++ b/src/kwin/config/config.cpp @@ -34,7 +34,6 @@ void Config::read(std::shared_ptr filter, std::shared_p minimumFingers = maximumFingers = fingers; } const bool triggerWhenThresholdReached = gestureGroup.readEntry("TriggerWhenThresholdReached", false); - const bool triggerOneActionOnly = gestureGroup.readEntry("TriggerOneActionOnly", false); std::shared_ptr gesture; if (gestureType == "Hold") @@ -89,7 +88,6 @@ void Config::read(std::shared_ptr filter, std::shared_p gesture->setFingers(minimumFingers, maximumFingers); gesture->setTriggerWhenThresholdReached(triggerWhenThresholdReached); - gesture->setTriggerOneActionOnly(triggerOneActionOnly); if (!gesture) continue; @@ -128,6 +126,7 @@ void Config::read(std::shared_ptr filter, std::shared_p continue; action->setRepeatInterval(actionGroup.readEntry("RepeatInterval", 0.0)); + action->setBlockOtherActions(actionGroup.readEntry("BlockOtherActions", false)); const auto conditions = readConditions(actionGroup.group("Conditions"), windowInfoProvider); for (const auto &condition : conditions) diff --git a/src/libgestures/libgestures/actions/action.cpp b/src/libgestures/libgestures/actions/action.cpp index 0669c89..183ce7b 100644 --- a/src/libgestures/libgestures/actions/action.cpp +++ b/src/libgestures/libgestures/actions/action.cpp @@ -35,6 +35,11 @@ bool GestureAction::canExecute() const return m_repeatInterval != 0 || !m_triggered; } +bool GestureAction::blocksOtherActions() const +{ + return m_triggered && m_blockOtherActions; +} + void GestureAction::onGestureCancelled() { if (m_when == When::Cancelled && canExecute() && satisfiesConditions()) @@ -82,6 +87,11 @@ void GestureAction::onGestureUpdated(const qreal &delta) } } +void GestureAction::setBlockOtherActions(const bool &blockOtherActions) +{ + m_blockOtherActions = blockOtherActions; +} + void GestureAction::setRepeatInterval(const qreal &interval) { m_repeatInterval = interval; diff --git a/src/libgestures/libgestures/actions/action.h b/src/libgestures/libgestures/actions/action.h index 39844b7..8dbb4c4 100644 --- a/src/libgestures/libgestures/actions/action.h +++ b/src/libgestures/libgestures/actions/action.h @@ -24,6 +24,12 @@ class GestureAction : public QObject bool repeat() const { return m_repeatInterval != 0; }; + /** + * @return Whether any other actions belonging to a gesture should not be executed. @c true if the action has been + * executed and blockOtherActions has been set to @c true, @c false otherwise. + */ + [[nodiscard]] bool blocksOtherActions() const; + void addCondition(const std::shared_ptr &condition); /** @@ -32,6 +38,7 @@ class GestureAction : public QObject */ bool satisfiesConditions() const; + void setBlockOtherActions(const bool &blockOtherActions); void setRepeatInterval(const qreal &interval); signals: /** @@ -65,6 +72,7 @@ private slots: void onGestureStarted(); void onGestureUpdated(const qreal &delta); private: + bool m_blockOtherActions = false; qreal m_repeatInterval = 0; std::vector> m_conditions; diff --git a/src/libgestures/libgestures/gestures/gesture.cpp b/src/libgestures/libgestures/gestures/gesture.cpp index 493084d..3b41ee5 100644 --- a/src/libgestures/libgestures/gestures/gesture.cpp +++ b/src/libgestures/libgestures/gestures/gesture.cpp @@ -21,6 +21,7 @@ void Gesture::onCancelled() m_accumulatedDelta = 0; m_hasStarted = false; + m_blockingAction = std::nullopt; } void Gesture::onEnded() @@ -29,10 +30,16 @@ void Gesture::onEnded() return; for (const auto &action : m_actions) + { + if (!action->repeat() && !m_triggerWhenThresholdReached && action->canExecute() && thresholdReached(m_accumulatedDelta) + && action->satisfiesConditions() && (!m_blockingAction || m_blockingAction->get() == action.get())) + action->execute(); Q_EMIT action->gestureEnded(); + } m_accumulatedDelta = 0; m_hasStarted = false; + m_blockingAction = std::nullopt; } void Gesture::onStarted() @@ -54,20 +61,23 @@ void Gesture::onUpdated(const qreal &delta, bool &endedPrematurely) for (const auto &action : m_actions) { - if (!action->satisfiesConditions()) + if (!action->satisfiesConditions() || (m_blockingAction.has_value() && m_blockingAction.value().get() != action.get())) continue; - if (!action->repeat() && m_triggerWhenThresholdReached && action->canExecute()) { + if (!action->repeat() && m_triggerWhenThresholdReached && action->canExecute()) + { action->execute(); - if (m_triggerOneActionOnly) - { - Q_EMIT ended(); - endedPrematurely = true; - return; - } + if (!action->blocksOtherActions()) + continue; + + Q_EMIT ended(); + endedPrematurely = true; + return; } Q_EMIT action->gestureUpdated(delta); + if (action->blocksOtherActions()) + m_blockingAction = action; } } @@ -121,9 +131,4 @@ void Gesture::setFingers(const uint8_t &minimum, const uint8_t &maximum) m_maximumFingers = maximum; } -void Gesture::setTriggerOneActionOnly(const bool &triggerOneActionOnly) -{ - m_triggerOneActionOnly = triggerOneActionOnly; -} - } // namespace libgestures \ No newline at end of file diff --git a/src/libgestures/libgestures/gestures/gesture.h b/src/libgestures/libgestures/gestures/gesture.h index d14962a..5330bda 100644 --- a/src/libgestures/libgestures/gestures/gesture.h +++ b/src/libgestures/libgestures/gestures/gesture.h @@ -34,12 +34,6 @@ class Gesture : public QObject void setTriggerWhenThresholdReached(const bool &triggerWhenThresholdReached); void setThreshold(const qreal &threshold); void setFingers(const uint8_t &minimum, const uint8_t &maximum); - - /** - * @param triggerOneActionOnly Whether only one action should be executed during a gesture. This can cause a - * gesture to end prematurely. - */ - void setTriggerOneActionOnly(const bool &triggerOneActionOnly); signals: /** * Emitted when the gesture has been cancelled. @@ -75,7 +69,6 @@ private slots: private: uint8_t m_minimumFingers = 0; uint8_t m_maximumFingers = 0; - bool m_triggerOneActionOnly = false; std::vector> m_conditions; @@ -83,6 +76,11 @@ private slots: qreal m_accumulatedDelta = 0; bool m_hasStarted = false; + + /** + * The action that currently blocks other actions. Reset after gesture has been cancelled or ended. + */ + std::optional> m_blockingAction; }; } // namespace libgestures \ No newline at end of file diff --git a/tests/libgestures/gestures/test_gesturerecognizer.cpp b/tests/libgestures/gestures/test_gesturerecognizer.cpp index 42b9c4c..c0f9f6a 100644 --- a/tests/libgestures/gestures/test_gesturerecognizer.cpp +++ b/tests/libgestures/gestures/test_gesturerecognizer.cpp @@ -13,14 +13,6 @@ void TestGestureRecognizer::init() m_hold2To3->setFingers(2, 3); m_hold3To4 = std::make_shared(); m_hold3To4->setFingers(3, 4); - - m_hold2_2actions_trigger1only = std::make_shared(); - m_hold2_2actions_trigger1only->setTriggerWhenThresholdReached(true); - m_hold2_2actions_trigger1only->setFingers(2, 2); - m_hold2_2actions_trigger1only->setTriggerOneActionOnly(true); - m_hold2_2actions_trigger1only->setThreshold(1); - m_hold2_2actions_trigger1only->addAction(std::make_shared()); - m_hold2_2actions_trigger1only->addAction(std::make_shared()); } void TestGestureRecognizer::gestureBegin_calledTwice_hasOneActiveGesture() @@ -91,8 +83,9 @@ void TestGestureRecognizer::holdGestureUpdate_twoActiveGesturesAndOneEndsPrematu gesture1->setThreshold(1); gesture1->setFingers(2, 2); gesture1->setTriggerWhenThresholdReached(true); - gesture1->setTriggerOneActionOnly(true); - gesture1->addAction(std::make_shared()); + const auto action = std::make_shared(); + action->setBlockOtherActions(true); + gesture1->addAction(action); const auto gesture2 = std::make_shared(); gesture2->setThreshold(1); gesture2->setFingers(2, 2); @@ -159,8 +152,9 @@ void TestGestureRecognizer::pinchGestureUpdate_twoActiveGesturesAndOneEndsPremat gesture1->setThreshold(0.1); gesture1->setFingers(2, 2); gesture1->setTriggerWhenThresholdReached(true); - gesture1->setTriggerOneActionOnly(true); - gesture1->addAction(std::make_shared()); + const auto action = std::make_shared(); + action->setBlockOtherActions(true); + gesture1->addAction(action); const auto gesture2 = std::make_shared(); gesture2->setDirection(PinchDirection::Expanding); gesture2->setThreshold(0.1); @@ -262,8 +256,9 @@ void TestGestureRecognizer::swipeGestureUpdate_twoActiveGesturesAndOneEndsPremat gesture1->setThreshold(1); gesture1->setFingers(3, 3); gesture1->setTriggerWhenThresholdReached(true); - gesture1->setTriggerOneActionOnly(true); - gesture1->addAction(std::make_shared()); + const auto action = std::make_shared(); + action->setBlockOtherActions(true); + gesture1->addAction(action); const auto gesture2 = std::make_shared(); gesture2->setDirection(SwipeDirection::Right); gesture2->setThreshold(1); diff --git a/tests/libgestures/gestures/test_gesturerecognizer.h b/tests/libgestures/gestures/test_gesturerecognizer.h index cdb9a96..094a639 100644 --- a/tests/libgestures/gestures/test_gesturerecognizer.h +++ b/tests/libgestures/gestures/test_gesturerecognizer.h @@ -48,7 +48,6 @@ private slots: std::shared_ptr m_hold2; std::shared_ptr m_hold2To3; std::shared_ptr m_hold3To4; - std::shared_ptr m_hold2_2actions_trigger1only; }; } // namespace libgestures \ No newline at end of file