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.cpp151
1 files changed, 90 insertions, 61 deletions
diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp
index 3829043d07..e601d553f2 100644
--- a/src/plugins/platforms/wasm/qwasmintegration.cpp
+++ b/src/plugins/platforms/wasm/qwasmintegration.cpp
@@ -33,6 +33,8 @@
#include "qwasmcompositor.h"
#include "qwasmopenglcontext.h"
#include "qwasmtheme.h"
+#include "qwasmclipboard.h"
+#include "qwasmservices.h"
#include "qwasmwindow.h"
#ifndef QT_NO_OPENGL
@@ -55,47 +57,76 @@
using namespace emscripten;
QT_BEGIN_NAMESPACE
-void browserBeforeUnload()
+static void browserBeforeUnload(emscripten::val)
{
QWasmIntegration::QWasmBrowserExit();
}
-EMSCRIPTEN_BINDINGS(my_module)
+static void addCanvasElement(emscripten::val canvas)
{
- function("browserBeforeUnload", &browserBeforeUnload);
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ QWasmIntegration::get()->addScreen(canvasId);
}
-static QWasmIntegration *globalHtml5Integration;
-QWasmIntegration *QWasmIntegration::get() { return globalHtml5Integration; }
+static void removeCanvasElement(emscripten::val canvas)
+{
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ QWasmIntegration::get()->removeScreen(canvasId);
+}
-QWasmIntegration::QWasmIntegration()
- : m_fontDb(nullptr),
- m_compositor(new QWasmCompositor),
- m_screen(new QWasmScreen(m_compositor)),
- m_eventDispatcher(nullptr)
+static void resizeCanvasElement(emscripten::val canvas)
{
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ QWasmIntegration::get()->resizeScreen(canvasId);
+}
- globalHtml5Integration = this;
+EMSCRIPTEN_BINDINGS(qtQWasmIntegraton)
+{
+ function("qtBrowserBeforeUnload", &browserBeforeUnload);
+ function("qtAddCanvasElement", &addCanvasElement);
+ function("qtRemoveCanvasElement", &removeCanvasElement);
+ function("qtResizeCanvasElement", &resizeCanvasElement);
+}
- updateQScreenAndCanvasRenderSize();
- QWindowSystemInterface::handleScreenAdded(m_screen);
- emscripten_set_resize_callback(0, (void *)this, 1, uiEvent_cb);
+QWasmIntegration *QWasmIntegration::s_instance;
- m_eventTranslator = new QWasmEventTranslator;
+QWasmIntegration::QWasmIntegration()
+ : m_fontDb(nullptr),
+ m_desktopServices(nullptr),
+ m_clipboard(new QWasmClipboard)
+{
+ s_instance = this;
+
+ // We expect that qtloader.js has populated Module.qtCanvasElements with one or more canvases.
+ // Also check Module.canvas, which may be set if the emscripen or a custom loader is used.
+ emscripten::val qtCanvaseElements = val::module_property("qtCanvasElements");
+ emscripten::val canvas = val::module_property("canvas");
+
+ if (!qtCanvaseElements.isUndefined()) {
+ int screenCount = qtCanvaseElements["length"].as<int>();
+ for (int i = 0; i < screenCount; ++i) {
+ emscripten::val canvas = qtCanvaseElements[i].as<emscripten::val>();
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ addScreen(canvasId);
+ }
+ } else if (!canvas.isUndefined()){
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ addScreen(canvasId);
+ }
- EM_ASM(// exit app if browser closes
- window.onbeforeunload = function () {
- Module.browserBeforeUnload();
- };
- );
+ emscripten::val::global("window").set("onbeforeunload", val::module_property("qtBrowserBeforeUnload"));
}
QWasmIntegration::~QWasmIntegration()
{
- delete m_compositor;
- QWindowSystemInterface::handleScreenRemoved(m_screen);
delete m_fontDb;
- delete m_eventTranslator;
+ delete m_desktopServices;
+
+ for (auto it = m_screens.constBegin(); it != m_screens.constEnd(); ++it)
+ QWindowSystemInterface::handleScreenRemoved(*it);
+ m_screens.clear();
+
+ s_instance = nullptr;
}
void QWasmIntegration::QWasmBrowserExit()
@@ -109,7 +140,7 @@ bool QWasmIntegration::hasCapability(QPlatformIntegration::Capability cap) const
switch (cap) {
case ThreadedPixmaps: return true;
case OpenGL: return true;
- case ThreadedOpenGL: return true;
+ case ThreadedOpenGL: return false;
case RasterGLSurface: return false; // to enable this you need to fix qopenglwidget and quickwidget for wasm
case MultipleWindows: return true;
case WindowManagement: return true;
@@ -119,13 +150,15 @@ bool QWasmIntegration::hasCapability(QPlatformIntegration::Capability cap) const
QPlatformWindow *QWasmIntegration::createPlatformWindow(QWindow *window) const
{
- return new QWasmWindow(window, m_compositor, m_backingStores.value(window));
+ QWasmCompositor *compositor = QWasmScreen::get(window->screen())->compositor();
+ return new QWasmWindow(window, compositor, m_backingStores.value(window));
}
QPlatformBackingStore *QWasmIntegration::createPlatformBackingStore(QWindow *window) const
{
#ifndef QT_NO_OPENGL
- QWasmBackingStore *backingStore = new QWasmBackingStore(m_compositor, window);
+ QWasmCompositor *compositor = QWasmScreen::get(window->screen())->compositor();
+ QWasmBackingStore *backingStore = new QWasmBackingStore(compositor, window);
m_backingStores.insert(window, backingStore);
return backingStore;
#else
@@ -155,9 +188,21 @@ QAbstractEventDispatcher *QWasmIntegration::createEventDispatcher() const
QVariant QWasmIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
+ if (hint == ShowIsFullScreen)
+ return true;
+
return QPlatformIntegration::styleHint(hint);
}
+Qt::WindowState QWasmIntegration::defaultWindowState(Qt::WindowFlags flags) const
+{
+ // Don't maximize dialogs
+ if (flags & Qt::Dialog & ~Qt::Window)
+ return Qt::WindowNoState;
+
+ return QPlatformIntegration::defaultWindowState(flags);
+}
+
QStringList QWasmIntegration::themeNames() const
{
return QStringList() << QLatin1String("webassembly");
@@ -170,50 +215,34 @@ QPlatformTheme *QWasmIntegration::createPlatformTheme(const QString &name) const
return QPlatformIntegration::createPlatformTheme(name);
}
-int QWasmIntegration::uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData)
+QPlatformServices *QWasmIntegration::services() const
{
- Q_UNUSED(e)
- Q_UNUSED(userData)
-
- if (eventType == EMSCRIPTEN_EVENT_RESIZE) {
- // This resize event is called when the HTML window is resized. Depending
- // on the page layout the the canvas might also have been resized, so we
- // update the Qt screen size (and canvas render size).
- updateQScreenAndCanvasRenderSize();
- }
-
- return 0;
+ if (m_desktopServices == nullptr)
+ m_desktopServices = new QWasmServices();
+ return m_desktopServices;
}
-static void set_canvas_size(double width, double height)
+QPlatformClipboard* QWasmIntegration::clipboard() const
{
- EM_ASM_({
- var canvas = Module.canvas;
- canvas.width = $0;
- canvas.height = $1;
- }, width, height);
+ return m_clipboard;
}
-void QWasmIntegration::updateQScreenAndCanvasRenderSize()
+void QWasmIntegration::addScreen(const QString &canvasId)
{
- // The HTML canvas has two sizes: the CSS size and the canvas render size.
- // The CSS size is determined according to standard CSS rules, while the
- // render size is set using the "width" and "height" attributes. The render
- // size must be set manually and is not auto-updated on CSS size change.
- // Setting the render size to a value larger than the CSS size enables high-dpi
- // rendering.
-
- double css_width;
- double css_height;
- emscripten_get_element_css_size(0, &css_width, &css_height);
- QSizeF cssSize(css_width, css_height);
+ QWasmScreen *screen = new QWasmScreen(canvasId);
+ m_clipboard->installEventHandlers(canvasId);
+ m_screens.insert(canvasId, screen);
+ QWindowSystemInterface::handleScreenAdded(screen);
+}
- QWasmScreen *screen = QWasmIntegration::get()->m_screen;
- QSizeF canvasSize = cssSize * screen->devicePixelRatio();
+void QWasmIntegration::removeScreen(const QString &canvasId)
+{
+ QWindowSystemInterface::handleScreenRemoved(m_screens.take(canvasId));
+}
- set_canvas_size(canvasSize.width(), canvasSize.height());
- screen->setGeometry(QRect(QPoint(0, 0), cssSize.toSize()));
- QWasmIntegration::get()->m_compositor->redrawWindowContent();
+void QWasmIntegration::resizeScreen(const QString &canvasId)
+{
+ m_screens.value(canvasId)->updateQScreenAndCanvasRenderSize();
}
QT_END_NAMESPACE