kwin ver. bump

This commit is contained in:
Rmys
2025-04-28 13:55:42 +03:00
parent 2b929aa4de
commit f59b4f2714
3 changed files with 239 additions and 208 deletions
-206
View File
@@ -1,206 +0,0 @@
From f3e6d3ca196aaef28478c27fd6a3caaed3cdbdff Mon Sep 17 00:00:00 2001
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
Date: Wed, 22 Nov 2023 15:05:52 +0200
Subject: [PATCH 1/4] Ignore decoration changes of closed windows
Ideally the decoration of a closed window should not change. However,
it seems like it can happen when resuming the session.
When switching to another VT, the touchpad input device is removed, but
the touch input device is still kept on my machine. This results in
the tablet mode changing temporarily and triggering recalculation of new
borders in breeze decoration. It's a no-no thing to do if the window is
closed. We need to guard against this case. But in long term, we need to
reroute all decoration state updates through kwin so it can block state
updates when the window is closed. It's also needed for double buffered
state.
How to improve handling of tablet mode detection when switching between
VTs needs a separate investigation.
CCBUG: 477166
---
src/window.cpp | 30 +++++++++++++++++++++++-------
src/x11window.cpp | 18 +++++++++++++++---
2 files changed, 38 insertions(+), 10 deletions(-)
diff --git a/src/window.cpp b/src/window.cpp
index d60ff3db325..be9ca43b2f1 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -2625,20 +2625,32 @@ void Window::setDecoration(std::shared_ptr<KDecoration2::Decoration> decoration)
}
if (decoration) {
QMetaObject::invokeMethod(decoration.get(), QOverload<>::of(&KDecoration2::Decoration::update), Qt::QueuedConnection);
- connect(decoration.get(), &KDecoration2::Decoration::shadowChanged, this, &Window::updateShadow);
- connect(decoration.get(), &KDecoration2::Decoration::bordersChanged,
- this, &Window::updateDecorationInputShape);
- connect(decoration.get(), &KDecoration2::Decoration::resizeOnlyBordersChanged,
- this, &Window::updateDecorationInputShape);
+ connect(decoration.get(), &KDecoration2::Decoration::shadowChanged, this, [this]() {
+ if (!isDeleted()) {
+ updateShadow();
+ }
+ });
connect(decoration.get(), &KDecoration2::Decoration::bordersChanged, this, [this]() {
+ if (isDeleted()) {
+ return;
+ }
GeometryUpdatesBlocker blocker(this);
const QRectF oldGeometry = moveResizeGeometry();
if (!isShade()) {
checkWorkspacePosition(oldGeometry);
}
+ updateDecorationInputShape();
+ });
+ connect(decoration.get(), &KDecoration2::Decoration::resizeOnlyBordersChanged, this, [this]() {
+ if (!isDeleted()) {
+ updateDecorationInputShape();
+ }
+ });
+ connect(decoratedClient()->decoratedClient(), &KDecoration2::DecoratedClient::sizeChanged, this, [this]() {
+ if (!isDeleted()) {
+ updateDecorationInputShape();
+ }
});
- connect(decoratedClient()->decoratedClient(), &KDecoration2::DecoratedClient::sizeChanged,
- this, &Window::updateDecorationInputShape);
}
m_decoration.decoration = decoration;
updateDecorationInputShape();
@@ -3658,6 +3670,10 @@ void Window::sendToOutput(Output *newOutput)
void Window::checkWorkspacePosition(QRectF oldGeometry, const VirtualDesktop *oldDesktop)
{
+ if (isDeleted()) {
+ qCWarning(KWIN_CORE) << "Window::checkWorkspacePosition: called for a closed window. Consider this a bug";
+ return;
+ }
if (isDock() || isDesktop() || !isPlaceable()) {
return;
}
diff --git a/src/x11window.cpp b/src/x11window.cpp
index 724f49e0964..8b2fce35f43 100644
--- a/src/x11window.cpp
+++ b/src/x11window.cpp
@@ -1340,9 +1340,21 @@ void X11Window::createDecoration()
{
std::shared_ptr<KDecoration2::Decoration> decoration(Workspace::self()->decorationBridge()->createDecoration(this));
if (decoration) {
- connect(decoration.get(), &KDecoration2::Decoration::resizeOnlyBordersChanged, this, &X11Window::updateInputWindow);
- connect(decoration.get(), &KDecoration2::Decoration::bordersChanged, this, &X11Window::updateFrameExtents);
- connect(decoratedClient()->decoratedClient(), &KDecoration2::DecoratedClient::sizeChanged, this, &X11Window::updateInputWindow);
+ connect(decoration.get(), &KDecoration2::Decoration::resizeOnlyBordersChanged, this, [this]() {
+ if (!isDeleted()) {
+ updateInputWindow();
+ }
+ });
+ connect(decoration.get(), &KDecoration2::Decoration::bordersChanged, this, [this]() {
+ if (!isDeleted()) {
+ updateFrameExtents();
+ }
+ });
+ connect(decoratedClient()->decoratedClient(), &KDecoration2::DecoratedClient::sizeChanged, this, [this]() {
+ if (!isDeleted()) {
+ updateInputWindow();
+ }
+ });
}
setDecoration(decoration);
--
GitLab
From 4d0d153a579ed3b0bd74b7f4d95539d9e926a271 Mon Sep 17 00:00:00 2001
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
Date: Wed, 22 Nov 2023 16:23:53 +0200
Subject: [PATCH 2/4] Always reset tabbox ClientModel if a window is added or
removed
Otherwise dangling pointers can end up in TabBox::ClientModel. Tabbox is
written with hard model resets in mind. In order to fix it, the client
model has to be rewritten.
BUG: 477166
---
src/workspace.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/workspace.cpp b/src/workspace.cpp
index db37ade6eea..664fc76d975 100644
--- a/src/workspace.cpp
+++ b/src/workspace.cpp
@@ -2002,9 +2002,9 @@ void Workspace::setWasUserInteraction()
void Workspace::updateTabbox()
{
#if KWIN_BUILD_TABBOX
- if (m_tabbox->isDisplayed()) {
- m_tabbox->reset(true);
- }
+ // Need to reset the client model even if the task switcher is hidden otherwise there
+ // might be dangling pointers. Consider rewriting client model logic!
+ m_tabbox->reset(true);
#endif
}
--
GitLab
From b40b13b661c44199633d58b43ba571ca92cf30f1 Mon Sep 17 00:00:00 2001
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
Date: Wed, 22 Nov 2023 18:03:02 +0200
Subject: [PATCH 3/4] tabbox: Fix ClientModel::createClientList() reinserting
closed windows
---
src/tabbox/clientmodel.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tabbox/clientmodel.cpp b/src/tabbox/clientmodel.cpp
index af3fe4273bf..29f968d5be4 100644
--- a/src/tabbox/clientmodel.cpp
+++ b/src/tabbox/clientmodel.cpp
@@ -198,7 +198,7 @@ void ClientModel::createClientList(bool partialReset)
// TODO: new clients are not added at correct position
if (partialReset && !m_mutableClientList.isEmpty()) {
Window *firstClient = m_mutableClientList.constFirst();
- if (firstClient) {
+ if (!firstClient->isDeleted()) {
start = firstClient;
}
}
--
GitLab
From 3ffa3ed0d8ab5da79a0d4e2546c157ed317d6aa8 Mon Sep 17 00:00:00 2001
From: Vlad Zahorodnii <vlad.zahorodnii@kde.org>
Date: Wed, 22 Nov 2023 18:41:49 +0200
Subject: [PATCH 4/4] tabbox: Guard against including closed windows when using
stacking order
Closed windows are present in the stack. If user has selected
"Stacking order" sort order in task switcher KCM, we need to guard
against closed windows in the stack.
---
src/tabbox/tabbox.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tabbox/tabbox.cpp b/src/tabbox/tabbox.cpp
index 809c60e682d..2c16009ac42 100644
--- a/src/tabbox/tabbox.cpp
+++ b/src/tabbox/tabbox.cpp
@@ -171,7 +171,7 @@ bool TabBoxHandlerImpl::checkMultiScreen(Window *client) const
Window *TabBoxHandlerImpl::clientToAddToList(Window *client) const
{
- if (!client) {
+ if (!client || client->isDeleted()) {
return nullptr;
}
Window *ret = nullptr;
--
GitLab
+237
View File
@@ -0,0 +1,237 @@
diff --git a/src/backends/drm/drm_commit_thread.cpp b/src/backends/drm/drm_commit_thread.cpp
index 2b23b59bb35..49a2085ae9e 100644
--- a/src/backends/drm/drm_commit_thread.cpp
+++ b/src/backends/drm/drm_commit_thread.cpp
@@ -301,10 +301,10 @@ DrmCommitThread::~DrmCommitThread()
m_pong.notify_all();
}
m_thread->wait();
- if (m_committed) {
- m_committed->setDefunct();
- m_gpu->addDefunctCommit(std::move(m_committed));
- }
+ }
+ if (m_committed) {
+ m_committed->setDefunct();
+ m_gpu->addDefunctCommit(std::move(m_committed));
}
}
diff --git a/src/layershellv1window.cpp b/src/layershellv1window.cpp
index 0e044fcf183..b6e18dedd61 100644
--- a/src/layershellv1window.cpp
+++ b/src/layershellv1window.cpp
@@ -55,8 +55,8 @@ LayerShellV1Window::LayerShellV1Window(LayerSurfaceV1Interface *shellSurface,
connect(shellSurface->surface(), &SurfaceInterface::aboutToBeDestroyed,
this, &LayerShellV1Window::destroyWindow);
- connect(output, &Output::enabledChanged,
- this, &LayerShellV1Window::handleOutputEnabledChanged);
+ connect(workspace(), &Workspace::outputRemoved,
+ this, &LayerShellV1Window::handleOutputRemoved);
connect(shellSurface->surface(), &SurfaceInterface::sizeChanged,
this, &LayerShellV1Window::handleSizeChanged);
@@ -338,9 +338,9 @@ void LayerShellV1Window::handleAcceptsFocusChanged()
}
}
-void LayerShellV1Window::handleOutputEnabledChanged()
+void LayerShellV1Window::handleOutputRemoved(Output *output)
{
- if (!m_desiredOutput->isEnabled()) {
+ if (output == m_desiredOutput) {
closeWindow();
destroyWindow();
}
diff --git a/src/layershellv1window.h b/src/layershellv1window.h
index 923b5a6b4e0..9cdaa1d56a9 100644
--- a/src/layershellv1window.h
+++ b/src/layershellv1window.h
@@ -66,7 +66,7 @@ private:
void handleUnmapped();
void handleCommitted();
void handleAcceptsFocusChanged();
- void handleOutputEnabledChanged();
+ void handleOutputRemoved(Output *output);
void scheduleRearrange();
void activateScreenEdge();
void deactivateScreenEdge();
diff --git a/src/layershellv1window.cpp b/src/layershellv1window.cpp
index b6e18dedd61..2282ac147b8 100644
--- a/src/layershellv1window.cpp
+++ b/src/layershellv1window.cpp
@@ -204,7 +204,9 @@ void LayerShellV1Window::destroyWindow()
}
m_shellSurface->disconnect(this);
m_shellSurface->surface()->disconnect(this);
- m_desiredOutput->disconnect(this);
+
+ disconnect(workspace(), &Workspace::outputRemoved,
+ this, &LayerShellV1Window::handleOutputRemoved);
markAsDeleted();
Q_EMIT closed();
diff --git a/src/core/renderloop.cpp b/src/core/renderloop.cpp
index f2ef3ea213b..d997e2bf737 100644
--- a/src/core/renderloop.cpp
+++ b/src/core/renderloop.cpp
@@ -263,7 +263,7 @@ void RenderLoop::scheduleRepaint(Item *item, RenderLayer *layer, OutputLayer *ou
}
const bool vrr = d->presentationMode == PresentationMode::AdaptiveSync || d->presentationMode == PresentationMode::AdaptiveAsync;
const bool tearing = d->presentationMode == PresentationMode::Async || d->presentationMode == PresentationMode::AdaptiveAsync;
- if ((vrr || tearing) && workspace()->activeWindow() && d->output) {
+ if ((vrr || tearing) && workspace() && workspace()->activeWindow() && d->output) {
Window *const activeWindow = workspace()->activeWindow();
if ((item || layer || outputLayer) && activeWindowControlsVrrRefreshRate() && item != activeWindow->surfaceItem()) {
d->delayedVrrTimer.start();
diff --git a/src/events.cpp b/src/events.cpp
index 6f73c712631..b3afa19ead6 100644
--- a/src/events.cpp
+++ b/src/events.cpp
@@ -658,7 +658,7 @@ void X11Window::clientMessageEvent(xcb_client_message_event_t *e)
m_surfaceSerial = (uint64_t(e->data.data32[1]) << 32) | e->data.data32[0];
if (auto w = waylandServer()) {
if (XwaylandSurfaceV1Interface *xwaylandSurface = w->xwaylandShell()->findSurface(m_surfaceSerial)) {
- setSurface(xwaylandSurface->surface());
+ associate(xwaylandSurface);
}
}
}
diff --git a/src/wayland_server.cpp b/src/wayland_server.cpp
index 1278713b8d1..6bd34758442 100644
--- a/src/wayland_server.cpp
+++ b/src/wayland_server.cpp
@@ -350,7 +350,7 @@ bool WaylandServer::init()
return window->surfaceSerial() == surface->serial();
});
if (window) {
- window->setSurface(surface->surface());
+ window->associate(surface);
return;
}
@@ -358,7 +358,7 @@ bool WaylandServer::init()
return window->surfaceSerial() == surface->serial();
});
if (unmanaged) {
- unmanaged->setSurface(surface->surface());
+ unmanaged->associate(surface);
return;
}
});
diff --git a/src/x11window.cpp b/src/x11window.cpp
index 1a5c4c16fb2..ab9410bc7a9 100644
--- a/src/x11window.cpp
+++ b/src/x11window.cpp
@@ -33,6 +33,7 @@
#include "tiles/tilemanager.h"
#include "virtualdesktops.h"
#include "wayland/surface.h"
+#include "wayland/xwaylandshell_v1.h"
#include "wayland_server.h"
#include "workspace.h"
#include <KDecoration3/DecoratedWindow>
@@ -588,11 +589,6 @@ bool X11Window::track(xcb_window_t w)
switch (kwinApp()->operationMode()) {
case Application::OperationModeWayland:
// The wayland surface is associated with the override-redirect window asynchronously.
- if (surface()) {
- associate();
- } else {
- connect(this, &Window::surfaceChanged, this, &X11Window::associate);
- }
break;
case Application::OperationModeX11:
// We have no way knowing whether the override-redirect window can be painted. Mark it
@@ -1207,11 +1203,6 @@ bool X11Window::manage(xcb_window_t w, bool isMapped)
switch (kwinApp()->operationMode()) {
case Application::OperationModeWayland:
// The wayland surface is associated with the window asynchronously.
- if (surface()) {
- associate();
- } else {
- connect(this, &Window::surfaceChanged, this, &X11Window::associate);
- }
connect(kwinApp(), &Application::xwaylandScaleChanged, this, &X11Window::handleXwaylandScaleChanged);
break;
case Application::OperationModeX11:
@@ -5027,8 +5018,10 @@ void X11Window::updateWindowPixmap()
}
}
-void X11Window::associate()
+void X11Window::associate(XwaylandSurfaceV1Interface *shellSurface)
{
+ setSurface(shellSurface->surface());
+
if (surface()->isMapped()) {
if (m_syncRequest.acked) {
finishSync();
diff --git a/src/x11window.h b/src/x11window.h
index 797f600d4fb..d97f93764c1 100644
--- a/src/x11window.h
+++ b/src/x11window.h
@@ -39,6 +39,7 @@ namespace KWin
{
class KillPrompt;
+class XwaylandSurfaceV1Interface;
/**
* @brief Defines Predicates on how to search for a Client.
@@ -82,6 +83,8 @@ public:
explicit X11Window();
~X11Window() override; ///< Use destroyWindow() or releaseWindow()
+ void associate(XwaylandSurfaceV1Interface *shellSurface);
+
xcb_window_t frameId() const;
xcb_window_t window() const;
xcb_window_t wrapperId() const;
@@ -439,7 +442,6 @@ private:
QWindow *findInternalWindow() const;
void checkOutput();
- void associate();
void handleXwaylandScaleChanged();
void handleCommitted();
diff --git a/src/x11window.cpp b/src/x11window.cpp
index ab9410bc7a..218bc76af9 100644
--- a/src/x11window.cpp
+++ b/src/x11window.cpp
@@ -5020,6 +5020,10 @@ void X11Window::updateWindowPixmap()
void X11Window::associate(XwaylandSurfaceV1Interface *shellSurface)
{
+ if (surface()) {
+ disconnect(surface(), &SurfaceInterface::committed, this, &X11Window::handleCommitted);
+ }
+
setSurface(shellSurface->surface());
if (surface()->isMapped()) {
diff --git a/src/opengl/eglcontext.cpp b/src/opengl/eglcontext.cpp
index 48017391281..f1f9a4e3fa6 100644
--- a/src/opengl/eglcontext.cpp
+++ b/src/opengl/eglcontext.cpp
@@ -71,8 +71,8 @@ EglContext::EglContext(EglDisplay *display, EGLConfig config, ::EGLContext conte
EglContext::~EglContext()
{
- makeCurrent();
- if (m_vao) {
+ const bool current = makeCurrent();
+ if (m_vao && current) {
glDeleteVertexArrays(1, &m_vao);
}
m_shaderManager.reset();
+2 -2
View File
@@ -96,7 +96,7 @@
<Dependency>plasma-wayland-protocols</Dependency>
</BuildDependencies>
<Patches>
<!-- <Patch level="1">4692.patch</Patch> -->
<Patch level="1">git.patch</Patch>
</Patches>
</Source>
@@ -234,7 +234,7 @@
</Package>
<History>
<Update release="87">
<Update release="88">
<Date>2025-04-02</Date>
<Version>6.3.4</Version>
<Comment>Version bump.</Comment>