From 0b27ce4d34b1579c168b8bdde71aa007c38ca6d2 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Tue, 10 May 2022 17:31:10 +0200 Subject: [PATCH] Make touchscreen gestures realtime --- autotests/test_virtual_desktops.cpp | 2 +- src/effects.cpp | 4 +-- src/effects.h | 2 +- src/effects/overview/overvieweffect.cpp | 3 +- src/effects/windowview/windowvieweffect.cpp | 6 ++-- src/globalshortcuts.cpp | 4 +-- src/globalshortcuts.h | 2 +- src/input.cpp | 35 ++++++++------------- src/input.h | 2 +- src/libkwineffects/kwineffects.h | 2 +- src/virtualdesktops.cpp | 30 ++++++------------ 11 files changed, 37 insertions(+), 55 deletions(-) diff --git a/autotests/test_virtual_desktops.cpp b/autotests/test_virtual_desktops.cpp index 9d296c5165..05abf72193 100644 --- a/autotests/test_virtual_desktops.cpp +++ b/autotests/test_virtual_desktops.cpp @@ -45,7 +45,7 @@ void InputRedirection::registerRealtimeTouchpadSwipeShortcut(SwipeDirection, uin Q_UNUSED(fingerCount) } -void InputRedirection::registerTouchscreenSwipeShortcut(SwipeDirection, uint fingerCount, QAction *) +void InputRedirection::registerTouchscreenSwipeShortcut(SwipeDirection, uint, QAction *, std::function) { } diff --git a/src/effects.cpp b/src/effects.cpp index 5f3c68b708..8d94396d51 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -786,9 +786,9 @@ void EffectsHandlerImpl::registerTouchpadPinchShortcut(PinchDirection direction, input()->registerTouchpadPinchShortcut(direction, fingerCount, action); } -void EffectsHandlerImpl::registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action) +void EffectsHandlerImpl::registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function progressCallback) { - input()->registerTouchscreenSwipeShortcut(direction, fingerCount, action); + input()->registerTouchscreenSwipeShortcut(direction, fingerCount, action, progressCallback); } void *EffectsHandlerImpl::getProxy(QString name) diff --git a/src/effects.h b/src/effects.h index a01f8fba3e..a7f3ed54a5 100644 --- a/src/effects.h +++ b/src/effects.h @@ -107,7 +107,7 @@ public: void registerTouchpadSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action) override; void registerRealtimeTouchpadPinchShortcut(PinchDirection dir, uint fingerCount, QAction *onUp, std::function progressCallback) override; void registerTouchpadPinchShortcut(PinchDirection direction, uint fingerCount, QAction *action) override; - void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action) override; + void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function progressCallback) override; void *getProxy(QString name) override; void startMousePolling() override; void stopMousePolling() override; diff --git a/src/effects/overview/overvieweffect.cpp b/src/effects/overview/overvieweffect.cpp index 5647c17009..d2a309787d 100644 --- a/src/effects/overview/overvieweffect.cpp +++ b/src/effects/overview/overvieweffect.cpp @@ -45,8 +45,6 @@ OverviewEffect::OverviewEffect() KGlobalAccel::self()->setShortcut(m_toggleAction, {defaultToggleShortcut}); m_toggleShortcut = KGlobalAccel::self()->shortcut(m_toggleAction); effects->registerGlobalShortcut({defaultToggleShortcut}, m_toggleAction); - effects->registerTouchscreenSwipeShortcut(SwipeDirection::Up, 3, m_toggleAction); - effects->registerTouchscreenSwipeShortcut(SwipeDirection::Down, 3, m_toggleAction); auto progressCallback = [this](qreal progress) { if (m_status == Status::Active) { @@ -64,6 +62,7 @@ OverviewEffect::OverviewEffect() }; effects->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Up, 4, m_realtimeToggleAction, progressCallback); + effects->registerTouchscreenSwipeShortcut(SwipeDirection::Up, 3, m_realtimeToggleAction, progressCallback); connect(effects, &EffectsHandler::screenAboutToLock, this, &OverviewEffect::realDeactivate); diff --git a/src/effects/windowview/windowvieweffect.cpp b/src/effects/windowview/windowvieweffect.cpp index 48f2e7c97d..73536cc68d 100644 --- a/src/effects/windowview/windowvieweffect.cpp +++ b/src/effects/windowview/windowvieweffect.cpp @@ -108,7 +108,7 @@ WindowViewEffect::WindowViewEffect() } }); - effects->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Down, 4, m_realtimeToggleAction, [this](qreal progress) { + const auto gestureCallback = [this](qreal progress) { if (m_status == Status::Active) { return; } @@ -121,7 +121,9 @@ WindowViewEffect::WindowViewEffect() if (!isRunning()) { partialActivate(); } - }); + }; + effects->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Down, 4, m_realtimeToggleAction, gestureCallback); + effects->registerTouchscreenSwipeShortcut(SwipeDirection::Down, 3, m_realtimeToggleAction, gestureCallback); reconfigure(ReconfigureAll); } diff --git a/src/globalshortcuts.cpp b/src/globalshortcuts.cpp index cb7cab367a..7e8b5afd6f 100644 --- a/src/globalshortcuts.cpp +++ b/src/globalshortcuts.cpp @@ -191,9 +191,9 @@ void GlobalShortcutsManager::registerRealtimeTouchpadPinch(QAction *onUp, std::f addIfNotExists(GlobalShortcut(RealtimeFeedbackPinchShortcut{direction, progressCallback, fingerCount}, onUp), DeviceType::Touchpad); } -void GlobalShortcutsManager::registerTouchscreenSwipe(QAction *action, SwipeDirection direction, uint fingerCount) +void GlobalShortcutsManager::registerTouchscreenSwipe(QAction *action, std::function progressCallback, SwipeDirection direction, uint fingerCount) { - addIfNotExists(GlobalShortcut(SwipeShortcut{DeviceType::Touchscreen, direction, fingerCount}, action), DeviceType::Touchscreen); + addIfNotExists(GlobalShortcut(RealtimeFeedbackSwipeShortcut{DeviceType::Touchscreen, direction, progressCallback, fingerCount}, action), DeviceType::Touchscreen); } bool GlobalShortcutsManager::processKey(Qt::KeyboardModifiers mods, int keyQt) diff --git a/src/globalshortcuts.h b/src/globalshortcuts.h index 77d5ba4fa7..0984e5a4c2 100644 --- a/src/globalshortcuts.h +++ b/src/globalshortcuts.h @@ -72,7 +72,7 @@ public: void registerRealtimeTouchpadPinch(QAction *onUp, std::function progressCallback, PinchDirection direction, uint fingerCount = 4); - void registerTouchscreenSwipe(QAction *action, SwipeDirection direction, uint fingerCount); + void registerTouchscreenSwipe(QAction *action, std::function progressCallback, SwipeDirection direction, uint fingerCount); /** * @brief Processes a key event to decide whether a shortcut needs to be triggered. diff --git a/src/input.cpp b/src/input.cpp index 7dcca49197..2a1cdd5c7d 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1065,7 +1065,7 @@ public: m_gestureCancelled = true; return true; } else { - m_touchPoints.insert(id, {pos, QSize()}); + m_touchPoints.insert(id, pos); if (m_touchPoints.count() == 1) { m_lastTouchDownTime = time; } else { @@ -1078,7 +1078,7 @@ public: float xfactor = output->physicalSize().width() / (float)output->geometry().width(); float yfactor = output->physicalSize().height() / (float)output->geometry().height(); bool distanceMatch = std::any_of(m_touchPoints.constBegin(), m_touchPoints.constEnd(), [pos, xfactor, yfactor](const auto &point) { - QPointF p = pos - point.pos; + QPointF p = pos - point; return std::abs(xfactor * p.x()) + std::abs(yfactor * p.y()) < 50; }); if (!distanceMatch) { @@ -1103,19 +1103,15 @@ public: if (m_gestureCancelled) { return true; } - // only track one finger for simplicity - if (id != m_touchPoints.begin().key()) { - return true; - } - auto &point = m_touchPoints[id]; - QPointF dist = pos - point.pos; auto output = kwinApp()->platform()->outputAt(pos.toPoint()); - float xfactor = output->physicalSize().width() / (float)output->geometry().width(); - float yfactor = output->physicalSize().height() / (float)output->geometry().height(); - QSize delta = QSize(xfactor * dist.x(), yfactor * dist.y()) * 10; - point.distance += delta; - point.pos = pos; - input()->shortcuts()->processSwipeUpdate(DeviceType::Touchscreen, delta); + const float xfactor = output->physicalSize().width() / (float)output->geometry().width(); + const float yfactor = output->physicalSize().height() / (float)output->geometry().height(); + + 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()); + point = pos; return true; } return false; @@ -1144,17 +1140,12 @@ public: } private: - struct TouchPoint - { - QPointF pos; - QSize distance; - }; bool m_gestureTaken = false; bool m_gestureCancelled = false; bool m_touchGestureCancelSent = false; uint32_t m_lastTouchDownTime = 0; QPointF m_lastAverageDistance; - QMap m_touchPoints; + QMap m_touchPoints; QTimer *m_powerDown = nullptr; }; @@ -3247,9 +3238,9 @@ void InputRedirection::registerGlobalAccel(KGlobalAccelInterface *interface) m_shortcuts->setKGlobalAccelInterface(interface); } -void InputRedirection::registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action) +void InputRedirection::registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function progressCallback) { - m_shortcuts->registerTouchscreenSwipe(action, direction, fingerCount); + m_shortcuts->registerTouchscreenSwipe(action, progressCallback, direction, fingerCount); } void InputRedirection::warpPointer(const QPointF &pos) diff --git a/src/input.h b/src/input.h index ad00378f02..892768de9d 100644 --- a/src/input.h +++ b/src/input.h @@ -139,7 +139,7 @@ public: void registerRealtimeTouchpadSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *onUp, std::function progressCallback); void registerTouchpadPinchShortcut(PinchDirection direction, uint fingerCount, QAction *action); void registerRealtimeTouchpadPinchShortcut(PinchDirection direction, uint fingerCount, QAction *onUp, std::function progressCallback); - void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action); + void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function progressCallback); void registerGlobalAccel(KGlobalAccelInterface *interface); bool supportsPointerWarping() const; diff --git a/src/libkwineffects/kwineffects.h b/src/libkwineffects/kwineffects.h index 5ccf08b027..bb805f61e8 100644 --- a/src/libkwineffects/kwineffects.h +++ b/src/libkwineffects/kwineffects.h @@ -941,7 +941,7 @@ public: * @param action The action which gets triggered when the gesture triggers * @since 5.25 */ - virtual void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action) = 0; + virtual void registerTouchscreenSwipeShortcut(SwipeDirection direction, uint fingerCount, QAction *action, std::function progressCallback) = 0; /** * Retrieve the proxy class for an effect if it has one. Will return NULL if diff --git a/src/virtualdesktops.cpp b/src/virtualdesktops.cpp index 20994609a0..919fd310be 100644 --- a/src/virtualdesktops.cpp +++ b/src/virtualdesktops.cpp @@ -809,31 +809,22 @@ void VirtualDesktopManager::initShortcuts() connect(m_swipeGestureReleasedX.get(), &QAction::triggered, this, &VirtualDesktopManager::gestureReleasedX); connect(m_swipeGestureReleasedY.get(), &QAction::triggered, this, &VirtualDesktopManager::gestureReleasedY); - // These take the live feedback from a gesture - input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Left, 3, m_swipeGestureReleasedX.get(), [this](qreal cb) { + const auto left = [this](qreal cb) { if (grid().width() > 1) { m_currentDesktopOffset.setX(cb); Q_EMIT currentChanging(current(), m_currentDesktopOffset); } - }); - input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Right, 3, m_swipeGestureReleasedX.get(), [this](qreal cb) { + }; + const auto right = [this](qreal cb) { if (grid().width() > 1) { m_currentDesktopOffset.setX(-cb); Q_EMIT currentChanging(current(), m_currentDesktopOffset); } - }); - input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Left, 4, m_swipeGestureReleasedX.get(), [this](qreal cb) { - if (grid().width() > 1) { - m_currentDesktopOffset.setX(cb); - Q_EMIT currentChanging(current(), m_currentDesktopOffset); - } - }); - input()->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Right, 4, m_swipeGestureReleasedX.get(), [this](qreal cb) { - if (grid().width() > 1) { - m_currentDesktopOffset.setX(-cb); - 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) { if (grid().height() > 1) { m_currentDesktopOffset.setY(-cb); @@ -846,9 +837,8 @@ void VirtualDesktopManager::initShortcuts() Q_EMIT currentChanging(current(), m_currentDesktopOffset); } }); - - input()->registerTouchscreenSwipeShortcut(SwipeDirection::Left, 3, slotRightAction); - input()->registerTouchscreenSwipeShortcut(SwipeDirection::Right, 3, slotLeftAction); + input()->registerTouchscreenSwipeShortcut(SwipeDirection::Left, 3, m_swipeGestureReleasedX.get(), left); + input()->registerTouchscreenSwipeShortcut(SwipeDirection::Right, 3, m_swipeGestureReleasedX.get(), right); // axis events input()->registerAxisShortcut(Qt::ControlModifier | Qt::AltModifier, PointerAxisDown,