summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorMikolaj Boc <mikolaj.boc@qt.io>2022-11-14 15:23:22 +0100
committerMikolaj Boc <mikolaj.boc@qt.io>2022-11-15 12:19:47 +0100
commitc56bd31f23cdb67545775e7cd8be4264fa85d59a (patch)
tree4373940c4f2388820610e205c64d0f53d676a8d9 /src/plugins
parentea7a3105de688d8691cfd9d1f7af88f565c4fc4e (diff)
Always export and link in JSEvents and specialHTMLTargets
The two symbols are linked in & exported by using a publicly visible symbol emscripten_set_wheel_callback. To actually link it, but avoid calling it, a volatile false boolean flag is used in a guarding if. This should ideally be done by setting DEFAULT_LIBRARY_FUNCS_TO_INCLUDE, but a cmake bug (see QTBUG-108444) is preventing this. Fixes: QTBUG-108423 Task-number: QTBUG-108444 Change-Id: I6b0406d1059dcec63b3942468e210c53292ffe90 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp88
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.h3
2 files changed, 8 insertions, 83 deletions
diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
index 4aa14d820f..4a7cd988c3 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.cpp
+++ b/src/plugins/platforms/wasm/qwasmscreen.cpp
@@ -77,20 +77,11 @@ QWasmScreen::QWasmScreen(const emscripten::val &containerOrCanvas)
event.call<void>("preventDefault");
});
- // Create "specialHTMLTargets" mapping for the canvas. Normally, Emscripten
- // uses the html element id when targeting elements, for example when registering
- // event callbacks. However, this approach is limited to supporting single-document
- // 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.
- //
- // 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);
+ // Create "specialHTMLTargets" mapping for the canvas - the element might be unreachable based
+ // on its id only under some conditions, like the target being embedded in a shadow DOM or a
+ // subframe.
+ emscripten::val::module_property("specialHTMLTargets")
+ .set(canvasTargetId().toStdString(), m_canvas);
// Install event handlers on the container/canvas. This must be
// done after the canvas has been created above.
@@ -104,9 +95,8 @@ QWasmScreen::~QWasmScreen()
{
Q_ASSERT(!m_compositor); // deleteScreen should have been called to remove this screen
- if (hasSpecialHtmlTargets())
- emscripten::val::module_property("specialHTMLTargets")
- .set(canvasSpecialHtmlTargetId(), emscripten::val::undefined());
+ emscripten::val::module_property("specialHTMLTargets")
+ .set(canvasTargetId().toStdString(), emscripten::val::undefined());
m_canvas.set(m_canvasResizeObserverCallbackContextPropertyName, emscripten::val(intptr_t(0)));
}
@@ -158,73 +148,11 @@ QString QWasmScreen::canvasId() const
return QWasmString::toQString(m_canvas["id"]);
}
-// 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
{
- 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(uintptr_t(this));
-}
-
-namespace {
-
-// Compare Emscripten versions, returns > 0 if a is greater than b.
-
-int compareVersionComponents(int a, int b)
-{
- return a >= 0 && b >= 0 ? a - b : 0;
-}
-
-int compareEmscriptenVersions(std::tuple<int, int, int> a, std::tuple<int, int, int> b)
-{
- if (std::get<0>(a) == std::get<0>(b)) {
- if (std::get<1>(a) == std::get<1>(b)) {
- return compareVersionComponents(std::get<2>(a), std::get<2>(b));
- }
- return compareVersionComponents(std::get<1>(a), std::get<1>(b));
- }
- return compareVersionComponents(std::get<0>(a), std::get<0>(b));
-}
-
-bool isEmsdkVersionGreaterThan(std::tuple<int, int, int> test)
-{
- return compareEmscriptenVersions(
- std::make_tuple(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__), test) > 0;
-}
-
-} // namespace
-
-bool QWasmScreen::hasSpecialHtmlTargets() const
-{
- static bool gotIt = []{
- // Enable use of specialHTMLTargets, if available
-
- // On Emscripten > 3.1.14 (exact version not known), emscripten::val::module_property()
- // aborts instead of returning undefined when attempting to resolve the specialHTMLTargets
- // property, in the case where it is not defined. Disable the availability test in this case.
- // FIXME: Add alternative way to enable.
- if (isEmsdkVersionGreaterThan(std::make_tuple(3, 1, 14)))
- return false;
-
- emscripten::val htmlTargets = emscripten::val::module_property("specialHTMLTargets");
- if (htmlTargets.isUndefined())
- return false;
-
- // Check that the object has the expected type - it can also be
- // defined as an abort() function which prints an error on usage.
- return htmlTargets["constructor"]["name"].as<std::string>() == std::string("Array");
- }();
- return gotIt;
+ return QString("!qtcanvas_%1").arg(uintptr_t(this));
}
QRect QWasmScreen::geometry() const
diff --git a/src/plugins/platforms/wasm/qwasmscreen.h b/src/plugins/platforms/wasm/qwasmscreen.h
index 49e539be82..72f727da3a 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.h
+++ b/src/plugins/platforms/wasm/qwasmscreen.h
@@ -64,9 +64,6 @@ 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;