1*4882a593SmuzhiyunFrom c8853fb402c4ea6cc978d8cf1c50232f5edb81f4 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com>
3*4882a593SmuzhiyunDate: Sat, 9 May 2020 17:05:32 +0800
4*4882a593SmuzhiyunSubject: [PATCH 08/17] qwaylanddisplay: Wakeup main event dispatcher when
5*4882a593Smuzhiyun events pending
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunThe socket might not be able to generate poll events to wakeup the main
8*4882a593Smuzhiyunevent dispatcher when there're multiple wayland clients(e.g. waylandsink)
9*4882a593Smuzhiyunreading it.
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunSo let's create a extra thread to check the wayland display event queue
12*4882a593Smuzhiyunfor pending events and wakeup the main event dispatcher.
13*4882a593Smuzhiyun
14*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
15*4882a593Smuzhiyun---
16*4882a593Smuzhiyun src/client/qwaylanddisplay.cpp | 50 +++++++++++++++++++++++++++++++++-
17*4882a593Smuzhiyun src/client/qwaylanddisplay_p.h |  2 ++
18*4882a593Smuzhiyun 2 files changed, 51 insertions(+), 1 deletion(-)
19*4882a593Smuzhiyun
20*4882a593Smuzhiyundiff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
21*4882a593Smuzhiyunindex 86045a3..dc61d23 100644
22*4882a593Smuzhiyun--- a/src/client/qwaylanddisplay.cpp
23*4882a593Smuzhiyun+++ b/src/client/qwaylanddisplay.cpp
24*4882a593Smuzhiyun@@ -83,6 +83,8 @@
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #include <QtCore/QDebug>
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun+#include <QThread>
29*4882a593Smuzhiyun+
30*4882a593Smuzhiyun #include <errno.h>
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #include <tuple> // for std::tie
33*4882a593Smuzhiyun@@ -284,6 +286,48 @@ private:
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun Q_LOGGING_CATEGORY(lcQpaWayland, "qt.qpa.wayland"); // for general (uncategorized) Wayland platform logging
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun+class QWaylandDisplayThread : public QThread
38*4882a593Smuzhiyun+{
39*4882a593Smuzhiyun+public:
40*4882a593Smuzhiyun+    QWaylandDisplayThread(struct wl_display *display);
41*4882a593Smuzhiyun+    ~QWaylandDisplayThread();
42*4882a593Smuzhiyun+
43*4882a593Smuzhiyun+protected:
44*4882a593Smuzhiyun+    virtual void run() override;
45*4882a593Smuzhiyun+
46*4882a593Smuzhiyun+private:
47*4882a593Smuzhiyun+    struct wl_display *mDisplay = nullptr;
48*4882a593Smuzhiyun+    bool quit;
49*4882a593Smuzhiyun+};
50*4882a593Smuzhiyun+
51*4882a593Smuzhiyun+QWaylandDisplayThread::QWaylandDisplayThread(struct wl_display *display)
52*4882a593Smuzhiyun+    : mDisplay(display), quit(false)
53*4882a593Smuzhiyun+{
54*4882a593Smuzhiyun+    start();
55*4882a593Smuzhiyun+}
56*4882a593Smuzhiyun+
57*4882a593Smuzhiyun+QWaylandDisplayThread::~QWaylandDisplayThread()
58*4882a593Smuzhiyun+{
59*4882a593Smuzhiyun+    quit = true;
60*4882a593Smuzhiyun+    wait();
61*4882a593Smuzhiyun+}
62*4882a593Smuzhiyun+
63*4882a593Smuzhiyun+void QWaylandDisplayThread::run()
64*4882a593Smuzhiyun+{
65*4882a593Smuzhiyun+    while (!quit) {
66*4882a593Smuzhiyun+        if (wl_display_prepare_read(mDisplay) != 0) {
67*4882a593Smuzhiyun+            // wakeup dispatcher for pending events
68*4882a593Smuzhiyun+            if (auto *dispatcher = QCoreApplication::eventDispatcher())
69*4882a593Smuzhiyun+                dispatcher->wakeUp();
70*4882a593Smuzhiyun+        } else {
71*4882a593Smuzhiyun+            wl_display_flush(mDisplay);
72*4882a593Smuzhiyun+            wl_display_cancel_read(mDisplay);
73*4882a593Smuzhiyun+        }
74*4882a593Smuzhiyun+
75*4882a593Smuzhiyun+        usleep(100000);
76*4882a593Smuzhiyun+    }
77*4882a593Smuzhiyun+}
78*4882a593Smuzhiyun+
79*4882a593Smuzhiyun struct wl_surface *QWaylandDisplay::createSurface(void *handle)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun     struct wl_surface *surface = mCompositor.create_surface();
82*4882a593Smuzhiyun@@ -351,6 +395,8 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
83*4882a593Smuzhiyun     if (!mXkbContext)
84*4882a593Smuzhiyun         qCWarning(lcQpaWayland, "failed to create xkb context");
85*4882a593Smuzhiyun #endif
86*4882a593Smuzhiyun+
87*4882a593Smuzhiyun+    mThread = new QWaylandDisplayThread(mDisplay);
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun QWaylandDisplay::~QWaylandDisplay(void)
91*4882a593Smuzhiyun@@ -377,8 +423,10 @@ QWaylandDisplay::~QWaylandDisplay(void)
92*4882a593Smuzhiyun #if QT_CONFIG(cursor)
93*4882a593Smuzhiyun     qDeleteAll(mCursorThemes);
94*4882a593Smuzhiyun #endif
95*4882a593Smuzhiyun-    if (mDisplay)
96*4882a593Smuzhiyun+    if (mDisplay) {
97*4882a593Smuzhiyun+        delete mThread;
98*4882a593Smuzhiyun         wl_display_disconnect(mDisplay);
99*4882a593Smuzhiyun+    }
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun // Steps which is called just after constructor. This separates registry_global() out of the constructor
103*4882a593Smuzhiyundiff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
104*4882a593Smuzhiyunindex 42bc661..fb632b3 100644
105*4882a593Smuzhiyun--- a/src/client/qwaylanddisplay_p.h
106*4882a593Smuzhiyun+++ b/src/client/qwaylanddisplay_p.h
107*4882a593Smuzhiyun@@ -109,6 +109,7 @@ class QWaylandSurface;
108*4882a593Smuzhiyun class QWaylandShellIntegration;
109*4882a593Smuzhiyun class QWaylandCursor;
110*4882a593Smuzhiyun class QWaylandCursorTheme;
111*4882a593Smuzhiyun+class QWaylandDisplayThread;
112*4882a593Smuzhiyun class EventThread;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun typedef void (*RegistryListener)(void *data,
115*4882a593Smuzhiyun@@ -276,6 +277,7 @@ private:
116*4882a593Smuzhiyun     QList<QWaylandWindow *> mActiveWindows;
117*4882a593Smuzhiyun     struct wl_callback *mSyncCallback = nullptr;
118*4882a593Smuzhiyun     static const wl_callback_listener syncCallbackListener;
119*4882a593Smuzhiyun+    QWaylandDisplayThread *mThread = nullptr;
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun     bool mClientSideInputContextRequested = !QPlatformInputContextFactory::requested().isNull();
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun--
124*4882a593Smuzhiyun2.20.1
125*4882a593Smuzhiyun
126