From 2ad896c71d4c0e1c5e478bb969097ddd43453a59 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Wed, 17 Jan 2024 22:42:37 +0200 Subject: [PATCH] plugins/shakecursor: Make the cursor big enough upon the first shake The current behavior is that the cursor size follows how hard or fast the cursor is shaken. While this looks fancy, given the purpose of this plugin, it should be possible to magnify the cursor as easy as possible without interfering or false triggering. This change implements a sort of a compromise. When the cursor is shaken for the first time, the cursor is magnified by some certain scale factor. Then every next shake magnifies the cursor further by a smaller amount. --- src/plugins/shakecursor/shakecursor.cpp | 57 ++++++++++++------- src/plugins/shakecursor/shakecursor.h | 12 ++-- .../shakecursor/shakecursorconfig.kcfg | 5 +- src/plugins/shakecursor/shakedetector.cpp | 9 +-- src/plugins/shakecursor/shakedetector.h | 3 +- 5 files changed, 56 insertions(+), 30 deletions(-) diff --git a/src/plugins/shakecursor/shakecursor.cpp b/src/plugins/shakecursor/shakecursor.cpp index 2063c3f8cc..2b5e38e814 100644 --- a/src/plugins/shakecursor/shakecursor.cpp +++ b/src/plugins/shakecursor/shakecursor.cpp @@ -21,17 +21,11 @@ ShakeCursorEffect::ShakeCursorEffect() { input()->installInputEventSpy(this); - m_resetCursorScaleTimer.setSingleShot(true); - connect(&m_resetCursorScaleTimer, &QTimer::timeout, this, [this]() { - m_resetCursorScaleAnimation.setStartValue(m_cursorMagnification); - m_resetCursorScaleAnimation.setEndValue(1.0); - m_resetCursorScaleAnimation.setDuration(animationTime(150)); - m_resetCursorScaleAnimation.setEasingCurve(QEasingCurve::InOutCubic); - m_resetCursorScaleAnimation.start(); - }); + m_deflateTimer.setSingleShot(true); + connect(&m_deflateTimer, &QTimer::timeout, this, &ShakeCursorEffect::deflate); - connect(&m_resetCursorScaleAnimation, &QVariantAnimation::valueChanged, this, [this]() { - magnify(m_resetCursorScaleAnimation.currentValue().toReal()); + connect(&m_scaleAnimation, &QVariantAnimation::valueChanged, this, [this]() { + magnify(m_scaleAnimation.currentValue().toReal()); }); ShakeCursorConfig::instance(effects->config()); @@ -59,9 +53,36 @@ void ShakeCursorEffect::reconfigure(ReconfigureFlags flags) m_shakeDetector.setSensitivity(ShakeCursorConfig::sensitivity()); } -bool ShakeCursorEffect::isActive() const +void ShakeCursorEffect::inflate() { - return m_cursorMagnification != 1.0; + qreal magnification; + if (m_targetMagnification == 1.0) { + magnification = ShakeCursorConfig::magnification(); + } else { + magnification = m_targetMagnification + ShakeCursorConfig::overMagnification(); + } + + animateTo(magnification); +} + +void ShakeCursorEffect::deflate() +{ + animateTo(1.0); +} + +void ShakeCursorEffect::animateTo(qreal magnification) +{ + if (m_targetMagnification != magnification) { + m_scaleAnimation.stop(); + + m_scaleAnimation.setStartValue(m_currentMagnification); + m_scaleAnimation.setEndValue(magnification); + m_scaleAnimation.setDuration(animationTime(200)); + m_scaleAnimation.setEasingCurve(QEasingCurve::InOutCubic); + m_scaleAnimation.start(); + + m_targetMagnification = magnification; + } } void ShakeCursorEffect::pointerEvent(MouseEvent *event) @@ -74,24 +95,22 @@ void ShakeCursorEffect::pointerEvent(MouseEvent *event) return; } - if (const auto shakeFactor = m_shakeDetector.update(event)) { - m_resetCursorScaleTimer.start(animationTime(2000)); - m_resetCursorScaleAnimation.stop(); - - magnify(std::max(m_cursorMagnification, 1.0 + ShakeCursorConfig::magnification() * shakeFactor.value())); + if (m_shakeDetector.update(event)) { + inflate(); + m_deflateTimer.start(animationTime(2000)); } } void ShakeCursorEffect::magnify(qreal magnification) { if (magnification == 1.0) { - m_cursorMagnification = 1.0; + m_currentMagnification = 1.0; if (m_cursorItem) { m_cursorItem.reset(); effects->showCursor(); } } else { - m_cursorMagnification = magnification; + m_currentMagnification = magnification; if (!m_cursorItem) { effects->hideCursor(); diff --git a/src/plugins/shakecursor/shakecursor.h b/src/plugins/shakecursor/shakecursor.h index e1f1debd98..3f7fe0a0a0 100644 --- a/src/plugins/shakecursor/shakecursor.h +++ b/src/plugins/shakecursor/shakecursor.h @@ -31,18 +31,22 @@ public: void reconfigure(ReconfigureFlags flags) override; void pointerEvent(MouseEvent *event) override; - bool isActive() const override; private: void magnify(qreal magnification); - QTimer m_resetCursorScaleTimer; - QVariantAnimation m_resetCursorScaleAnimation; + void inflate(); + void deflate(); + void animateTo(qreal magnification); + + QTimer m_deflateTimer; + QVariantAnimation m_scaleAnimation; ShakeDetector m_shakeDetector; Cursor *m_cursor; std::unique_ptr m_cursorItem; - qreal m_cursorMagnification = 1.0; + qreal m_targetMagnification = 1.0; + qreal m_currentMagnification = 1.0; }; } // namespace KWin diff --git a/src/plugins/shakecursor/shakecursorconfig.kcfg b/src/plugins/shakecursor/shakecursorconfig.kcfg index 50985c9a7c..fb355248cf 100644 --- a/src/plugins/shakecursor/shakecursorconfig.kcfg +++ b/src/plugins/shakecursor/shakecursorconfig.kcfg @@ -12,7 +12,10 @@ 4 - 2 + 3 + + + 1 diff --git a/src/plugins/shakecursor/shakedetector.cpp b/src/plugins/shakecursor/shakedetector.cpp index 5b8f5a8fc2..91bede4977 100644 --- a/src/plugins/shakecursor/shakedetector.cpp +++ b/src/plugins/shakecursor/shakedetector.cpp @@ -32,7 +32,7 @@ void ShakeDetector::setSensitivity(qreal sensitivity) m_sensitivity = sensitivity; } -std::optional ShakeDetector::update(QMouseEvent *event) +bool ShakeDetector::update(QMouseEvent *event) { // Prune the old entries in the history. auto it = m_history.begin(); @@ -73,13 +73,14 @@ std::optional ShakeDetector::update(QMouseEvent *event) const qreal boundsHeight = bottom - top; const qreal diagonal = std::sqrt(boundsWidth * boundsWidth + boundsHeight * boundsHeight); if (diagonal < 100) { - return std::nullopt; + return false; } const qreal shakeFactor = distance / diagonal; if (shakeFactor > m_sensitivity) { - return shakeFactor - m_sensitivity; + m_history.clear(); + return true; } - return std::nullopt; + return false; } diff --git a/src/plugins/shakecursor/shakedetector.h b/src/plugins/shakecursor/shakedetector.h index 51c2898522..25f40a7560 100644 --- a/src/plugins/shakecursor/shakedetector.h +++ b/src/plugins/shakecursor/shakedetector.h @@ -9,7 +9,6 @@ #include #include -#include /** * The ShakeDetector type provides a way to detect pointer shake gestures. @@ -23,7 +22,7 @@ class ShakeDetector public: ShakeDetector(); - std::optional update(QMouseEvent *event); + bool update(QMouseEvent *event); quint64 interval() const; void setInterval(quint64 interval);