testing approach
This commit is contained in:
parent
cf0089e100
commit
b989e4b7f0
4 changed files with 345 additions and 4 deletions
218
sonic-win/sonic-win-6.6.4-panel-compositor-atom.patch
Normal file
218
sonic-win/sonic-win-6.6.4-panel-compositor-atom.patch
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
diff -ruN a/src/events.cpp b/src/events.cpp
|
||||
--- a/src/events.cpp 2026-04-08 10:00:41.000000000 -0300
|
||||
+++ b/src/events.cpp 2026-07-03 20:48:53.648591796 -0300
|
||||
@@ -398,7 +398,7 @@
|
||||
}
|
||||
if ((dirtyProperties & NET::WMStrut) != 0
|
||||
|| (dirtyProperties2 & NET::WM2ExtendedStrut) != 0) {
|
||||
- workspace()->rearrange();
|
||||
+ workspace()->scheduleRearrange();
|
||||
}
|
||||
if ((dirtyProperties & NET::WMIcon) != 0) {
|
||||
getIcons();
|
||||
diff -ruN a/src/plugins/backgroundcontrast/contrast.cpp b/src/plugins/backgroundcontrast/contrast.cpp
|
||||
--- a/src/plugins/backgroundcontrast/contrast.cpp 2026-04-08 10:00:41.000000000 -0300
|
||||
+++ b/src/plugins/backgroundcontrast/contrast.cpp 2026-07-03 20:52:36.464290127 -0300
|
||||
@@ -28,6 +28,7 @@
|
||||
{
|
||||
|
||||
static const QByteArray s_contrastAtomName = QByteArrayLiteral("_KDE_NET_WM_BACKGROUND_CONTRAST_REGION");
|
||||
+static const QByteArray s_panelAnimatingAtomName = QByteArrayLiteral("_SONIC_WM_PANEL_ANIMATING");
|
||||
|
||||
ContrastManagerInterface *ContrastEffect::s_contrastManager = nullptr;
|
||||
QTimer *ContrastEffect::s_contrastManagerRemoveTimer = nullptr;
|
||||
@@ -42,6 +43,12 @@
|
||||
if (m_shader && m_shader->isValid()) {
|
||||
if (effects->xcbConnection()) {
|
||||
m_net_wm_contrast_region = effects->announceSupportProperty(s_contrastAtomName, this);
|
||||
+ xcb_connection_t *c = effects->xcbConnection();
|
||||
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(c, xcb_intern_atom_unchecked(c, false, s_panelAnimatingAtomName.length(), s_panelAnimatingAtomName.constData()), nullptr);
|
||||
+ if (reply) {
|
||||
+ m_panelAnimatingAtom = reply->atom;
|
||||
+ free(reply);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +60,14 @@
|
||||
connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() {
|
||||
if (m_shader && m_shader->isValid()) {
|
||||
m_net_wm_contrast_region = effects->announceSupportProperty(s_contrastAtomName, this);
|
||||
+ if (effects->xcbConnection()) {
|
||||
+ xcb_connection_t *c = effects->xcbConnection();
|
||||
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(c, xcb_intern_atom_unchecked(c, false, s_panelAnimatingAtomName.length(), s_panelAnimatingAtomName.constData()), nullptr);
|
||||
+ if (reply) {
|
||||
+ m_panelAnimatingAtom = reply->atom;
|
||||
+ free(reply);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
});
|
||||
|
||||
@@ -182,11 +197,36 @@
|
||||
|
||||
void ContrastEffect::slotPropertyNotify(EffectWindow *w, long atom)
|
||||
{
|
||||
- if (w && atom == m_net_wm_contrast_region && m_net_wm_contrast_region != XCB_ATOM_NONE) {
|
||||
+ if (!w) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (atom == m_panelAnimatingAtom && m_panelAnimatingAtom != XCB_ATOM_NONE) {
|
||||
+ if (!isPanelAnimating(w)) {
|
||||
+ updateContrastRegion(w);
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ if (atom == m_net_wm_contrast_region && m_net_wm_contrast_region != XCB_ATOM_NONE) {
|
||||
+ if (isPanelAnimating(w)) {
|
||||
+ return;
|
||||
+ }
|
||||
updateContrastRegion(w);
|
||||
}
|
||||
}
|
||||
|
||||
+bool ContrastEffect::isPanelAnimating(EffectWindow *w) const
|
||||
+{
|
||||
+ if (m_panelAnimatingAtom == XCB_ATOM_NONE) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ const QByteArray value = w->readProperty(m_panelAnimatingAtom, XCB_ATOM_CARDINAL, 32);
|
||||
+ if (value.size() < static_cast<int>(sizeof(uint32_t))) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ const uint32_t *cardinals = reinterpret_cast<const uint32_t *>(value.constData());
|
||||
+ return cardinals[0] != 0;
|
||||
+}
|
||||
+
|
||||
QMatrix4x4 ContrastEffect::colorMatrix(qreal contrast, qreal intensity, qreal saturation)
|
||||
{
|
||||
QMatrix4x4 satMatrix; // saturation
|
||||
diff -ruN a/src/plugins/backgroundcontrast/contrast.h b/src/plugins/backgroundcontrast/contrast.h
|
||||
--- a/src/plugins/backgroundcontrast/contrast.h 2026-04-08 10:00:41.000000000 -0300
|
||||
+++ b/src/plugins/backgroundcontrast/contrast.h 2026-07-03 20:52:02.805738497 -0300
|
||||
@@ -57,6 +57,7 @@
|
||||
QRegion contrastRegion(const EffectWindow *w) const;
|
||||
bool shouldContrast(const EffectWindow *w, int mask, const WindowPaintData &data) const;
|
||||
void updateContrastRegion(EffectWindow *w);
|
||||
+ bool isPanelAnimating(EffectWindow *w) const;
|
||||
void doContrast(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, const QRegion &shape, const float opacity, const QMatrix4x4 &screenProjection);
|
||||
void uploadRegion(std::span<QVector2D> map, const QRegion ®ion, qreal scale);
|
||||
Q_REQUIRED_RESULT bool uploadGeometry(GLVertexBuffer *vbo, const QRegion ®ion, qreal scale);
|
||||
@@ -65,6 +66,7 @@
|
||||
std::unique_ptr<ContrastShader> m_shader;
|
||||
|
||||
long m_net_wm_contrast_region = 0;
|
||||
+ long m_panelAnimatingAtom = 0;
|
||||
QHash<const EffectWindow *, QMetaObject::Connection> m_contrastChangedConnections; // used only in Wayland to keep track of effect changed
|
||||
struct Data
|
||||
{
|
||||
diff -ruN a/src/plugins/blur/blur.cpp b/src/plugins/blur/blur.cpp
|
||||
--- a/src/plugins/blur/blur.cpp 2026-04-08 10:00:41.000000000 -0300
|
||||
+++ b/src/plugins/blur/blur.cpp 2026-07-03 20:52:27.003135068 -0300
|
||||
@@ -48,6 +48,7 @@
|
||||
{
|
||||
|
||||
static const QByteArray s_blurAtomName = QByteArrayLiteral("_KDE_NET_WM_BLUR_BEHIND_REGION");
|
||||
+static const QByteArray s_panelAnimatingAtomName = QByteArrayLiteral("_SONIC_WM_PANEL_ANIMATING");
|
||||
|
||||
BlurManagerInterface *BlurEffect::s_blurManager = nullptr;
|
||||
QTimer *BlurEffect::s_blurManagerRemoveTimer = nullptr;
|
||||
@@ -125,6 +126,12 @@
|
||||
|
||||
if (effects->xcbConnection()) {
|
||||
net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this);
|
||||
+ xcb_connection_t *c = effects->xcbConnection();
|
||||
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(c, xcb_intern_atom_unchecked(c, false, s_panelAnimatingAtomName.length(), s_panelAnimatingAtomName.constData()), nullptr);
|
||||
+ if (reply) {
|
||||
+ m_panelAnimatingAtom = reply->atom;
|
||||
+ free(reply);
|
||||
+ }
|
||||
}
|
||||
|
||||
connect(effects, &EffectsHandler::windowAdded, this, &BlurEffect::slotWindowAdded);
|
||||
@@ -132,6 +139,14 @@
|
||||
connect(effects, &EffectsHandler::propertyNotify, this, &BlurEffect::slotPropertyNotify);
|
||||
connect(effects, &EffectsHandler::xcbConnectionChanged, this, [this]() {
|
||||
net_wm_blur_region = effects->announceSupportProperty(s_blurAtomName, this);
|
||||
+ if (effects->xcbConnection()) {
|
||||
+ xcb_connection_t *c = effects->xcbConnection();
|
||||
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(c, xcb_intern_atom_unchecked(c, false, s_panelAnimatingAtomName.length(), s_panelAnimatingAtomName.constData()), nullptr);
|
||||
+ if (reply) {
|
||||
+ m_panelAnimatingAtom = reply->atom;
|
||||
+ free(reply);
|
||||
+ }
|
||||
+ }
|
||||
});
|
||||
|
||||
// Fetch the blur regions for all windows
|
||||
@@ -292,11 +307,38 @@
|
||||
|
||||
void BlurEffect::slotPropertyNotify(EffectWindow *w, long atom)
|
||||
{
|
||||
- if (w && atom == net_wm_blur_region && net_wm_blur_region != XCB_ATOM_NONE) {
|
||||
+ if (!w) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (atom == m_panelAnimatingAtom && m_panelAnimatingAtom != XCB_ATOM_NONE) {
|
||||
+ // When the panel stops animating, apply any blur region updates we deferred.
|
||||
+ if (!isPanelAnimating(w)) {
|
||||
+ updateBlurRegion(w);
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ if (atom == net_wm_blur_region && net_wm_blur_region != XCB_ATOM_NONE) {
|
||||
+ if (isPanelAnimating(w)) {
|
||||
+ // Defer blur region updates until the panel finishes its animation.
|
||||
+ return;
|
||||
+ }
|
||||
updateBlurRegion(w);
|
||||
}
|
||||
}
|
||||
|
||||
+bool BlurEffect::isPanelAnimating(EffectWindow *w) const
|
||||
+{
|
||||
+ if (m_panelAnimatingAtom == XCB_ATOM_NONE) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ const QByteArray value = w->readProperty(m_panelAnimatingAtom, XCB_ATOM_CARDINAL, 32);
|
||||
+ if (value.size() < static_cast<int>(sizeof(uint32_t))) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ const uint32_t *cardinals = reinterpret_cast<const uint32_t *>(value.constData());
|
||||
+ return cardinals[0] != 0;
|
||||
+}
|
||||
+
|
||||
void BlurEffect::setupDecorationConnections(EffectWindow *w)
|
||||
{
|
||||
if (!w->decoration()) {
|
||||
diff -ruN a/src/plugins/blur/blur.h b/src/plugins/blur/blur.h
|
||||
--- a/src/plugins/blur/blur.h 2026-04-08 10:00:41.000000000 -0300
|
||||
+++ b/src/plugins/blur/blur.h 2026-07-03 20:51:43.097415496 -0300
|
||||
@@ -83,6 +83,7 @@
|
||||
bool decorationSupportsBlurBehind(const EffectWindow *w) const;
|
||||
bool shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data) const;
|
||||
void updateBlurRegion(EffectWindow *w);
|
||||
+ bool isPanelAnimating(EffectWindow *w) const;
|
||||
void blur(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, const QRegion ®ion, WindowPaintData &data);
|
||||
GLTexture *ensureNoiseTexture();
|
||||
|
||||
@@ -136,6 +137,7 @@
|
||||
|
||||
bool m_valid = false;
|
||||
long net_wm_blur_region = 0;
|
||||
+ long m_panelAnimatingAtom = 0;
|
||||
QRegion m_paintedArea; // keeps track of all painted areas (from bottom to top)
|
||||
QRegion m_currentBlur; // keeps track of the currently blured area of the windows(from bottom to top)
|
||||
|
||||
diff -ruN a/src/workspace.cpp b/src/workspace.cpp
|
||||
--- a/src/workspace.cpp 2026-04-08 10:00:41.000000000 -0300
|
||||
+++ b/src/workspace.cpp 2026-07-03 20:48:53.649393515 -0300
|
||||
@@ -2178,7 +2178,7 @@
|
||||
|
||||
void Workspace::scheduleRearrange()
|
||||
{
|
||||
- m_rearrangeTimer.start(0);
|
||||
+ m_rearrangeTimer.start(50);
|
||||
}
|
||||
|
||||
void Workspace::rearrange()
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
Name: sonic-win
|
||||
Version: 6.6.4
|
||||
Release: 12%{?dist}
|
||||
Release: 14%{?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,7 +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
|
||||
Patch0: sonic-win-6.6.4-panel-compositor-atom.patch
|
||||
|
||||
## proposed patches
|
||||
|
||||
|
|
@ -298,6 +298,11 @@ mkdir -p %{buildroot}%{_sysconfdir}/xdg/Xwayland-session.d
|
|||
|
||||
|
||||
%changelog
|
||||
* Fri Jul 03 2026 Anders da Silva Rytter Hansen <andersrh@users.noreply.github.com> - 6.6.4-13
|
||||
- Batch blur and contrast region updates for panels that set the private
|
||||
_SONIC_WM_PANEL_ANIMATING X atom during floating animation, keeping the
|
||||
strut-throttling behavior in place.
|
||||
|
||||
* 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.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
diff -ruN a/shell/panelview.cpp b/shell/panelview.cpp
|
||||
--- a/shell/panelview.cpp 2026-04-08 06:33:10.000000000 -0300
|
||||
+++ b/shell/panelview.cpp 2026-07-03 21:54:49.238018607 -0300
|
||||
@@ -1364,6 +1364,37 @@
|
||||
}
|
||||
}
|
||||
|
||||
+void PanelView::setPanelAnimating(bool animating)
|
||||
+{
|
||||
+ if (!KX11Extras::compositingActive()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ auto *x11App = qGuiApp->nativeInterface<QNativeInterface::QX11Application>();
|
||||
+ if (!x11App) {
|
||||
+ return;
|
||||
+ }
|
||||
+ xcb_connection_t *connection = x11App->connection();
|
||||
+ if (m_panelAnimatingAtom == XCB_ATOM_NONE) {
|
||||
+ constexpr QByteArrayView atomName("_SONIC_WM_PANEL_ANIMATING");
|
||||
+ xcb_intern_atom_cookie_t cookie = xcb_intern_atom_unchecked(connection, false, atomName.length(), atomName.constData());
|
||||
+ xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookie, nullptr);
|
||||
+ if (reply) {
|
||||
+ m_panelAnimatingAtom = reply->atom;
|
||||
+ free(reply);
|
||||
+ }
|
||||
+ }
|
||||
+ if (m_panelAnimatingAtom == XCB_ATOM_NONE) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (animating) {
|
||||
+ uint32_t value = 1;
|
||||
+ xcb_change_property(connection, XCB_PROP_MODE_REPLACE, winId(), m_panelAnimatingAtom, XCB_ATOM_CARDINAL, 32, 1, &value);
|
||||
+ } else {
|
||||
+ xcb_delete_property(connection, winId(), m_panelAnimatingAtom);
|
||||
+ }
|
||||
+ xcb_flush(connection);
|
||||
+}
|
||||
+
|
||||
bool PanelView::canSetStrut() const
|
||||
{
|
||||
// read the wm name, need to do this every time which means a roundtrip unfortunately
|
||||
@@ -1587,10 +1618,10 @@
|
||||
return;
|
||||
}
|
||||
m_floatingness = get<double>(value);
|
||||
- positionAndResizePanel();
|
||||
});
|
||||
connect(&m_floatingnessAnimation, &QPropertyAnimation::finished, rootObject, [this]() {
|
||||
- updateMask();
|
||||
+ setPanelAnimating(false);
|
||||
+ positionAndResizePanel();
|
||||
});
|
||||
connect(rootObject, SIGNAL(minPanelHeightChanged()), this, SLOT(updatePadding()));
|
||||
connect(rootObject, SIGNAL(minPanelWidthChanged()), this, SLOT(updatePadding()));
|
||||
@@ -1784,12 +1815,24 @@
|
||||
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();
|
||||
|
||||
// positionPanel and updateMask are called by m_floatingnessAnimation
|
||||
if (m_floatingnessAnimation.targetObject()) {
|
||||
+ if (instantAnimation) {
|
||||
+ updateMask();
|
||||
+ return;
|
||||
+ }
|
||||
+ setPanelAnimating(true);
|
||||
m_floatingnessAnimation.start();
|
||||
}
|
||||
}
|
||||
diff -ruN a/shell/panelview.h b/shell/panelview.h
|
||||
--- a/shell/panelview.h 2026-04-08 06:33:10.000000000 -0300
|
||||
+++ b/shell/panelview.h 2026-07-03 20:50:54.914625829 -0300
|
||||
@@ -8,10 +8,13 @@
|
||||
|
||||
#include <Plasma/Theme>
|
||||
#include <QPointer>
|
||||
+#include <QAbstractAnimation>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QTimer>
|
||||
#include <QWindow> // For WId
|
||||
|
||||
+#include <xcb/xcb.h>
|
||||
+
|
||||
#include <KSvg/FrameSvg>
|
||||
#include <kwindoweffects.h>
|
||||
|
||||
@@ -307,6 +310,7 @@
|
||||
void handleQmlStatusChange(QQmlComponent::Status status);
|
||||
void updateMask();
|
||||
void updateEnabledBorders();
|
||||
+ void setPanelAnimating(bool animating);
|
||||
void updatePadding();
|
||||
void updateFloating();
|
||||
void updateFloatingAnimationDuration();
|
||||
@@ -363,6 +367,7 @@
|
||||
LengthMode m_lengthMode;
|
||||
Plasma::Theme m_theme;
|
||||
QTimer m_unhideTimer;
|
||||
+ xcb_atom_t m_panelAnimatingAtom = XCB_ATOM_NONE;
|
||||
Plasma::Types::BackgroundHints m_backgroundHints;
|
||||
KSvg::FrameSvg::EnabledBorders m_enabledBorders = KSvg::FrameSvg::AllBorders;
|
||||
QPointer<QScreen> m_lastScreen;
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
Name: sonic-workspace
|
||||
Summary: Plasma workspace, applications and applets
|
||||
Version: 6.6.4
|
||||
Release: 15%{?dist}
|
||||
Release: 16%{?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,7 +37,7 @@ Source40: ssh-agent.conf
|
|||
Source41: spice-vdagent.conf
|
||||
|
||||
## upstream patches
|
||||
Patch0: sonic-workspace-6.6.4-mask-throttle.patch
|
||||
Patch0: sonic-workspace-6.6.4-panel-compositor-atom.patch
|
||||
|
||||
## upstreamable Patches
|
||||
|
||||
|
|
@ -691,6 +691,12 @@ fi
|
|||
|
||||
|
||||
%changelog
|
||||
* Fri Jul 03 2026 Anders da Silva Rytter Hansen <andersrh@users.noreply.github.com> - 6.6.4-16
|
||||
- Move panel floating animation coordination into the compositor via a private
|
||||
_SONIC_WM_PANEL_ANIMATING X atom. The panel no longer throttles its own mask
|
||||
updates; instead it tells the compositor when it is animating, and the
|
||||
compositor batches blur/contrast region updates until the animation finishes.
|
||||
|
||||
* 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue