QPA: Fix event dispatcher dependent operations in platform integration
999e5162ec3e86c9cb84c3ec95dfd0ba4b21277f breaks QPlatformIntegration implementations that perform tasks in their constructor that rely on the event dispatcher. For example creating a QSocketNotifier is not possible anymore since the event dispatcher is created later on. This is fixed by introducing an additional virtual in QPlatformIntegration that gets called after createEventDispatcher(). Two broken platform plugins have been identified so far: eglfs is creating socket notifiers to read events from input devices and xcb's input context plugins may use dbus. Both are updated accordingly. Task-number: QTBUG-33768 Change-Id: I5badb623958a52ab5314ff93dd7d60061f5df70a Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
This commit is contained in:
parent
8a383c585f
commit
cf092abdfc
@ -479,6 +479,10 @@ void QCoreApplicationPrivate::createEventDispatcher()
|
||||
#endif
|
||||
}
|
||||
|
||||
void QCoreApplicationPrivate::eventDispatcherReady()
|
||||
{
|
||||
}
|
||||
|
||||
QThread *QCoreApplicationPrivate::theMainThread = 0;
|
||||
QThread *QCoreApplicationPrivate::mainThread()
|
||||
{
|
||||
@ -714,6 +718,7 @@ void QCoreApplication::init()
|
||||
}
|
||||
|
||||
d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher;
|
||||
d->eventDispatcherReady();
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_LIBRARY
|
||||
|
@ -99,6 +99,7 @@ public:
|
||||
bool notify_helper(QObject *, QEvent *);
|
||||
|
||||
virtual void createEventDispatcher();
|
||||
virtual void eventDispatcherReady();
|
||||
static void removePostedEvent(QEvent *);
|
||||
#ifdef Q_OS_WIN
|
||||
static void removePostedTimerEvent(QObject *object, int timerId);
|
||||
|
@ -1048,6 +1048,14 @@ void QGuiApplicationPrivate::createEventDispatcher()
|
||||
eventDispatcher = platform_integration->createEventDispatcher();
|
||||
}
|
||||
|
||||
void QGuiApplicationPrivate::eventDispatcherReady()
|
||||
{
|
||||
if (platform_integration == 0)
|
||||
createPlatformIntegration();
|
||||
|
||||
platform_integration->initialize();
|
||||
}
|
||||
|
||||
#if defined(QT_DEBUG) && defined(Q_OS_LINUX)
|
||||
// Find out if our parent process is gdb by looking at the 'exe' symlink under /proc.
|
||||
static bool runningUnderDebugger()
|
||||
|
@ -84,6 +84,7 @@ public:
|
||||
|
||||
void createPlatformIntegration();
|
||||
void createEventDispatcher() Q_DECL_OVERRIDE;
|
||||
void eventDispatcherReady() Q_DECL_OVERRIDE;
|
||||
|
||||
virtual void notifyLayoutDirectionChange();
|
||||
virtual void notifyActiveWindowChange(QWindow *previous);
|
||||
|
@ -290,6 +290,18 @@ QPaintEngine *QPlatformIntegration::createImagePaintEngine(QPaintDevice *paintDe
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Performs initialization steps that depend on having an event dispatcher
|
||||
available. Called after the event dispatcher has been created.
|
||||
|
||||
Tasks that require an event dispatcher, for example creating socket notifiers, cannot be
|
||||
performed in the constructor. Instead, they should be performed here. The default
|
||||
implementation does nothing.
|
||||
*/
|
||||
void QPlatformIntegration::initialize()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the platforms input context.
|
||||
|
||||
|
@ -112,6 +112,7 @@ public:
|
||||
|
||||
// Event dispatcher:
|
||||
virtual QAbstractEventDispatcher *createEventDispatcher() const = 0;
|
||||
virtual void initialize();
|
||||
|
||||
//Deeper window system integrations
|
||||
virtual QPlatformFontDatabase *fontDatabase() const;
|
||||
|
@ -80,13 +80,8 @@ static void *eglContextForContext(QOpenGLContext *context);
|
||||
QEglFSIntegration::QEglFSIntegration()
|
||||
: mFontDb(new QGenericUnixFontDatabase)
|
||||
, mServices(new QGenericUnixServices)
|
||||
, mInputContext(0)
|
||||
{
|
||||
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
|
||||
new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
|
||||
new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
|
||||
new QEvdevTouchScreenHandlerThread(QString() /* spec */, this);
|
||||
#endif
|
||||
|
||||
QEglFSHooks::hooks()->platformInit();
|
||||
|
||||
EGLint major, minor;
|
||||
@ -109,8 +104,6 @@ QEglFSIntegration::QEglFSIntegration()
|
||||
|
||||
mScreen = new QEglFSScreen(mDisplay);
|
||||
screenAdded(mScreen);
|
||||
|
||||
mInputContext = QPlatformInputContextFactory::create();
|
||||
}
|
||||
|
||||
QEglFSIntegration::~QEglFSIntegration()
|
||||
@ -170,6 +163,12 @@ QAbstractEventDispatcher *QEglFSIntegration::createEventDispatcher() const
|
||||
return createUnixEventDispatcher();
|
||||
}
|
||||
|
||||
void QEglFSIntegration::initialize()
|
||||
{
|
||||
mInputContext = QPlatformInputContextFactory::create();
|
||||
createInputHandlers();
|
||||
}
|
||||
|
||||
QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
|
||||
{
|
||||
switch (hint)
|
||||
@ -309,4 +308,13 @@ EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceForm
|
||||
return chooser.chooseConfig();
|
||||
}
|
||||
|
||||
void QEglFSIntegration::createInputHandlers()
|
||||
{
|
||||
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
|
||||
new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
|
||||
new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
|
||||
new QEvdevTouchScreenHandlerThread(QString() /* spec */, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -68,6 +68,7 @@ public:
|
||||
QPlatformServices *services() const;
|
||||
|
||||
QAbstractEventDispatcher *createEventDispatcher() const;
|
||||
void initialize();
|
||||
|
||||
QVariant styleHint(QPlatformIntegration::StyleHint hint) const;
|
||||
|
||||
@ -86,6 +87,8 @@ public:
|
||||
QPlatformInputContext *inputContext() const { return mInputContext; }
|
||||
|
||||
private:
|
||||
void createInputHandlers();
|
||||
|
||||
EGLDisplay mDisplay;
|
||||
QScopedPointer<QPlatformFontDatabase> mFontDb;
|
||||
QScopedPointer<QPlatformServices> mServices;
|
||||
|
@ -172,7 +172,6 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char
|
||||
}
|
||||
|
||||
m_fontDatabase.reset(new QGenericUnixFontDatabase());
|
||||
m_inputContext.reset(QPlatformInputContextFactory::create());
|
||||
}
|
||||
|
||||
QXcbIntegration::~QXcbIntegration()
|
||||
@ -292,6 +291,13 @@ QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const
|
||||
return createUnixEventDispatcher();
|
||||
}
|
||||
|
||||
void QXcbIntegration::initialize()
|
||||
{
|
||||
// Perform everything that may potentially need the event dispatcher (timers, socket
|
||||
// notifiers) here instead of the constructor.
|
||||
m_inputContext.reset(QPlatformInputContextFactory::create());
|
||||
}
|
||||
|
||||
void QXcbIntegration::moveToScreen(QWindow *window, int screen)
|
||||
{
|
||||
Q_UNUSED(window);
|
||||
|
@ -68,6 +68,7 @@ public:
|
||||
|
||||
bool hasCapability(Capability cap) const;
|
||||
QAbstractEventDispatcher *createEventDispatcher() const;
|
||||
void initialize();
|
||||
|
||||
void moveToScreen(QWindow *window, int screen);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user