commit df39295f23c7d9ead8481a95b9c78caaff1e8bc8 Author: Sandro Mani Date: Mon Feb 16 10:22:14 2015 +0100 Have XCB/Windows platform integration classes keep their own instance pointer Through the chain of code called by QPlatformIntegrationFactory::create, there are cases where QGuiApplicationPrivate::platform_integration is accessed (typically through QGuiApplicationPrivate::platformIntegration()) before the call to QPlatformIntegrationFactory::create has returned. Change-Id: I7805b72be5b56aed5cb8ce30cb908743c9b1f91b Task-number: QTBUG-44388 Reviewed-by: Shawn Rutledge Reviewed-by: Friedemann Kleint diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 58d6758..d06f605 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -235,9 +235,12 @@ QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() delete m_fontDatabase; } +QWindowsIntegration *QWindowsIntegration::m_instance = Q_NULLPTR; + QWindowsIntegration::QWindowsIntegration(const QStringList ¶mList) : d(new QWindowsIntegrationPrivate(paramList)) { + m_instance = this; #ifndef QT_NO_CLIPBOARD d->m_clipboard.registerViewer(); #endif @@ -246,6 +249,7 @@ QWindowsIntegration::QWindowsIntegration(const QStringList ¶mList) : QWindowsIntegration::~QWindowsIntegration() { + m_instance = Q_NULLPTR; } void QWindowsIntegration::initialize() @@ -540,11 +544,6 @@ QPlatformAccessibility *QWindowsIntegration::accessibility() const } #endif -QWindowsIntegration *QWindowsIntegration::instance() -{ - return static_cast(QGuiApplicationPrivate::platformIntegration()); -} - unsigned QWindowsIntegration::options() const { return d->m_options; diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index 7fb37bc..ff26342 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -91,7 +91,7 @@ public: Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE; QList possibleKeys(const QKeyEvent *e) const Q_DECL_OVERRIDE; - static QWindowsIntegration *instance(); + static QWindowsIntegration *instance() { return m_instance; } inline void emitScreenAdded(QPlatformScreen *s) { screenAdded(s); } inline void emitDestroyScreen(QPlatformScreen *s) { destroyScreen(s); } @@ -104,6 +104,8 @@ public: private: QScopedPointer d; + + static QWindowsIntegration *m_instance; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index ae59de5..0091736 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -279,7 +279,7 @@ void QXcbConnection::updateScreens() ++xcbScreenNumber; } // for each xcb screen - QXcbIntegration *integration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration *integration = QXcbIntegration::instance(); // 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) { @@ -432,7 +432,7 @@ QXcbConnection::~QXcbConnection() delete m_reader; - QXcbIntegration *integration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration *integration = QXcbIntegration::instance(); // Delete screens in reverse order to avoid crash in case of multiple screens while (!m_screens.isEmpty()) integration->destroyScreen(m_screens.takeLast()); diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index f0c4a7f..050a9be 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -118,11 +118,15 @@ static bool runningUnderDebugger() #endif } +QXcbIntegration *QXcbIntegration::m_instance = Q_NULLPTR; + QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char **argv) : m_services(new QGenericUnixServices) , m_instanceName(0) , m_canGrab(true) { + m_instance = this; + qRegisterMetaType(); #ifdef XCB_USE_XLIB XInitThreads(); @@ -187,6 +191,7 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char QXcbIntegration::~QXcbIntegration() { qDeleteAll(m_connections); + m_instance = Q_NULLPTR; } QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index db6ad54..ffe49e7 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -99,6 +99,9 @@ public: #endif void sync(); + + static QXcbIntegration *instance() { return m_instance; } + private: QList m_connections; @@ -118,6 +121,8 @@ private: mutable QByteArray m_wmClass; const char *m_instanceName; bool m_canGrab; + + static QXcbIntegration *m_instance; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 31dedd4..c9aaada 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -359,7 +359,7 @@ void *QXcbNativeInterface::getTimestamp(const QXcbScreen *screen) void *QXcbNativeInterface::startupId() { - QXcbIntegration* integration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration* integration = QXcbIntegration::instance(); QXcbConnection *defaultConnection = integration->defaultConnection(); if (defaultConnection) return reinterpret_cast(const_cast(defaultConnection->startupId().constData())); @@ -368,7 +368,7 @@ void *QXcbNativeInterface::startupId() void *QXcbNativeInterface::x11Screen() { - QXcbIntegration *integration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration *integration = QXcbIntegration::instance(); QXcbConnection *defaultConnection = integration->defaultConnection(); if (defaultConnection) return reinterpret_cast(defaultConnection->primaryScreenNumber()); @@ -377,7 +377,7 @@ void *QXcbNativeInterface::x11Screen() void *QXcbNativeInterface::rootWindow() { - QXcbIntegration *integration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration *integration = QXcbIntegration::instance(); QXcbConnection *defaultConnection = integration->defaultConnection(); if (defaultConnection) return reinterpret_cast(defaultConnection->rootWindow()); @@ -397,7 +397,7 @@ void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time) void QXcbNativeInterface::setStartupId(const char *data) { QByteArray startupId(data); - QXcbIntegration *integration = static_cast(QGuiApplicationPrivate::platformIntegration()); + QXcbIntegration *integration = QXcbIntegration::instance(); QXcbConnection *defaultConnection = integration->defaultConnection(); if (defaultConnection) defaultConnection->setStartupId(startupId); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 0094278..7e85600 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -489,7 +489,7 @@ void QXcbWindow::create() m_syncValue.hi = 0; m_syncValue.lo = 0; - const QByteArray wmClass = static_cast(QGuiApplicationPrivate::platformIntegration())->wmClass(); + const QByteArray wmClass = QXcbIntegration::instance()->wmClass(); if (!wmClass.isEmpty()) { Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::WM_CLASS),