Fix event dispatching on WASM

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 <morten.sorvig@qt.io>
bb10
Mikolaj Boc 2022-12-15 13:24:19 +01:00 committed by Morten Johan Sørvig
parent eac9f39517
commit 8f04c50cff
4 changed files with 23 additions and 6 deletions

View File

@ -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);

View File

@ -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:

View File

@ -14,4 +14,8 @@ void QWasmEventDispatcher::processWindowSystemEvents(QEventLoop::ProcessEventsFl
QWindowSystemInterface::sendWindowSystemEvents(flags);
}
bool QWasmEventDispatcher::hasWindowSystemEvents() {
return QWindowSystemInterface::windowSystemEventsQueued();
}
QT_END_NAMESPACE

View File

@ -12,6 +12,7 @@ class QWasmEventDispatcher : public QEventDispatcherWasm
{
protected:
void processWindowSystemEvents(QEventLoop::ProcessEventsFlags flags) override;
bool hasWindowSystemEvents() override;
};
QT_END_NAMESPACE