From 74f98d4c12b398e22953e557bb115723eb7c2d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 16 Jun 2016 13:30:32 +0200 Subject: [PATCH] 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 --- shell_client.cpp | 13 ++++++++----- shell_client.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/shell_client.cpp b/shell_client.cpp index 7128cebd43..16d89a6953 100644 --- a/shell_client.cpp +++ b/shell_client.cpp @@ -101,8 +101,14 @@ void ShellClient::init() connect(s, &SurfaceInterface::unmapped, this, &ShellClient::unmap); connect(s, &SurfaceInterface::destroyed, this, &ShellClient::destroyClient); if (m_shellSurface) { + m_caption = m_shellSurface->title(); 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::maximizedChanged, this, @@ -450,10 +456,7 @@ QString ShellClient::caption(bool full, bool stripped) const { Q_UNUSED(full) Q_UNUSED(stripped) - if (m_shellSurface) { - return m_shellSurface->title(); - } - return QString(); + return m_caption; } void ShellClient::closeWindow() diff --git a/shell_client.h b/shell_client.h index a783d725a8..117bb2e2b6 100644 --- a/shell_client.h +++ b/shell_client.h @@ -195,6 +195,7 @@ private: friend class RequestGeometryBlocker; int m_requestGeometryBlockCounter = 0; QRect m_blockedRequestGeometry; + QString m_caption; }; }