From bc30ca64dc3b4d35c3bd7fb77749f949eb2f73bd Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Thu, 11 Jan 2024 14:44:40 +0200 Subject: [PATCH] Fix evaluating window rules for closed windows gedit changes its caption from "Untitled document - gedit" to "gedit" when it closes. This schedules Window::evaluateWindowRules() to be called when the window is already marked as deleted. kwin then crashes. In order to prevent that, a direct connection can be used instead. But then the caption must be initialized extra carefully because if the window rule changes the window type, "" can be lost. --- src/rules.cpp | 5 +---- src/window.cpp | 4 +++- src/x11window.cpp | 10 ++++------ 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/rules.cpp b/src/rules.cpp index 6ddad43c97..4a91485ef9 100644 --- a/src/rules.cpp +++ b/src/rules.cpp @@ -408,10 +408,7 @@ bool Rules::match(const Window *c) const return false; } if (titlematch != UnimportantMatch) { // track title changes to rematch rules - QObject::connect(c, &Window::captionChanged, c, &Window::evaluateWindowRules, - // QueuedConnection, because title may change before - // the client is ready (could segfault!) - static_cast(Qt::QueuedConnection | Qt::UniqueConnection)); + QObject::connect(c, &Window::captionNormalChanged, c, &Window::evaluateWindowRules, Qt::UniqueConnection); } if (!matchTitle(c->captionNormal())) { return false; diff --git a/src/window.cpp b/src/window.cpp index e9f26e6c66..0982649be4 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -4084,7 +4084,7 @@ void Window::evaluateWindowRules() void Window::setupWindowRules() { - disconnect(this, &Window::captionChanged, this, &Window::evaluateWindowRules); + disconnect(this, &Window::captionNormalChanged, this, &Window::evaluateWindowRules); m_rules = workspace()->rulebook()->find(this); // check only after getting the rules, because there may be a rule forcing window type } @@ -4099,6 +4099,7 @@ void Window::updateWindowRules(Rules::Types selection) void Window::finishWindowRules() { + disconnect(this, &Window::captionNormalChanged, this, &Window::evaluateWindowRules); updateWindowRules(Rules::All); m_rules = WindowRules(); } @@ -4107,6 +4108,7 @@ void Window::finishWindowRules() // Used e.g. after the rules have been modified using the kcm. void Window::applyWindowRules() { + Q_ASSERT(!isDeleted()); // apply force rules // Placement - does need explicit update, just like some others below // Geometry : setGeometry() doesn't check rules diff --git a/src/x11window.cpp b/src/x11window.cpp index b782cd479d..f4c6e166bd 100644 --- a/src/x11window.cpp +++ b/src/x11window.cpp @@ -639,15 +639,13 @@ bool X11Window::manage(xcb_window_t w, bool isMapped) readWmClientLeader(wmClientLeaderCookie); getWmClientMachine(); getSyncCounter(); - // First only read the caption text, so that setupWindowRules() can use it for matching, - // and only then really set the caption using setCaption(), which checks for duplicates etc. - // and also relies on rules already existing - cap_normal = readName(); - setupWindowRules(); - setCaption(cap_normal, true); + setCaption(readName()); + setupWindowRules(); connect(this, &X11Window::windowClassChanged, this, &X11Window::evaluateWindowRules); + updateCaption(); // in case the window type has been changed by a window rule and has been dropped + if (Xcb::Extensions::self()->isShapeAvailable()) { xcb_shape_select_input(kwinApp()->x11Connection(), window(), true); }