HYL_OK3568_LINUX/buildroot/package/qt5/qt5wayland/0008-qwaylanddisplay-Wakeup-main-event-dispatcher-when-ev.patch

126 lines
3.6 KiB
Diff
Raw Normal View History

2025-05-10 21:49:39 +08:00
From c8853fb402c4ea6cc978d8cf1c50232f5edb81f4 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/17] 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 86045a3..dc61d23 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -83,6 +83,8 @@
#include <QtCore/QDebug>
+#include <QThread>
+
#include <errno.h>
#include <tuple> // for std::tie
@@ -284,6 +286,48 @@ private:
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();
@@ -351,6 +395,8 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
if (!mXkbContext)
qCWarning(lcQpaWayland, "failed to create xkb context");
#endif
+
+ mThread = new QWaylandDisplayThread(mDisplay);
}
QWaylandDisplay::~QWaylandDisplay(void)
@@ -377,8 +423,10 @@ QWaylandDisplay::~QWaylandDisplay(void)
#if QT_CONFIG(cursor)
qDeleteAll(mCursorThemes);
#endif
- if (mDisplay)
+ if (mDisplay) {
+ delete mThread;
wl_display_disconnect(mDisplay);
+ }
}
// Steps which is called just after constructor. This separates registry_global() out of the constructor
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
index 42bc661..fb632b3 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;
class EventThread;
typedef void (*RegistryListener)(void *data,
@@ -276,6 +277,7 @@ private:
QList<QWaylandWindow *> mActiveWindows;
struct wl_callback *mSyncCallback = nullptr;
static const wl_callback_listener syncCallbackListener;
+ QWaylandDisplayThread *mThread = nullptr;
bool mClientSideInputContextRequested = !QPlatformInputContextFactory::requested().isNull();
--
2.20.1