[x11] Check pending release when mapping

Summary:
 when unmap notify is followed by a map, the old Unmanaged will get released and never be managed again. by checking if there is a pending release operation, we can safely re-manage the window again.

BUG: 413350

Reviewers: #kwin, zzag

Reviewed By: #kwin, zzag

Subscribers: zzag, kwin, scao

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D24878
icc-effect-master
Sian Cao 2019-10-24 18:00:16 +08:00
parent 48bb38d11c
commit 1177ef3720
3 changed files with 19 additions and 2 deletions

View File

@ -328,8 +328,17 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
Unmanaged* c = findUnmanaged(event->window);
if (c == nullptr)
c = createUnmanaged(event->window);
if (c)
return c->windowEvent(e);
if (c) {
// if hasScheduledRelease is true, it means a unamp and map sequence has occurred.
// since release is scheduled after map notify, this old Unmanaged will get released
// before KWIN has chance to remanage it again. so release it right now.
if (c->hasScheduledRelease()) {
c->release();
c = createUnmanaged(event->window);
}
if (c)
return c->windowEvent(e);
}
}
return (event->event != event->window); // hide wm typical event from Qt
}
@ -1265,6 +1274,7 @@ bool Unmanaged::windowEvent(xcb_generic_event_t *e)
// short enough to not cause problems in the close window animations.
// It's of course still possible that we miss the destroy in which case non-fatal
// X errors are reported to the event loop and logged by Qt.
m_scheduledRelease = true;
QTimer::singleShot(1, this, SLOT(release()));
break;
}

View File

@ -123,6 +123,11 @@ void Unmanaged::deleteUnmanaged(Unmanaged* c)
delete c;
}
bool Unmanaged::hasScheduledRelease() const
{
return m_scheduledRelease;
}
int Unmanaged::desktop() const
{
return NET::OnAllDesktops; // TODO for some window types should be the current desktop?

View File

@ -36,6 +36,7 @@ public:
explicit Unmanaged();
bool windowEvent(xcb_generic_event_t *e);
bool track(xcb_window_t w);
bool hasScheduledRelease() const;
static void deleteUnmanaged(Unmanaged* c);
int desktop() const override;
QStringList activities() const override;
@ -62,6 +63,7 @@ private:
void configureNotifyEvent(xcb_configure_notify_event_t *e);
QWindow *findInternalWindow() const;
bool m_outline = false;
bool m_scheduledRelease = false;
};
} // namespace