summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm/qwasmintegration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmintegration.cpp')
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.cpp98
1 files changed, 81 insertions, 17 deletions
diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp
index 5dc96e0f3c..c8f5072cb8 100644
--- a/src/plugins/platforms/wasm/qwasmintegration.cpp
+++ b/src/plugins/platforms/wasm/qwasmintegration.cpp
@@ -38,14 +38,19 @@ using namespace emscripten;
using namespace Qt::StringLiterals;
+static void setContainerElements(emscripten::val elementArray)
+{
+ QWasmIntegration::get()->setContainerElements(elementArray);
+}
+
static void addContainerElement(emscripten::val element)
{
- QWasmIntegration::get()->addScreen(element);
+ QWasmIntegration::get()->addContainerElement(element);
}
static void removeContainerElement(emscripten::val element)
{
- QWasmIntegration::get()->removeScreen(element);
+ QWasmIntegration::get()->removeContainerElement(element);
}
static void resizeContainerElement(emscripten::val element)
@@ -66,6 +71,7 @@ static void resizeAllScreens(emscripten::val event)
EMSCRIPTEN_BINDINGS(qtQWasmIntegraton)
{
+ function("qtSetContainerElements", &setContainerElements);
function("qtAddContainerElement", &addContainerElement);
function("qtRemoveContainerElement", &removeContainerElement);
function("qtResizeContainerElement", &resizeContainerElement);
@@ -94,6 +100,7 @@ QWasmIntegration::QWasmIntegration()
// div element. Qt historically supported supplying canvas for screen elements - these elements
// will be transformed into divs and warnings about deprecation will be printed. See
// QWasmScreen ctor.
+ emscripten::val filtered = emscripten::val::array();
emscripten::val qtContainerElements = val::module_property("qtContainerElements");
if (qtContainerElements.isArray()) {
for (int i = 0; i < qtContainerElements["length"].as<int>(); ++i) {
@@ -101,13 +108,14 @@ QWasmIntegration::QWasmIntegration()
if (element.isNull() || element.isUndefined())
qWarning() << "Skipping null or undefined element in qtContainerElements";
else
- addScreen(element);
+ filtered.call<void>("push", element);
}
} else {
// No screens, which may or may not be intended
qWarning() << "The qtContainerElements module property was not set or is invalid. "
"Proceeding with no screens.";
}
+ setContainerElements(filtered);
// install browser window resize handler
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, nullptr, EM_TRUE,
@@ -149,7 +157,7 @@ QWasmIntegration::~QWasmIntegration()
#endif
for (const auto &elementAndScreen : m_screens)
- elementAndScreen.second->deleteScreen();
+ elementAndScreen.wasmScreen->deleteScreen();
m_screens.clear();
@@ -285,37 +293,93 @@ QPlatformAccessibility *QWasmIntegration::accessibility() const
}
#endif
+void QWasmIntegration::setContainerElements(emscripten::val elementArray)
+{
+ const auto *primaryScreenBefore = m_screens.isEmpty() ? nullptr : m_screens[0].wasmScreen;
+ QList<ScreenMapping> newScreens;
+
+ QList<QWasmScreen *> screensToDelete;
+ std::transform(m_screens.begin(), m_screens.end(), std::back_inserter(screensToDelete),
+ [](const ScreenMapping &mapping) { return mapping.wasmScreen; });
+
+ for (int i = 0; i < elementArray["length"].as<int>(); ++i) {
+ const auto element = elementArray[i];
+ const auto it = std::find_if(
+ m_screens.begin(), m_screens.end(),
+ [&element](const ScreenMapping &screen) { return screen.emscriptenVal == element; });
+ QWasmScreen *screen;
+ if (it != m_screens.end()) {
+ screen = it->wasmScreen;
+ screensToDelete.erase(std::remove_if(screensToDelete.begin(), screensToDelete.end(),
+ [screen](const QWasmScreen *removedScreen) {
+ return removedScreen == screen;
+ }),
+ screensToDelete.end());
+ } else {
+ screen = new QWasmScreen(element);
+ QWindowSystemInterface::handleScreenAdded(screen);
+ }
+ newScreens.push_back({element, screen});
+ }
+
+ std::for_each(screensToDelete.begin(), screensToDelete.end(),
+ [](QWasmScreen *removed) { removed->deleteScreen(); });
+
+ m_screens = newScreens;
+ auto *primaryScreenAfter = m_screens.isEmpty() ? nullptr : m_screens[0].wasmScreen;
+ if (primaryScreenAfter && primaryScreenAfter != primaryScreenBefore)
+ QWindowSystemInterface::handlePrimaryScreenChanged(primaryScreenAfter);
+}
-void QWasmIntegration::addScreen(const emscripten::val &element)
+void QWasmIntegration::addContainerElement(emscripten::val element)
{
+ Q_ASSERT_X(m_screens.end()
+ == std::find_if(m_screens.begin(), m_screens.end(),
+ [&element](const ScreenMapping &screen) {
+ return screen.emscriptenVal == element;
+ }),
+ Q_FUNC_INFO, "Double-add of an element");
+
QWasmScreen *screen = new QWasmScreen(element);
- m_screens.append(qMakePair(element, screen));
QWindowSystemInterface::handleScreenAdded(screen);
+ m_screens.push_back({element, screen});
}
-void QWasmIntegration::removeScreen(const emscripten::val &element)
+void QWasmIntegration::removeContainerElement(emscripten::val element)
{
- auto it = std::find_if(m_screens.begin(), m_screens.end(),
- [&] (const QPair<emscripten::val, QWasmScreen *> &candidate) { return candidate.first.equals(element); });
+ const auto *primaryScreenBefore = m_screens.isEmpty() ? nullptr : m_screens[0].wasmScreen;
+
+ const auto it =
+ std::find_if(m_screens.begin(), m_screens.end(),
+ [&element](const ScreenMapping &screen) { return screen.emscriptenVal == element; });
if (it == m_screens.end()) {
- qWarning() << "Attempting to remove non-existing screen for element"
- << QString::fromJsString(element["id"]);
+ qWarning() << "Attempt to remove a nonexistent screen.";
return;
}
- it->second->deleteScreen();
- m_screens.erase(it);
+
+ QWasmScreen *removedScreen = it->wasmScreen;
+ removedScreen->deleteScreen();
+
+ m_screens.erase(std::remove_if(m_screens.begin(), m_screens.end(),
+ [removedScreen](const ScreenMapping &mapping) {
+ return removedScreen == mapping.wasmScreen;
+ }),
+ m_screens.end());
+ auto *primaryScreenAfter = m_screens.isEmpty() ? nullptr : m_screens[0].wasmScreen;
+ if (primaryScreenAfter && primaryScreenAfter != primaryScreenBefore)
+ QWindowSystemInterface::handlePrimaryScreenChanged(primaryScreenAfter);
}
void QWasmIntegration::resizeScreen(const emscripten::val &element)
{
auto it = std::find_if(m_screens.begin(), m_screens.end(),
- [&] (const QPair<emscripten::val, QWasmScreen *> &candidate) { return candidate.first.equals(element); });
+ [&] (const ScreenMapping &candidate) { return candidate.emscriptenVal.equals(element); });
if (it == m_screens.end()) {
qWarning() << "Attempting to resize non-existing screen for element"
<< QString::fromJsString(element["id"]);
return;
}
- it->second->updateQScreenAndCanvasRenderSize();
+ it->wasmScreen->updateQScreenAndCanvasRenderSize();
}
void QWasmIntegration::updateDpi()
@@ -325,13 +389,13 @@ void QWasmIntegration::updateDpi()
return;
qreal dpiValue = dpi.as<qreal>();
for (const auto &elementAndScreen : m_screens)
- QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(elementAndScreen.second->screen(), dpiValue, dpiValue);
+ QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(elementAndScreen.wasmScreen->screen(), dpiValue, dpiValue);
}
void QWasmIntegration::resizeAllScreens()
{
for (const auto &elementAndScreen : m_screens)
- elementAndScreen.second->updateQScreenAndCanvasRenderSize();
+ elementAndScreen.wasmScreen->updateQScreenAndCanvasRenderSize();
}
quint64 QWasmIntegration::getTimestamp()