From 8f04c50cffe5d6b3963a29715b2dd2d37269d5de Mon Sep 17 00:00:00 2001 From: Mikolaj Boc Date: Thu, 15 Dec 2022 13:24:19 +0100 Subject: [PATCH] Fix event dispatching on WASM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1) Check only for the events that the dispatcher is able to process, otherwise it enters an endless loop 2) Take care to run the correct wake up callback with Asyncify.handleSleep Fixes: QTBUG-109066 Change-Id: I10d29d18962c3e438e56712e1f43ecadedb6205c Pick-to: 6.5 Reviewed-by: Morten Johan Sørvig --- src/corelib/kernel/qeventdispatcher_wasm.cpp | 21 ++++++++++++++----- src/corelib/kernel/qeventdispatcher_wasm_p.h | 3 ++- .../platforms/wasm/qwasmeventdispatcher.cpp | 4 ++++ .../platforms/wasm/qwasmeventdispatcher.h | 1 + 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_wasm.cpp b/src/corelib/kernel/qeventdispatcher_wasm.cpp index 23f218c4a0..23d558a61b 100644 --- a/src/corelib/kernel/qeventdispatcher_wasm.cpp +++ b/src/corelib/kernel/qeventdispatcher_wasm.cpp @@ -41,9 +41,12 @@ static bool useAsyncify() } EM_JS(void, qt_asyncify_suspend_js, (), { + if (Module.qtSuspendId === undefined) + Module.qtSuspendId = 0; let sleepFn = (wakeUp) => { Module.qtAsyncifyWakeUp = wakeUp; }; + ++Module.qtSuspendId; return Asyncify.handleSleep(sleepFn); }); @@ -52,10 +55,16 @@ EM_JS(void, qt_asyncify_resume_js, (), { if (wakeUp == undefined) return; Module.qtAsyncifyWakeUp = undefined; + const suspendId = Module.qtSuspendId; // Delayed wakeup with zero-timer. Workaround/fix for // https://github.com/emscripten-core/emscripten/issues/10515 - setTimeout(wakeUp); + setTimeout(() => { + // Another suspend occurred while the timeout was in queue. + if (Module.qtSuspendId !== suspendId) + return; + wakeUp(); + }); }); #else @@ -200,7 +209,7 @@ bool QEventDispatcherWasm::processEvents(QEventLoop::ProcessEventsFlags flags) { emit awake(); - bool hasPendingEvents = qGlobalPostedEventsCount() > 0; + bool hasPendingEvents = hasWindowSystemEvents(); qCDebug(lcEventDispatcher) << "QEventDispatcherWasm::processEvents flags" << flags << "pending events" << hasPendingEvents; @@ -212,8 +221,6 @@ bool QEventDispatcherWasm::processEvents(QEventLoop::ProcessEventsFlags flags) handleApplicationExec(); } - hasPendingEvents = qGlobalPostedEventsCount() > 0; - if (!hasPendingEvents && (flags & QEventLoop::WaitForMoreEvents)) wait(); @@ -227,7 +234,7 @@ bool QEventDispatcherWasm::processEvents(QEventLoop::ProcessEventsFlags flags) processTimers(); } - hasPendingEvents = qGlobalPostedEventsCount() > 0; + hasPendingEvents = hasWindowSystemEvents(); QCoreApplication::sendPostedEvents(); processWindowSystemEvents(flags); return hasPendingEvents; @@ -238,6 +245,10 @@ void QEventDispatcherWasm::processWindowSystemEvents(QEventLoop::ProcessEventsFl Q_UNUSED(flags); } +bool QEventDispatcherWasm::hasWindowSystemEvents() { + return false; +} + void QEventDispatcherWasm::registerSocketNotifier(QSocketNotifier *notifier) { LOCK_GUARD(g_staticDataMutex); diff --git a/src/corelib/kernel/qeventdispatcher_wasm_p.h b/src/corelib/kernel/qeventdispatcher_wasm_p.h index b6de4187f4..3c211b3052 100644 --- a/src/corelib/kernel/qeventdispatcher_wasm_p.h +++ b/src/corelib/kernel/qeventdispatcher_wasm_p.h @@ -52,7 +52,8 @@ public: static void socketSelect(int timeout, int socket, bool waitForRead, bool waitForWrite, bool *selectForRead, bool *selectForWrite, bool *socketDisconnect); - protected: +protected: + virtual bool hasWindowSystemEvents(); virtual void processWindowSystemEvents(QEventLoop::ProcessEventsFlags flags); private: diff --git a/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp index 2fd1a30401..f48bcb6314 100644 --- a/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp +++ b/src/plugins/platforms/wasm/qwasmeventdispatcher.cpp @@ -14,4 +14,8 @@ void QWasmEventDispatcher::processWindowSystemEvents(QEventLoop::ProcessEventsFl QWindowSystemInterface::sendWindowSystemEvents(flags); } +bool QWasmEventDispatcher::hasWindowSystemEvents() { + return QWindowSystemInterface::windowSystemEventsQueued(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmeventdispatcher.h b/src/plugins/platforms/wasm/qwasmeventdispatcher.h index a28fa7263b..5b9b08cba3 100644 --- a/src/plugins/platforms/wasm/qwasmeventdispatcher.h +++ b/src/plugins/platforms/wasm/qwasmeventdispatcher.h @@ -12,6 +12,7 @@ class QWasmEventDispatcher : public QEventDispatcherWasm { protected: void processWindowSystemEvents(QEventLoop::ProcessEventsFlags flags) override; + bool hasWindowSystemEvents() override; }; QT_END_NAMESPACE