Revert previous workaround and fix it in a more correct way in Sonic-Win and Sonic-Workspace by not updating by every single frame but instead update per 50ms
Some checks failed
Build RPMs / build (sonic-interface-libraries.spec) (push) Failing after 11s
Build RPMs / build (sonic-win.spec) (push) Failing after 6s
Build RPMs / build (sonic-workspace.spec) (push) Failing after 7s

This commit is contained in:
Anders da Silva Rytter Hansen 2026-07-02 14:43:28 -03:00
commit cf0089e100
7 changed files with 173 additions and 93 deletions

View file

@ -1,39 +0,0 @@
From: Anders da Silva Rytter Hansen <andersrh@users.noreply.github.com>
Date: Thu, 2 Jul 2026 10:47:00 -0300
Subject: [PATCH] desktoppackage: disable panel floating/opacity animations
Disable the floating and opacity transitions so the panel changes state instantly and stays fluid.
This fixes the UI lag, when switching virtual desktops.
References: https://bugs.kde.org/show_bug.cgi?id=484501 and https://github.com/orgs/Sonic-DE/discussions/20
---
desktoppackage/contents/views/Panel.qml | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/desktoppackage/contents/views/Panel.qml b/desktoppackage/contents/views/Panel.qml
--- a/desktoppackage/contents/views/Panel.qml
+++ b/desktoppackage/contents/views/Panel.qml
@@ -133,19 +133,15 @@
}
// Floatingness is a value in [0, 1] that's multiplied to the floating margin; 0: not floating, 1: floating, between 0 and 1: animation between the two states
- readonly property int floatingnessAnimationDuration: Kirigami.Units.longDuration
+ // Disable the panel geometry animation: animated resizes of the panel
+ // window cause synchronous compositor work that stalls the desktop during
+ // virtual-desktop switches.
+ readonly property int floatingnessAnimationDuration: 0
property double floatingnessTarget: 0.0 // The animation is handled in panelview.cpp for efficiency
property double floatingness: 0.0
// PanelOpacity is a value in [0, 1] that's used as the opacity of the opaque elements over the transparent ones; values between 0 and 1 are used for animations
property double panelOpacity
- Behavior on panelOpacity {
- NumberAnimation {
- duration: Kirigami.Units.longDuration
- easing.type: Easing.OutCubic
- }
- }
-
KSvg.FrameSvgItem {
id: translucentItem
visible: root.floatingness === 0 && root.panelOpacity !== 1

View file

@ -11,7 +11,7 @@
Name: sonic-desktop-interface
Summary: Plasma Desktop shell
Version: 6.6.4
Release: 12%{?dist}
Release: 13%{?dist}
License: BSD-2-Clause AND BSD-3-Clause AND CC0-1.0 AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-only AND LGPL-2.0-only AND LGPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND LGPL-3.0-only AND (GPL-2.0-only OR GPL-3.0-only) AND (LGPL-2.1-only OR LGPL-3.0-only)
#URL: https://invent.kde.org/plasma/%{name}
@ -35,11 +35,6 @@ Source20: breeze-fedora-0.3.tar.gz
# Do not remove this as it breaks Fedora's QA policy
Patch101: hide-virtual-keyboard-indicator-on-sddm.patch
# Disable panel floating/opacity animations. Animated panel resizes cause
# synchronous compositor work that stalls the desktop when switching virtual
# desktops, so make the panel state changes instant instead.
Patch102: sonic-desktop-interface-6.6.4-x11-panel-lag.patch
## upstreamable patches
BuildRequires: pkgconfig(libusb)
@ -398,6 +393,9 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/kaccess.desktop
%changelog
* Thu Jul 02 2026 Anders da Silva Rytter Hansen <andersrh@users.noreply.github.com> - 6.6.4-13
- Revert previous workaround and fix issue in Sonic-Win and Sonic-Workspace instead.
* Thu Jul 02 2026 Anders da Silva Rytter Hansen <andersrh@users.noreply.github.com> - 6.6.4-12
- Disable panel floating/opacity animations to avoid stutter when the panel
changes state (e.g. switching virtual desktops).

View file

@ -0,0 +1,42 @@
From: Anders da Silva Rytter Hansen <andersrh@users.noreply.github.com>
Date: Thu, 02 Jul 2026 12:00:00 +0000
Subject: [PATCH] Batch strut-triggered workspace rearranges to reduce stutter
When a panel animates between floating and docked states it can change
its strut several times in quick succession. KWin handled those by
calling Workspace::rearrange() immediately, which recalculates work areas
and calls checkWorkspacePosition() on every client. That O(n) work on
every strut update causes visible stutter on X11 when other animations
are running.
Use the existing scheduleRearrange() path instead and bump its timer
from 0 ms to 50 ms so rapid strut changes are coalesced into a single
re-layout. This keeps the work area correct while reducing the amount
of synchronous work done during panel transitions.
---
src/events.cpp | 2 +-
src/workspace.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/src/events.cpp 2026-04-08 10:00:41.000000000 -0300
+++ b/src/events.cpp 2026-07-02 12:20:39.184413094 -0300
@@ -398,7 +398,7 @@
}
if ((dirtyProperties & NET::WMStrut) != 0
|| (dirtyProperties2 & NET::WM2ExtendedStrut) != 0) {
- workspace()->rearrange();
+ workspace()->scheduleRearrange();
}
if ((dirtyProperties & NET::WMIcon) != 0) {
getIcons();
--- a/src/workspace.cpp 2026-04-08 10:00:41.000000000 -0300
+++ b/src/workspace.cpp 2026-07-02 12:20:49.966586529 -0300
@@ -2178,7 +2178,7 @@
void Workspace::scheduleRearrange()
{
- m_rearrangeTimer.start(0);
+ m_rearrangeTimer.start(50);
}
void Workspace::rearrange()

View file

@ -4,7 +4,7 @@
Name: sonic-win
Version: 6.6.4
Release: 11%{?dist}
Release: 12%{?dist}
Summary: KDE Window manager
License: BSD-2-Clause AND BSD-3-Clause AND CC0-1.0 AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-only AND GPL-3.0-or-later AND LGPL-2.0-only AND LGPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND LGPL-3.0-only AND (GPL-2.0-only OR GPL-3.0-only) AND (LGPL-2.1-only OR LGPL-3.0-only) AND MIT
@ -18,6 +18,7 @@ URL: https://github.com/Sonic-DE/%{name}
Source0: %{url}/archive/refs/tags/%{version}.tar.gz#/%{name}-%{version}.tar.gz
## upstream patches
Patch0: sonic-win-6.6.4-strut-throttle.patch
## proposed patches
@ -297,6 +298,10 @@ mkdir -p %{buildroot}%{_sysconfdir}/xdg/Xwayland-session.d
%changelog
* Thu Jul 02 2026 Anders da Silva Rytter Hansen <andersrh@users.noreply.github.com> - 6.6.4-12
- Batch strut-triggered workspace rearranges to reduce stutter during panel
state transitions.
* Sun Apr 12 2026 Steve Cossette <farchord@gmail.com> - 6.6.4-2
- Added evdev as BR for controller support (#22)

View file

@ -0,0 +1,114 @@
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()));

