[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
This commit is contained in:
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); Unmanaged* c = findUnmanaged(event->window);
if (c == nullptr) if (c == nullptr)
c = createUnmanaged(event->window); c = createUnmanaged(event->window);
if (c) if (c) {
return c->windowEvent(e); // 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 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. // 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 // 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. // X errors are reported to the event loop and logged by Qt.
m_scheduledRelease = true;
QTimer::singleShot(1, this, SLOT(release())); QTimer::singleShot(1, this, SLOT(release()));
break; break;
} }

View file

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

View file

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