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
This commit is contained in:
Vlad Zahorodnii 2023-11-22 15:05:52 +02:00
parent 073737bddb
commit f3e6d3ca19
2 changed files with 38 additions and 10 deletions

View file

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

View file

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