From 3f7133a022788115acf001d54323ab2bcc2355a1 Mon Sep 17 00:00:00 2001 From: David Redondo Date: Tue, 18 Jan 2022 10:37:42 +0100 Subject: [PATCH] Apply timeout to startfeedback for xdg activation Since xdg activation startups do not time out automatically run a timer for each start up in the effect. BUG:438622 FIXED-IN:5.24 --- .../startupfeedback/startupfeedback.cpp | 37 +++++++++++++------ src/effects/startupfeedback/startupfeedback.h | 13 ++++++- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/effects/startupfeedback/startupfeedback.cpp b/src/effects/startupfeedback/startupfeedback.cpp index d0ef5af023..a1bcc08ec1 100644 --- a/src/effects/startupfeedback/startupfeedback.cpp +++ b/src/effects/startupfeedback/startupfeedback.cpp @@ -13,10 +13,11 @@ #include #include #include -#include -#include -#include #include +#include +#include +#include +#include // KDE #include #include @@ -141,7 +142,8 @@ void StartupFeedbackEffect::reconfigure(Effect::ReconfigureFlags flags) const bool busyCursor = c.readEntry("BusyCursor", true); c = m_configWatcher->config()->group("BusyCursorSettings"); - m_startupInfo->setTimeout(c.readEntry("Timeout", s_startupDefaultTimeout)); + m_timeout = std::chrono::seconds(c.readEntry("Timeout", s_startupDefaultTimeout)); + m_startupInfo->setTimeout(m_timeout.count()); const bool busyBlinking = c.readEntry("Blinking", false); const bool busyBouncing = c.readEntry("Bouncing", true); if (!busyCursor) @@ -163,7 +165,7 @@ void StartupFeedbackEffect::reconfigure(Effect::ReconfigureFlags flags) m_type = PassiveFeedback; if (m_active) { stop(); - start(m_startups[ m_currentStartup ]); + start(m_startups[m_currentStartup]); } } @@ -263,9 +265,19 @@ void StartupFeedbackEffect::slotMouseChanged(const QPoint& pos, const QPoint& ol void StartupFeedbackEffect::gotNewStartup(const QString &id, const QIcon &icon) { + Startup &startup = m_startups[id]; + startup.icon = icon; + + startup.expiredTimer.reset(new QTimer()); + // Stop the animation if the startup doesn't finish within reasonable interval. + connect(startup.expiredTimer.data(), &QTimer::timeout, this, [this, id]() { + gotRemoveStartup(id); + }); + startup.expiredTimer->setSingleShot(true); + startup.expiredTimer->start(m_timeout); + m_currentStartup = id; - m_startups[ id ] = icon; - start(icon); + start(startup); } void StartupFeedbackEffect::gotRemoveStartup(const QString &id) @@ -283,14 +295,15 @@ void StartupFeedbackEffect::gotRemoveStartup(const QString &id) void StartupFeedbackEffect::gotStartupChange(const QString &id, const QIcon &icon) { if (m_currentStartup == id) { - if (!icon.isNull() && icon.name() != m_startups[m_currentStartup].name()) { - m_startups[ id ] = icon; - start(icon); + Startup ¤tStartup = m_startups[m_currentStartup]; + if (!icon.isNull() && icon.name() != currentStartup.icon.name()) { + currentStartup.icon = icon; + start(currentStartup); } } } -void StartupFeedbackEffect::start(const QIcon &icon) +void StartupFeedbackEffect::start(const Startup &startup) { if (m_type == NoFeedback || m_splashVisible || effects->isCursorHidden()) return; @@ -309,7 +322,7 @@ void StartupFeedbackEffect::start(const QIcon &icon) // get ratio for bouncing cursor so we don't need to manually calculate the sizes for each icon size if (m_type == BouncingFeedback) m_bounceSizesRatio = iconSize / 16.0; - const QPixmap iconPixmap = icon.pixmap(iconSize); + const QPixmap iconPixmap = startup.icon.pixmap(iconSize); prepareTextures(iconPixmap); m_dirtyRect = m_currentGeometry = feedbackRect(); effects->addRepaint(m_dirtyRect); diff --git a/src/effects/startupfeedback/startupfeedback.h b/src/effects/startupfeedback/startupfeedback.h index 608ac75e23..5c58a44807 100644 --- a/src/effects/startupfeedback/startupfeedback.h +++ b/src/effects/startupfeedback/startupfeedback.h @@ -14,6 +14,8 @@ #include #include +#include + class KSelectionOwner; namespace KWin { @@ -57,7 +59,13 @@ private: BlinkingFeedback, PassiveFeedback }; - void start(const QIcon &icon); + + struct Startup { + QIcon icon; + QSharedPointer expiredTimer; + }; + + void start(const Startup &startup); void stop(); QImage scalePixmap(const QPixmap& pm, const QSize& size) const; void prepareTextures(const QPixmap& pix); @@ -67,7 +75,7 @@ private: KStartupInfo* m_startupInfo; KSelectionOwner* m_selection; QString m_currentStartup; - QMap m_startups; // QString == pixmap + QMap m_startups; bool m_active; int m_frame; int m_progress; @@ -80,6 +88,7 @@ private: int m_cursorSize; KConfigWatcher::Ptr m_configWatcher; bool m_splashVisible; + std::chrono::seconds m_timeout; }; } // namespace