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