summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qeventdispatcher_wasm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qeventdispatcher_wasm.cpp')
-rw-r--r--src/corelib/kernel/qeventdispatcher_wasm.cpp90
1 files changed, 32 insertions, 58 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_wasm.cpp b/src/corelib/kernel/qeventdispatcher_wasm.cpp
index c733f46c14..73f468aae5 100644
--- a/src/corelib/kernel/qeventdispatcher_wasm.cpp
+++ b/src/corelib/kernel/qeventdispatcher_wasm.cpp
@@ -26,14 +26,16 @@ Q_LOGGING_CATEGORY(lcEventDispatcherTimers, "qt.eventdispatcher.timers");
#define LOCK_GUARD(M)
#endif
-#ifdef QT_HAVE_EMSCRIPTEN_ASYNCIFY
-
// Emscripten asyncify currently supports one level of suspend -
// recursion is not permitted. We track the suspend state here
// on order to fail (more) gracefully, but we can of course only
// track Qts own usage of asyncify.
static bool g_is_asyncify_suspended = false;
+EM_JS(bool, qt_have_asyncify_js, (), {
+ return typeof Asyncify != "undefined";
+});
+
EM_JS(void, qt_asyncify_suspend_js, (), {
let sleepFn = (wakeUp) => {
Module.qtAsyncifyWakeUp = wakeUp;
@@ -52,6 +54,15 @@ EM_JS(void, qt_asyncify_resume_js, (), {
setTimeout(wakeUp);
});
+// Returns true if asyncify is available.
+bool qt_have_asyncify()
+{
+ static bool have_asyncify = []{
+ return qt_have_asyncify_js();
+ }();
+ return have_asyncify;
+}
+
// Suspends the main thread until qt_asyncify_resume() is called. Returns
// false immediately if Qt has already suspended the main thread (recursive
// suspend is not supported by Emscripten). Returns true (after resuming),
@@ -76,19 +87,6 @@ bool qt_asyncify_resume()
return true;
}
-// Yields control to the browser, so that it can process events. Must
-// be called on the main thread. Returns false immediately if Qt has
-// already suspended the main thread. Returns true after yielding.
-bool qt_asyncify_yield()
-{
- if (g_is_asyncify_suspended)
- return false;
- emscripten_sleep(0);
- return true;
-}
-
-#endif // QT_HAVE_EMSCRIPTEN_ASYNCIFY
-
Q_CONSTINIT QEventDispatcherWasm *QEventDispatcherWasm::g_mainThreadEventDispatcher = nullptr;
#if QT_CONFIG(thread)
Q_CONSTINIT QVector<QEventDispatcherWasm *> QEventDispatcherWasm::g_secondaryThreadEventDispatchers;
@@ -198,9 +196,6 @@ bool QEventDispatcherWasm::processEvents(QEventLoop::ProcessEventsFlags flags)
handleApplicationExec();
}
- if (!(flags & QEventLoop::ExcludeUserInputEvents))
- pollForNativeEvents();
-
hasPendingEvents = qGlobalPostedEventsCount() > 0;
if (!hasPendingEvents && (flags & QEventLoop::WaitForMoreEvents))
@@ -373,34 +368,14 @@ void QEventDispatcherWasm::handleApplicationExec()
void QEventDispatcherWasm::handleDialogExec()
{
-#ifndef QT_HAVE_EMSCRIPTEN_ASYNCIFY
- qWarning() << "Warning: dialog exec() is not supported on Qt for WebAssembly in this"
- << "configuration. Please use show() instead, or enable experimental support"
- << "for asyncify.\n"
- << "When using exec() (without asyncify) the dialog will show, the user can interact"
- << "with it and the appropriate signals will be emitted on close. However, the"
- << "exec() call never returns, stack content at the time of the exec() call"
- << "is leaked, and the exec() call may interfere with input event processing";
- emscripten_sleep(1); // This call never returns
-#endif
+ if (!qt_have_asyncify()) {
+ qWarning() << "Warning: exec() is not supported on Qt for WebAssembly in this configuration. Please build"
+ << "with asyncify support, or use an asynchronous API like QDialog::open()";
+ emscripten_sleep(1); // This call never returns
+ }
// For the asyncify case we do nothing here and wait for events in wait()
}
-void QEventDispatcherWasm::pollForNativeEvents()
-{
- // Secondary thread event dispatchers do not support native events
- if (isSecondaryThreadEventDispatcher())
- return;
-
-#if HAVE_EMSCRIPTEN_ASYNCIFY
- // Asyncify allows us to yield to the browser and have it process native events -
- // but this will fail if we are recursing and are already in a yield.
- bool didYield = qt_asyncify_yield();
- if (!didYield)
- qWarning("QEventDispatcherWasm::processEvents() did not asyncify process native events");
-#endif
-}
-
// Blocks/suspends the calling thread. This is possible in two cases:
// - Caller is a secondary thread: block on m_moreEvents
// - Caller is the main thread and asyncify is enabled: suspend using qt_asyncify_suspend()
@@ -422,20 +397,20 @@ bool QEventDispatcherWasm::wait(int timeout)
#endif
Q_ASSERT(emscripten_is_main_runtime_thread());
Q_ASSERT(isMainThreadEventDispatcher());
-#ifdef QT_HAVE_EMSCRIPTEN_ASYNCIFY
- if (timeout > 0)
- qWarning() << "QEventDispatcherWasm asyncify wait with timeout is not supported; timeout will be ignored"; // FIXME
-
- bool didSuspend = qt_asyncify_suspend();
- if (!didSuspend) {
- qWarning("QEventDispatcherWasm: current thread is already suspended; could not asyncify wait for events");
- return false;
+ if (qt_have_asyncify()) {
+ if (timeout > 0)
+ qWarning() << "QEventDispatcherWasm asyncify wait with timeout is not supported; timeout will be ignored"; // FIXME
+
+ bool didSuspend = qt_asyncify_suspend();
+ if (!didSuspend) {
+ qWarning("QEventDispatcherWasm: current thread is already suspended; could not asyncify wait for events");
+ return false;
+ }
+ return true;
+ } else {
+ qWarning("QEventLoop::WaitForMoreEvents is not supported on the main thread without asyncify");
+ Q_UNUSED(timeout);
}
- return true;
-#else
- qWarning("QEventLoop::WaitForMoreEvents is not supported on the main thread without asyncify");
- Q_UNUSED(timeout);
-#endif
return false;
}
@@ -453,12 +428,10 @@ bool QEventDispatcherWasm::wakeEventDispatcherThread()
}
#endif
Q_ASSERT(isMainThreadEventDispatcher());
-#ifdef QT_HAVE_EMSCRIPTEN_ASYNCIFY
if (g_is_asyncify_suspended) {
runOnMainThread([]{ qt_asyncify_resume(); });
return true;
}
-#endif
return false;
}
@@ -522,6 +495,7 @@ void QEventDispatcherWasm::updateNativeTimer()
if (m_timerId > 0) {
emscripten_clear_timeout(m_timerId);
m_timerId = 0;
+ m_timerTargetTime = 0;
}
return;
}