View file

@ -1,42 +0,0 @@
From: Anders da Silva Rytter Hansen <andersrh@users.noreply.github.com>
Date: Thu, 2 Jul 2026 09:40:00 -0300
Subject: [PATCH] shell: handle zero-duration floating panel animation
The QML side now disables the floating panel animation by setting
floatingnessAnimationDuration to 0. With a zero-duration
QPropertyAnimation the valueChanged signal may not be emitted, so update
m_floatingness and the QML property synchronously before doing the
geometry/mask/strut updates.
References: https://bugs.kde.org/show_bug.cgi?id=484501 and https://github.com/orgs/Sonic-DE/discussions/20
---
shell/panelview.cpp | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/shell/panelview.cpp b/shell/panelview.cpp
--- a/shell/panelview.cpp
+++ b/shell/panelview.cpp
@@ -1782,6 +1782,13 @@ void PanelView::updateFloating()
m_topFloatingPadding = rootObject()->property("fixedTopFloatingPadding").toInt();
m_bottomFloatingPadding = rootObject()->property("fixedBottomFloatingPadding").toInt();
+ const bool instantAnimation = m_floatingnessAnimation.duration() == 0;
+ if (instantAnimation) {
+ // Skip the animation; jump straight to the target value.
+ m_floatingness = m_floatingnessAnimation.endValue().toDouble();
+ rootObject()->setProperty("floatingness", m_floatingness);
+ }
+
positionAndResizePanel();
updateExclusiveZone();
updateShadows();
@@ -1789,6 +1796,10 @@ void PanelView::updateFloating()
// positionPanel and updateMask are called by m_floatingnessAnimation
if (m_floatingnessAnimation.targetObject()) {
+ if (instantAnimation) {
+ updateMask();
+ return;
+ }
m_floatingnessAnimation.start();
}
}

View file

@ -7,7 +7,7 @@
Name: sonic-workspace
Summary: Plasma workspace, applications and applets
Version: 6.6.4
Release: 14%{?dist}
Release: 15%{?dist}
# Automatically converted from old format: BSD-2-Clause AND BSD-3-Clause AND CC0-1.0 AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-only AND LGPL-2.0-only AND LGPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND LGPL-3.0-only AND LGPL-3.0-or-later AND (GPL-2.0-only OR GPL-3.0-only) AND (LGPL-2.1-only OR LGPL-3.0-only) AND MIT - review is highly recommended.
License: BSD-2-Clause AND BSD-3-Clause AND CC0-1.0 AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-only AND LGPL-2.0-only AND LGPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND LGPL-3.0-only AND LGPL-3.0-or-later AND (GPL-2.0-only OR GPL-3.0-only) AND (LGPL-2.1-only OR LGPL-3.0-only) AND MIT
@ -37,6 +37,7 @@ Source40: ssh-agent.conf
Source41: spice-vdagent.conf
## upstream patches
Patch0: sonic-workspace-6.6.4-mask-throttle.patch
## upstreamable Patches
@ -46,10 +47,6 @@ Patch106: plasma-workspace-5.27.80-enable-open-terminal-action.patch
# default to enable the lock/logout actions
Patch107: plasma-workspace-5.27.80-enable-lock-logout-action.patch
# Handle zero-duration floating panel animation now that the QML side disables
# the animation entirely.
Patch108: sonic-workspace-6.6.4-x11-panel-lag.patch
# udev
BuildRequires: zlib-devel
BuildRequires: libGL-devel
@ -694,6 +691,11 @@ fi
%changelog
* Thu Jul 02 2026 Anders da Silva Rytter Hansen <andersrh@users.noreply.github.com> - 6.6.4-15
- Reduce per-frame compositor work during panel floating animation:
throttle blur/contrast mask updates and avoid setGeometry/slideWindow
calls on every animation frame.
* Thu Jul 02 2026 Anders da Silva Rytter Hansen <andersrh@users.noreply.github.com> - 6.6.4-14
- Handle zero-duration floating panel animation so the panel can switch states
instantly without stutter.