Destroy ShellClient before Workspace is gone
Summary: Managing lifetime of objects during tear down is a bit clunky in KWin mostly because the wayland server outlives the workspace.3f4e733468
tried to tackle one aspect of this problem, but the proposed solution is good only in short term. If a ShellClient wants to discard force temporarily rules, it needs to access RuleBook, whose lifetime is bounded to the workspace, no matter what happens. Otherwise, the force temporarily rule will be applied again on the next startup. It's worth to mention that there was another attempt to address this problem, see commit826b9742e9
. It was reverted because some internal clients may need to destroy Wayland resources during tear down. This change takes another approach. In order to ensure that ShellClient can access RuleBook during tear down, we manually destroy Wayland clients in destructor of the Workspace class. Something is done already for X11 clients. Reviewers: #kwin Subscribers: romangg, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D22986
This commit is contained in:
parent
9525d71099
commit
45c93c6cae
3 changed files with 32 additions and 20 deletions
|
@ -423,11 +423,10 @@ void ShellClient::destroyClient()
|
||||||
if (isMoveResize()) {
|
if (isMoveResize()) {
|
||||||
leaveMoveResize();
|
leaveMoveResize();
|
||||||
}
|
}
|
||||||
Deleted *del = nullptr;
|
|
||||||
if (workspace()) {
|
// Replace ShellClient with an instance of Deleted in the stacking order.
|
||||||
del = Deleted::create(this);
|
Deleted *deleted = Deleted::create(this);
|
||||||
}
|
emit windowClosed(this, deleted);
|
||||||
emit windowClosed(this, del);
|
|
||||||
|
|
||||||
// Remove Force Temporarily rules.
|
// Remove Force Temporarily rules.
|
||||||
RuleBook::self()->discardUsed(this, true);
|
RuleBook::self()->discardUsed(this, true);
|
||||||
|
@ -435,25 +434,23 @@ void ShellClient::destroyClient()
|
||||||
destroyWindowManagementInterface();
|
destroyWindowManagementInterface();
|
||||||
destroyDecoration();
|
destroyDecoration();
|
||||||
|
|
||||||
if (workspace()) {
|
StackingUpdatesBlocker blocker(workspace());
|
||||||
StackingUpdatesBlocker blocker(workspace());
|
if (transientFor()) {
|
||||||
if (transientFor()) {
|
transientFor()->removeTransient(this);
|
||||||
transientFor()->removeTransient(this);
|
}
|
||||||
}
|
for (auto it = transients().constBegin(); it != transients().constEnd();) {
|
||||||
for (auto it = transients().constBegin(); it != transients().constEnd();) {
|
if ((*it)->transientFor() == this) {
|
||||||
if ((*it)->transientFor() == this) {
|
removeTransient(*it);
|
||||||
removeTransient(*it);
|
it = transients().constBegin(); // restart, just in case something more has changed with the list
|
||||||
it = transients().constBegin(); // restart, just in case something more has changed with the list
|
} else {
|
||||||
} else {
|
++it;
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
waylandServer()->removeClient(this);
|
waylandServer()->removeClient(this);
|
||||||
|
|
||||||
if (del) {
|
deleted->unrefWindow();
|
||||||
del->unrefWindow();
|
|
||||||
}
|
|
||||||
m_shellSurface = nullptr;
|
m_shellSurface = nullptr;
|
||||||
m_xdgShellSurface = nullptr;
|
m_xdgShellSurface = nullptr;
|
||||||
m_xdgShellPopup = nullptr;
|
m_xdgShellPopup = nullptr;
|
||||||
|
|
|
@ -300,6 +300,8 @@ private:
|
||||||
|
|
||||||
bool m_compositingSetup = false;
|
bool m_compositingSetup = false;
|
||||||
bool m_isInitialized = false;
|
bool m_isInitialized = false;
|
||||||
|
|
||||||
|
friend class Workspace;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -556,6 +556,19 @@ Workspace::~Workspace()
|
||||||
desktops.removeAll(c);
|
desktops.removeAll(c);
|
||||||
}
|
}
|
||||||
Client::cleanupX11();
|
Client::cleanupX11();
|
||||||
|
|
||||||
|
if (waylandServer()) {
|
||||||
|
const QList<ShellClient *> shellClients = waylandServer()->clients();
|
||||||
|
for (ShellClient *shellClient : shellClients) {
|
||||||
|
shellClient->destroyClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<ShellClient *> internalClients = waylandServer()->internalClients();
|
||||||
|
for (ShellClient *internalClient : internalClients) {
|
||||||
|
internalClient->destroyClient();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (UnmanagedList::iterator it = unmanaged.begin(), end = unmanaged.end(); it != end; ++it)
|
for (UnmanagedList::iterator it = unmanaged.begin(), end = unmanaged.end(); it != end; ++it)
|
||||||
(*it)->release(ReleaseReason::KWinShutsDown);
|
(*it)->release(ReleaseReason::KWinShutsDown);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue