summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorMorten Sørvig <morten.sorvig@qt.io>2022-05-10 09:36:59 +0200
committerMorten Sørvig <morten.sorvig@qt.io>2022-06-01 13:52:47 +0200
commit86103f3af562152f642140e393c7beacac311dea (patch)
tree6c2985492b34a23887c489b3061f61a4d8de8f6b /src/plugins
parentcfa44787de49b85eddf8ceebd21764f1138d92c9 (diff)
wasm: don't enable specialHTMLTargets by default
Adding specialHTMLTargets to EXPORTED_RUNTIME_METHODS carries the obligation to actually use it as well; failing to do so makes Emscripten stop with a reference error on startup. However, we can't guarantee that Qt will use it in all cases. The current usage depends on QGuiApplication being used. Application code could be using QCoreApplication, or no application object at all. Detect if specialHTMLTargets is present instead, and then enable the code paths which uses it if that's the case. This means that apps which want to use e.g. multiple browser windows can opt into support by making sure EXPORTED_RUNTIME_METHODS contains specialHTMLTargets. Change-Id: I81105aa01946602fcf593f170e305d7dc9bad3be Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp47
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.h3
2 files changed, 39 insertions, 11 deletions
diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
index 51593b9d29..f2d600dcb0 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.cpp
+++ b/src/plugins/platforms/wasm/qwasmscreen.cpp
@@ -78,9 +78,14 @@ QWasmScreen::QWasmScreen(const emscripten::val &containerOrCanvas)
// apps/ages only, since Emscripten uses the main document to look up the element.
// As a workaround for this, Emscripten supports registering custom mappings in the
// "specialHTMLTargets" object. Add a mapping for the canvas for this screen.
- emscripten::val specialHtmlTargets = emscripten::val::module_property("specialHTMLTargets");
- std::string id = std::string("!qtcanvas_") + std::to_string(uint32_t(this));
- specialHtmlTargets.set(id, m_canvas);
+ //
+ // This functionality is gated on "specialHTMLTargets" being available as a module
+ // property. One way to ensure this is the case is to add it to EXPORTED_RUNTIME_METHODS.
+ // Qt does not currently do this by default since if added it _must_ be used in order
+ // to avoid an undefined reference error at startup, and there are cases when Qt won't use
+ // it, for example if QGuiApplication is not usded.
+ if (hasSpecialHtmlTargets())
+ emscripten::val::module_property("specialHTMLTargets").set(canvasSpecialHtmlTargetId(), m_canvas);
// Install event handlers on the container/canvas. This must be
// done after the canvas has been created above.
@@ -97,9 +102,9 @@ QWasmScreen::~QWasmScreen()
// event handlers.
m_compositor = nullptr;
- emscripten::val specialHtmlTargets = emscripten::val::module_property("specialHTMLTargets");
- std::string id = std::string("!qtcanvas_") + std::to_string(uint32_t(this));
- specialHtmlTargets.set(id, emscripten::val::undefined());
+ if (hasSpecialHtmlTargets())
+ emscripten::val::module_property("specialHTMLTargets")
+ .set(canvasSpecialHtmlTargetId(), emscripten::val::undefined());
m_canvas.set(m_canvasResizeObserverCallbackContextPropertyName, emscripten::val(intptr_t(0)));
}
@@ -146,13 +151,33 @@ QString QWasmScreen::canvasId() const
return QWasmString::toQString(m_canvas["id"]);
}
-// Returns the canvas _target_ id, for use with Emscripten's
-// event registration functions. The target id is a globally
-// unique id, unlike the html element id which is only unique
-// within one html document. See specialHtmlTargets.
+// Returns the canvas _target_ id, for use with Emscripten's event registration
+// functions. This either based on the id registered in specialHtmlTargets, or
+// on the canvas id.
QString QWasmScreen::canvasTargetId() const
{
- return QStringLiteral("!qtcanvas_") + QString::number(int32_t(this));
+ if (hasSpecialHtmlTargets())
+ return QString::fromStdString(canvasSpecialHtmlTargetId());
+ else
+ return QStringLiteral("#") + canvasId();
+}
+
+std::string QWasmScreen::canvasSpecialHtmlTargetId() const
+{
+ // Return a globally unique id for the canvas. We can choose any string,
+ // as long as it starts with a "!".
+ return std::string("!qtcanvas_") + std::to_string(uint32_t(this));
+}
+
+bool QWasmScreen::hasSpecialHtmlTargets() const
+{
+ static bool gotIt = []{
+ // specialHTMLTargets is a JavaScript Array if available. Note that it is
+ // an abort() function if not, so a simple isUndefined() test wont't work here.
+ return emscripten::val::module_property("specialHTMLTargets")
+ ["constructor"]["name"].as<std::string>() == std::string("Array");
+ }();
+ return gotIt;
}
QRect QWasmScreen::geometry() const
diff --git a/src/plugins/platforms/wasm/qwasmscreen.h b/src/plugins/platforms/wasm/qwasmscreen.h
index 9887e8abab..0e7d5f1e43 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.h
+++ b/src/plugins/platforms/wasm/qwasmscreen.h
@@ -62,6 +62,9 @@ public slots:
void setGeometry(const QRect &rect);
private:
+ std::string canvasSpecialHtmlTargetId() const;
+ bool hasSpecialHtmlTargets() const;
+
emscripten::val m_container;
emscripten::val m_canvas;
std::unique_ptr<QWasmCompositor> m_compositor;