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 <shawn.rutledge@digia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
This commit is contained in:
Sandro Mani 2015-02-16 10:22:14 +01:00 committed by Shawn Rutledge
parent d568797226
commit df39295f23
8 changed files with 26 additions and 15 deletions

View File

@ -235,9 +235,12 @@ QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate()
delete m_fontDatabase;
}
QWindowsIntegration *QWindowsIntegration::m_instance = Q_NULLPTR;
QWindowsIntegration::QWindowsIntegration(const QStringList &paramList) :
d(new QWindowsIntegrationPrivate(paramList))
{
m_instance = this;
#ifndef QT_NO_CLIPBOARD
d->m_clipboard.registerViewer();
#endif
@ -246,6 +249,7 @@ QWindowsIntegration::QWindowsIntegration(const QStringList &paramList) :
QWindowsIntegration::~QWindowsIntegration()
{
m_instance = Q_NULLPTR;
}
void QWindowsIntegration::initialize()
@ -540,11 +544,6 @@ QPlatformAccessibility *QWindowsIntegration::accessibility() const
}
#endif
QWindowsIntegration *QWindowsIntegration::instance()
{
return static_cast<QWindowsIntegration *>(QGuiApplicationPrivate::platformIntegration());
}
unsigned QWindowsIntegration::options() const
{
return d->m_options;

View File

@ -91,7 +91,7 @@ public:
Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE;
QList<int> 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<QWindowsIntegrationPrivate> d;
static QWindowsIntegration *m_instance;
};
QT_END_NAMESPACE

View File

@ -100,7 +100,7 @@ QPlatformNativeInterface::NativeResourceForWindowFunction QXcbEglNativeInterface
void *QXcbEglNativeInterfaceHandler::eglDisplay()
{
QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
QXcbIntegration *integration = QXcbIntegration::instance();
QXcbEglIntegration *eglIntegration = static_cast<QXcbEglIntegration *>(integration->defaultConnection()->glIntegration());
return eglIntegration->eglDisplay();
}

View File

@ -240,7 +240,7 @@ void QXcbConnection::updateScreens()
++xcbScreenNumber;
} // for each xcb screen
QXcbIntegration *integration = static_cast<QXcbIntegration *>(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) {
@ -404,7 +404,7 @@ QXcbConnection::~QXcbConnection()
delete m_reader;
QXcbIntegration *integration = static_cast<QXcbIntegration *>(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());

View File

@ -110,11 +110,15 @@ static bool runningUnderDebugger()
#endif
}
QXcbIntegration *QXcbIntegration::m_instance = Q_NULLPTR;
QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char **argv)
: m_services(new QGenericUnixServices)
, m_instanceName(0)
, m_canGrab(true)
{
m_instance = this;
qRegisterMetaType<QXcbWindow*>();
#ifdef XCB_USE_XLIB
XInitThreads();
@ -179,6 +183,7 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
QXcbIntegration::~QXcbIntegration()
{
qDeleteAll(m_connections);
m_instance = Q_NULLPTR;
}
QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const

View File

@ -101,6 +101,9 @@ public:
#endif
void sync() Q_DECL_OVERRIDE;
static QXcbIntegration *instance() { return m_instance; }
private:
QList<QXcbConnection *> m_connections;
@ -120,6 +123,8 @@ private:
mutable QByteArray m_wmClass;
const char *m_instanceName;
bool m_canGrab;
static QXcbIntegration *m_instance;
};
QT_END_NAMESPACE

View File

@ -401,7 +401,7 @@ void *QXcbNativeInterface::getTimestamp(const QXcbScreen *screen)
void *QXcbNativeInterface::startupId()
{
QXcbIntegration* integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
QXcbIntegration* integration = QXcbIntegration::instance();
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
return reinterpret_cast<void *>(const_cast<char *>(defaultConnection->startupId().constData()));
@ -410,7 +410,7 @@ void *QXcbNativeInterface::startupId()
void *QXcbNativeInterface::x11Screen()
{
QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
QXcbIntegration *integration = QXcbIntegration::instance();
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
return reinterpret_cast<void *>(defaultConnection->primaryScreenNumber());
@ -419,7 +419,7 @@ void *QXcbNativeInterface::x11Screen()
void *QXcbNativeInterface::rootWindow()
{
QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
QXcbIntegration *integration = QXcbIntegration::instance();
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
return reinterpret_cast<void *>(defaultConnection->rootWindow());
@ -429,7 +429,7 @@ void *QXcbNativeInterface::rootWindow()
void *QXcbNativeInterface::display()
{
#ifdef XCB_USE_XLIB
QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
QXcbIntegration *integration = QXcbIntegration::instance();
QXcbConnection *defaultConnection = integration->defaultConnection();
return defaultConnection->xlib_display();
#else
@ -450,7 +450,7 @@ void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time)
void QXcbNativeInterface::setStartupId(const char *data)
{
QByteArray startupId(data);
QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
QXcbIntegration *integration = QXcbIntegration::instance();
QXcbConnection *defaultConnection = integration->defaultConnection();
if (defaultConnection)
defaultConnection->setStartupId(startupId);

View File

@ -461,7 +461,7 @@ void QXcbWindow::create()
m_syncValue.hi = 0;
m_syncValue.lo = 0;
const QByteArray wmClass = static_cast<QXcbIntegration *>(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),