From 9b4fbe85d2e00c625c3d4abd975faf555000f685 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Sun, 31 Aug 2014 16:16:53 +0300 Subject: Add a function for QPA plugins to explicitly destroy QScreens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously QPlatformScreen was automatically deleting its QScreen in ~QPlatformScreen(). That means that we cannot use QScreen's methods when the screen is being removed, because doing so would call virtual methods of QPlatformScreen. By that point the QPlatformScreen subclass object does not exist anymore, and we call the default implementation instead of the subclassed one, or get a crash for the pure virtual methods. This happens for example when removing a screen which contains a QWindow with some QML item using QQuickScreenAttached. This patch adds a QPlatformIntegration::destroyScreen() function, which deletes the QScreen and later the QPlatformScreen. ~QPlatformScreen will still delete the QScreen if it was not deleted with destroyScreen(), so code not ported to the new approach will continue to work as before, with only a warning added. Task-number: QTBUG-41141 Change-Id: Ie4a03dee08ceb4c3e94a81875411f6f723273fe1 Reviewed-by: Jørgen Lind Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms/xcb') diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 2e429939ba..08b414e82e 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -240,11 +240,12 @@ void QXcbConnection::updateScreens() ++xcbScreenNumber; } // for each xcb screen + QXcbIntegration *integration = static_cast(QGuiApplicationPrivate::platformIntegration()); // Now activeScreens is the complete set of screens which are active at this time. // Delete any existing screens which are not in activeScreens for (int i = m_screens.count() - 1; i >= 0; --i) { if (!activeScreens.contains(m_screens[i])) { - delete m_screens[i]; + integration->destroyScreen(m_screens.at(i)); m_screens.removeAt(i); } } @@ -261,7 +262,7 @@ void QXcbConnection::updateScreens() // Now that they are in the right order, emit the added signals for new screens only foreach (QXcbScreen* screen, m_screens) if (newScreens.contains(screen)) - ((QXcbIntegration*)QGuiApplicationPrivate::platformIntegration())->screenAdded(screen); + integration->screenAdded(screen); } QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName) @@ -400,9 +401,10 @@ QXcbConnection::~QXcbConnection() delete m_reader; + QXcbIntegration *integration = static_cast(QGuiApplicationPrivate::platformIntegration()); // Delete screens in reverse order to avoid crash in case of multiple screens while (!m_screens.isEmpty()) - delete m_screens.takeLast(); + integration->destroyScreen(m_screens.takeLast()); #ifdef XCB_USE_XLIB XCloseDisplay((Display *)m_xlib_display); -- cgit v1.2.3