Cache the caption of ShellSurface in ShellClient

Summary:
If the ShellSurface gets destroyed while a decoration repaint is pending,
it is possible that on tear down the decoration calls into
ShellClient::caption. This used to call into ShellSurfaceInterface::title
which accesses a d-ptr which is already destroyed at that point.

This change caches the caption instead of delegating to ShellSurface,
just like almost everything else caches. Thus the tear down cannot access
invalid memory.

Once we can depend on Frameworks 5.24, we should also make sure to
connect to the new Resource::unbound signal to be able to handle tear
down prior to the object being completely deleted.

Test Plan:
Unfortunately no test case as this depends on phase-of-moon
aligning of destruction of the interfaces

Reviewers: #kwin, #plasma_on_wayland

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D1913
This commit is contained in:
Martin Gräßlin 2016-06-16 13:30:32 +02:00
parent 0053b25903
commit 74f98d4c12
2 changed files with 9 additions and 5 deletions

View file

@ -101,8 +101,14 @@ void ShellClient::init()
connect(s, &SurfaceInterface::unmapped, this, &ShellClient::unmap); connect(s, &SurfaceInterface::unmapped, this, &ShellClient::unmap);
connect(s, &SurfaceInterface::destroyed, this, &ShellClient::destroyClient); connect(s, &SurfaceInterface::destroyed, this, &ShellClient::destroyClient);
if (m_shellSurface) { if (m_shellSurface) {
m_caption = m_shellSurface->title();
connect(m_shellSurface, &ShellSurfaceInterface::destroyed, this, &ShellClient::destroyClient); connect(m_shellSurface, &ShellSurfaceInterface::destroyed, this, &ShellClient::destroyClient);
connect(m_shellSurface, &ShellSurfaceInterface::titleChanged, this, &ShellClient::captionChanged); connect(m_shellSurface, &ShellSurfaceInterface::titleChanged, this,
[this] {
m_caption = m_shellSurface->title();
emit captionChanged();
}
);
connect(m_shellSurface, &ShellSurfaceInterface::fullscreenChanged, this, &ShellClient::clientFullScreenChanged); connect(m_shellSurface, &ShellSurfaceInterface::fullscreenChanged, this, &ShellClient::clientFullScreenChanged);
connect(m_shellSurface, &ShellSurfaceInterface::maximizedChanged, this, connect(m_shellSurface, &ShellSurfaceInterface::maximizedChanged, this,
@ -450,10 +456,7 @@ QString ShellClient::caption(bool full, bool stripped) const
{ {
Q_UNUSED(full) Q_UNUSED(full)
Q_UNUSED(stripped) Q_UNUSED(stripped)
if (m_shellSurface) { return m_caption;
return m_shellSurface->title();
}
return QString();
} }
void ShellClient::closeWindow() void ShellClient::closeWindow()

View file

@ -195,6 +195,7 @@ private:
friend class RequestGeometryBlocker; friend class RequestGeometryBlocker;
int m_requestGeometryBlockCounter = 0; int m_requestGeometryBlockCounter = 0;
QRect m_blockedRequestGeometry; QRect m_blockedRequestGeometry;
QString m_caption;
}; };
} }