114 lines
4.2 KiB
Diff
114 lines
4.2 KiB
Diff
From: Anders da Silva Rytter Hansen <andersrh@users.noreply.github.com>
|
|
Date: Thu, 02 Jul 2026 13:00:00 +0000
|
|
Subject: [PATCH] Reduce per-frame compositor work during panel floating animation
|
|
|
|
PanelView::updateMask() is called once per animation frame while the
|
|
panel transitions between docked and floating. It calls
|
|
KWindowEffects::enableBlurBehind() and enableBackgroundContrast() which
|
|
update the compositor's effect region via X11/D-Bus. Doing this for
|
|
every frame causes visible stutter when other animations are running.
|
|
|
|
Additionally, the animation's valueChanged handler was calling
|
|
positionAndResizePanel() every frame, which calls setGeometry(),
|
|
emits availableScreenRegionChanged() and calls slideWindow() every
|
|
frame even though the panel's X window geometry is constant during the
|
|
animation.
|
|
|
|
Coalesce the blur/contrast updates with a 50 ms single-shot timer and
|
|
replace the per-frame positionAndResizePanel() call with a lightweight
|
|
updateMask() call. Finalize geometry and effects once when the
|
|
animation finishes. This keeps the QML geometry/opacity animation
|
|
smooth while drastically reducing synchronous work sent to the
|
|
compositor.
|
|
---
|
|
shell/panelview.cpp | 19 +++++++++++++++++++
|
|
shell/panelview.h | 5 +++++
|
|
2 files changed, 24 insertions(+)
|
|
|
|
--- a/shell/panelview.h 2026-04-08 06:33:10.000000000 -0300
|
|
+++ b/shell/panelview.h 2026-07-02 13:09:59.011179892 -0300
|
|
@@ -8,6 +8,7 @@
|
|
|
|
#include <Plasma/Theme>
|
|
#include <QPointer>
|
|
+#include <QAbstractAnimation>
|
|
#include <QPropertyAnimation>
|
|
#include <QTimer>
|
|
#include <QWindow> // For WId
|
|
@@ -306,6 +307,7 @@
|
|
void adaptToScreen();
|
|
void handleQmlStatusChange(QQmlComponent::Status status);
|
|
void updateMask();
|
|
+ void applyPendingMaskUpdate();
|
|
void updateEnabledBorders();
|
|
void updatePadding();
|
|
void updateFloating();
|
|
@@ -363,6 +365,9 @@
|
|
LengthMode m_lengthMode;
|
|
Plasma::Theme m_theme;
|
|
QTimer m_unhideTimer;
|
|
+ QTimer m_maskThrottleTimer;
|
|
+ bool m_pendingMaskUpdate = false;
|
|
+ bool m_forceMaskUpdate = false;
|
|
Plasma::Types::BackgroundHints m_backgroundHints;
|
|
KSvg::FrameSvg::EnabledBorders m_enabledBorders = KSvg::FrameSvg::AllBorders;
|
|
QPointer<QScreen> m_lastScreen;
|
|
--- a/shell/panelview.cpp 2026-04-08 06:33:10.000000000 -0300
|
|
+++ b/shell/panelview.cpp 2026-07-02 13:39:01.337688294 -0300
|
|
@@ -111,6 +111,10 @@
|
|
m_strutsTimer.setSingleShot(true);
|
|
connect(&m_strutsTimer, &QTimer::timeout, this, &PanelView::updateExclusiveZone);
|
|
|
|
+ m_maskThrottleTimer.setSingleShot(true);
|
|
+ m_maskThrottleTimer.setInterval(50ms);
|
|
+ connect(&m_maskThrottleTimer, &QTimer::timeout, this, &PanelView::applyPendingMaskUpdate);
|
|
+
|
|
connect(m_corona, &Plasma::Corona::editModeChanged, this, &PanelView::updateEditModeLabel);
|
|
|
|
// Register enums
|
|
@@ -1304,6 +1308,17 @@
|
|
return;
|
|
}
|
|
|
|
+ if (m_floatingnessAnimation.state() == QAbstractAnimation::Running && !m_forceMaskUpdate) {
|
|
+ m_pendingMaskUpdate = true;
|
|
+ if (!m_maskThrottleTimer.isActive()) {
|
|
+ m_maskThrottleTimer.start();
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ m_forceMaskUpdate = false;
|
|
+ m_pendingMaskUpdate = false;
|
|
+
|
|
// Popups now align to the mask, without it they appear in the wrong position
|
|
// always create it and show blur and contrast when needed
|
|
QRegion mask;
|
|
@@ -1364,6 +1379,14 @@
|
|
}
|
|
}
|
|
|
|
+void PanelView::applyPendingMaskUpdate()
|
|
+{
|
|
+ if (m_pendingMaskUpdate) {
|
|
+ m_forceMaskUpdate = true;
|
|
+ updateMask();
|
|
+ }
|
|
+}
|
|
+
|
|
bool PanelView::canSetStrut() const
|
|
{
|
|
// read the wm name, need to do this every time which means a roundtrip unfortunately
|
|
@@ -1587,10 +1610,10 @@
|
|
return;
|
|
}
|
|
m_floatingness = get<double>(value);
|
|
- positionAndResizePanel();
|
|
+ updateMask();
|
|
});
|
|
connect(&m_floatingnessAnimation, &QPropertyAnimation::finished, rootObject, [this]() {
|
|
- updateMask();
|
|
+ positionAndResizePanel();
|
|
});
|
|
connect(rootObject, SIGNAL(minPanelHeightChanged()), this, SLOT(updatePadding()));
|
|
connect(rootObject, SIGNAL(minPanelWidthChanged()), this, SLOT(updatePadding()));
|