From 457ae8f19093c282a0f54d4e3b29e68c2a2477dc Mon Sep 17 00:00:00 2001
|
From: Jeffy Chen <jeffy.chen@rock-chips.com>
|
Date: Sat, 9 May 2020 17:05:32 +0800
|
Subject: [PATCH 08/15] qwaylanddisplay: Wakeup main event dispatcher when
|
events pending
|
|
The socket might not be able to generate poll events to wakeup the main
|
event dispatcher when there're multiple wayland clients(e.g. waylandsink)
|
reading it.
|
|
So let's create a extra thread to check the wayland display event queue
|
for pending events and wakeup the main event dispatcher.
|
|
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
|
---
|
src/client/qwaylanddisplay.cpp | 50 +++++++++++++++++++++++++++++++++-
|
src/client/qwaylanddisplay_p.h | 2 ++
|
2 files changed, 51 insertions(+), 1 deletion(-)
|
|
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
|
index ba4ce93..d07477a 100644
|
--- a/src/client/qwaylanddisplay.cpp
|
+++ b/src/client/qwaylanddisplay.cpp
|
@@ -83,6 +83,8 @@
|
|
#include <QtCore/QDebug>
|
|
+#include <QThread>
|
+
|
#include <errno.h>
|
#include <poll.h>
|
|
@@ -92,6 +94,48 @@ namespace QtWaylandClient {
|
|
Q_LOGGING_CATEGORY(lcQpaWayland, "qt.qpa.wayland"); // for general (uncategorized) Wayland platform logging
|
|
+class QWaylandDisplayThread : public QThread
|
+{
|
+public:
|
+ QWaylandDisplayThread(struct wl_display *display);
|
+ ~QWaylandDisplayThread();
|
+
|
+protected:
|
+ virtual void run() override;
|
+
|
+private:
|
+ struct wl_display *mDisplay = nullptr;
|
+ bool quit;
|
+};
|
+
|
+QWaylandDisplayThread::QWaylandDisplayThread(struct wl_display *display)
|
+ : mDisplay(display), quit(false)
|
+{
|
+ start();
|
+}
|
+
|
+QWaylandDisplayThread::~QWaylandDisplayThread()
|
+{
|
+ quit = true;
|
+ wait();
|
+}
|
+
|
+void QWaylandDisplayThread::run()
|
+{
|
+ while (!quit) {
|
+ if (wl_display_prepare_read(mDisplay) != 0) {
|
+ // wakeup dispatcher for pending events
|
+ if (auto *dispatcher = QCoreApplication::eventDispatcher())
|
+ dispatcher->wakeUp();
|
+ } else {
|
+ wl_display_flush(mDisplay);
|
+ wl_display_cancel_read(mDisplay);
|
+ }
|
+
|
+ usleep(100000);
|
+ }
|
+}
|
+
|
struct wl_surface *QWaylandDisplay::createSurface(void *handle)
|
{
|
struct wl_surface *surface = mCompositor.create_surface();
|
@@ -160,6 +204,8 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
|
qCWarning(lcQpaWayland, "failed to create xkb context");
|
#endif
|
|
+ mThread = new QWaylandDisplayThread(mDisplay);
|
+
|
forceRoundTrip();
|
|
if (!mWaitingScreens.isEmpty()) {
|
@@ -186,8 +232,10 @@ QWaylandDisplay::~QWaylandDisplay(void)
|
#if QT_CONFIG(cursor)
|
qDeleteAll(mCursorThemes);
|
#endif
|
- if (mDisplay)
|
+ if (mDisplay) {
|
+ delete mThread;
|
wl_display_disconnect(mDisplay);
|
+ }
|
}
|
|
void QWaylandDisplay::ensureScreen()
|
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
|
index 188e913..42b6c09 100644
|
--- a/src/client/qwaylanddisplay_p.h
|
+++ b/src/client/qwaylanddisplay_p.h
|
@@ -109,6 +109,7 @@ class QWaylandSurface;
|
class QWaylandShellIntegration;
|
class QWaylandCursor;
|
class QWaylandCursorTheme;
|
+class QWaylandDisplayThread;
|
|
typedef void (*RegistryListener)(void *data,
|
struct wl_registry *registry,
|
@@ -280,6 +281,7 @@ private:
|
struct wl_callback *mSyncCallback = nullptr;
|
static const wl_callback_listener syncCallbackListener;
|
QReadWriteLock m_frameQueueLock;
|
+ QWaylandDisplayThread *mThread = nullptr;
|
|
bool mClientSideInputContextRequested = !QPlatformInputContextFactory::requested().isNull();
|
bool mUsingInputContextFromCompositor = false;
|
--
|
2.20.1
|