[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:
parent
48bb38d11c
commit
1177ef3720
3 changed files with 19 additions and 2 deletions
14
events.cpp
14
events.cpp
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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?
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue