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, "<N>" can be lost.
This commit is contained in:
Vlad Zahorodnii 2024-01-11 14:44:40 +02:00
parent 4ab504c994
commit bc30ca64dc
3 changed files with 8 additions and 11 deletions

View file

@ -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::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
QObject::connect(c, &Window::captionNormalChanged, c, &Window::evaluateWindowRules, Qt::UniqueConnection);
}
if (!matchTitle(c->captionNormal())) {
return false;

View file

@ -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

View file

@ -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 <N> has been dropped
if (Xcb::Extensions::self()->isShapeAvailable()) {
xcb_shape_select_input(kwinApp()->x11Connection(), window(), true);
}