Commit 4a6badc2 authored by Vlad Zahorodnii's avatar Vlad Zahorodnii
Browse files

Ignore setActive() for windows that are being deleted

We may call setActive() on a window that is being deleted. We cannot
guarantee that at that moment the X11 window or the Wayland surface is
still valid. So, the best course of actions is to do nothing.

BUG: 424255
parent 6139ea78
......@@ -201,6 +201,9 @@ void AbstractClient::setIcon(const QIcon &icon)
void AbstractClient::setActive(bool act)
{
if (isZombie()) {
return;
}
if (m_active == act) {
return;
}
......@@ -235,6 +238,17 @@ void AbstractClient::doSetActive()
{
}
bool AbstractClient::isZombie() const
{
return m_zombie;
}
void AbstractClient::markAsZombie()
{
Q_ASSERT(!m_zombie);
m_zombie = true;
}
Layer AbstractClient::layer() const
{
if (m_layer == UnknownLayer)
......
......@@ -358,6 +358,7 @@ public:
return m_icon;
}
bool isZombie() const;
bool isActive() const {
return m_active;
}
......@@ -927,6 +928,7 @@ protected:
void startAutoRaise();
void autoRaise();
bool isMostRecentlyRaised() const;
void markAsZombie();
/**
* Whether the window accepts focus.
* The difference to wantsInput is that the implementation should not check rules and return
......@@ -1237,6 +1239,7 @@ private:
bool m_skipSwitcher = false;
QIcon m_icon;
bool m_active = false;
bool m_zombie = false;
bool m_keepAbove = false;
bool m_keepBelow = false;
bool m_demandsAttention = false;
......
......@@ -408,6 +408,7 @@ void InternalClient::showOnScreenEdge()
void InternalClient::destroyClient()
{
markAsZombie();
if (isMoveResize()) {
leaveMoveResize();
}
......
......@@ -146,7 +146,6 @@ X11Client::X11Client()
info = nullptr;
deleting = false;
m_fullscreenMode = FullScreenNone;
hidden = false;
noborder = false;
......@@ -214,8 +213,7 @@ void X11Client::deleteClient(X11Client *c)
*/
void X11Client::releaseWindow(bool on_shutdown)
{
Q_ASSERT(!deleting);
deleting = true;
markAsZombie();
#ifdef KWIN_BUILD_TABBOX
TabBox::TabBox *tabBox = TabBox::TabBox::self();
if (tabBox->isDisplayed() && tabBox->currentClient() == this) {
......@@ -288,8 +286,7 @@ void X11Client::releaseWindow(bool on_shutdown)
*/
void X11Client::destroyClient()
{
Q_ASSERT(!deleting);
deleting = true;
markAsZombie();
#ifdef KWIN_BUILD_TABBOX
TabBox::TabBox *tabBox = TabBox::TabBox::self();
if (tabBox && tabBox->isDisplayed() && tabBox->currentClient() == this) {
......@@ -1099,7 +1096,7 @@ void X11Client::destroyDecoration()
move(grav);
if (compositing())
discardWindowPixmap();
if (!deleting) {
if (!isZombie()) {
emit geometryShapeChanged(this, oldgeom);
}
}
......@@ -1533,7 +1530,7 @@ void X11Client::doSetShade(ShadeMode previousShadeMode)
void X11Client::updateVisibility()
{
if (deleting)
if (isZombie())
return;
if (hidden) {
info->setState(NET::Hidden, NET::Hidden);
......@@ -1579,7 +1576,7 @@ void X11Client::updateVisibility()
void X11Client::exportMappingState(int s)
{
Q_ASSERT(m_client != XCB_WINDOW_NONE);
Q_ASSERT(!deleting || s == XCB_ICCCM_WM_STATE_WITHDRAWN);
Q_ASSERT(!isZombie() || s == XCB_ICCCM_WM_STATE_WITHDRAWN);
if (s == XCB_ICCCM_WM_STATE_WITHDRAWN) {
m_client.deleteProperty(atoms->wm_state);
return;
......@@ -2202,7 +2199,7 @@ void X11Client::fetchIconicName()
void X11Client::setClientShown(bool shown)
{
if (deleting)
if (isZombie())
return; // Don't change shown status if this client is being deleted
if (shown != hidden)
return; // nothing to change
......
......@@ -491,7 +491,6 @@ private:
xcb_window_t m_transientForId;
xcb_window_t m_originalTransientForId;
X11Client *shade_below;
uint deleting : 1; ///< True when doing cleanup and destroying the client
Xcb::MotifHints m_motif;
uint hidden : 1; ///< Forcibly hidden by calling hide()
uint noborder : 1;
......
......@@ -188,7 +188,7 @@ bool XdgSurfaceClient::stateCompare() const
void XdgSurfaceClient::scheduleConfigure()
{
if (isClosing()) {
if (isZombie()) {
return;
}
......@@ -518,7 +518,7 @@ void XdgSurfaceClient::addDamage(const QRegion &damage)
bool XdgSurfaceClient::isShown(bool shaded_is_shown) const
{
Q_UNUSED(shaded_is_shown)
return !isClosing() && !isHidden() && !isMinimized();
return !isZombie() && !isHidden() && !isMinimized();
}
bool XdgSurfaceClient::isHiddenInternal() const
......@@ -564,14 +564,9 @@ void XdgSurfaceClient::internalHide()
emit windowHidden(this);
}
bool XdgSurfaceClient::isClosing() const
{
return m_isClosing;
}
void XdgSurfaceClient::destroyClient()
{
m_isClosing = true;
markAsZombie();
m_configureTimer->stop();
if (isMoveResize()) {
leaveMoveResize();
......@@ -1076,7 +1071,7 @@ bool XdgToplevelClient::acceptsFocus() const
return m_plasmaShellSurface->panelTakesFocus();
}
}
return !isClosing() && readyForPainting();
return !isZombie() && readyForPainting();
}
Layer XdgToplevelClient::layerForDock() const
......@@ -1427,7 +1422,7 @@ void XdgToplevelClient::installServerDecoration(ServerSideDecorationInterface *d
m_serverDecoration = decoration;
connect(m_serverDecoration, &ServerSideDecorationInterface::destroyed, this, [this] {
if (!isClosing() && readyForPainting()) {
if (!isZombie() && readyForPainting()) {
updateDecoration(/* check_workspace_pos */ true);
}
});
......@@ -1449,7 +1444,7 @@ void XdgToplevelClient::installXdgDecoration(XdgToplevelDecorationV1Interface *d
m_xdgDecoration = decoration;
connect(m_xdgDecoration, &XdgToplevelDecorationV1Interface::destroyed, this, [this] {
if (!isClosing() && m_isInitialized) {
if (!isZombie() && m_isInitialized) {
updateDecoration(/* check_workspace_pos */ true);
}
});
......
......@@ -82,7 +82,6 @@ public:
QRect requestedClientGeometry() const;
QSize requestedClientSize() const;
QRect clientGeometry() const;
bool isClosing() const;
bool isHidden() const;
protected:
......@@ -121,7 +120,6 @@ private:
QRect m_requestedFrameGeometry;
QRect m_bufferGeometry;
QRect m_requestedClientGeometry;
bool m_isClosing = false;
bool m_isHidden = false;
bool m_haveNextWindowGeometry = false;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment