summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/wasm')
-rw-r--r--src/plugins/platforms/wasm/qtloader.js29
-rw-r--r--src/plugins/platforms/wasm/qwasmclipboard.cpp38
-rw-r--r--src/plugins/platforms/wasm/qwasmcompositor.cpp4
-rw-r--r--src/plugins/platforms/wasm/qwasmcompositor.h2
-rw-r--r--src/plugins/platforms/wasm/qwasmeventtranslator.cpp64
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.cpp77
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.h13
-rw-r--r--src/plugins/platforms/wasm/qwasmservices.cpp45
-rw-r--r--src/plugins/platforms/wasm/qwasmservices.h45
-rw-r--r--src/plugins/platforms/wasm/wasm.pro6
-rw-r--r--src/plugins/platforms/wasm/wasm_shell.html8
11 files changed, 256 insertions, 75 deletions
diff --git a/src/plugins/platforms/wasm/qtloader.js b/src/plugins/platforms/wasm/qtloader.js
index 049eb1c35e..2db7723ae2 100644
--- a/src/plugins/platforms/wasm/qtloader.js
+++ b/src/plugins/platforms/wasm/qtloader.js
@@ -118,6 +118,12 @@
// "Exited", iff crashed is false.
// exitText
// Abort/exit message.
+// addCanvasElement
+// Add canvas at run-time. Adds a corresponding QScreen,
+// removeCanvasElement
+// Remove canvas at run-time. Removes the corresponding QScreen.
+// resizeCanvasElement
+// Signals to the application that a canvas has been resized.
var Module = {}
@@ -158,6 +164,7 @@ function QtLoader(config)
// Set contentEditable in order to enable clipboard events; hide the resulting focus frame.
canvas.contentEditable = true;
canvas.style.outline = "0px solid transparent";
+ canvas.style.caretColor = "transparent";
canvas.style.cursor = "default";
return canvas;
@@ -227,6 +234,9 @@ function QtLoader(config)
publicAPI.canLoadApplication = canLoadQt();
publicAPI.status = undefined;
publicAPI.loadEmscriptenModule = loadEmscriptenModule;
+ publicAPI.addCanvasElement = addCanvasElement;
+ publicAPI.removeCanvasElement = removeCanvasElement;
+ publicAPI.resizeCanvasElement = resizeCanvasElement;
restartCount = 0;
@@ -528,6 +538,25 @@ function QtLoader(config)
window.setTimeout(function() { handleStatusChange(); }, 0);
}
+ function addCanvasElement(element) {
+ if (publicAPI.status == "Running")
+ Module.qtAddCanvasElement(element);
+ else
+ console.log("Error: addCanvasElement can only be called in the Running state");
+ }
+
+ function removeCanvasElement(element) {
+ if (publicAPI.status == "Running")
+ Module.qtRemoveCanvasElement(element);
+ else
+ console.log("Error: removeCanvasElement can only be called in the Running state");
+ }
+
+ function resizeCanvasElement(element) {
+ if (publicAPI.status == "Running")
+ Module.qtResizeCanvasElement(element);
+ }
+
setStatus("Created");
return publicAPI;
diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp
index 7a7b253b19..d4a1e4dd50 100644
--- a/src/plugins/platforms/wasm/qwasmclipboard.cpp
+++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp
@@ -76,8 +76,8 @@ static void qClipboardCutTo(val event)
}
val module = val::global("Module");
- val clipdata = module.call<val>("getClipboardData");
- val clipFormat = module.call<val>("getClipboardFormat");
+ val clipdata = module.call<val>("qtGetClipboardData");
+ val clipFormat = module.call<val>("qtGetClipboardFormat");
event["clipboardData"].call<void>("setData", clipFormat, clipdata);
event.call<void>("preventDefault");
}
@@ -91,8 +91,8 @@ static void qClipboardCopyTo(val event)
}
val module = val::global("Module");
- val clipdata = module.call<val>("getClipboardData");
- val clipFormat = module.call<val>("getClipboardFormat");
+ val clipdata = module.call<val>("qtGetClipboardData");
+ val clipFormat = module.call<val>("qtGetClipboardFormat");
event["clipboardData"].call<void>("setData", clipFormat, clipdata);
event.call<void>("preventDefault");
}
@@ -101,7 +101,7 @@ static void qClipboardPasteTo(val event)
{
bool hasClipboardApi = QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi;
val clipdata = hasClipboardApi ?
- val::global("Module").call<val>("getClipboardData") :
+ val::global("Module").call<val>("qtGetClipboardData") :
event["clipboardData"].call<val>("getData", std::string("text"));
const std::string data = clipdata.as<std::string>();
@@ -113,14 +113,14 @@ static void qClipboardPasteTo(val event)
}
}
-EMSCRIPTEN_BINDINGS(clipboard_module) {
- function("getClipboardData", &getClipboardData);
- function("getClipboardFormat", &getClipboardFormat);
- function("pasteClipboardData", &pasteClipboardData);
- function("qClipboardPromiseResolve", &qClipboardPromiseResolve);
- function("qClipboardCutTo", &qClipboardCutTo);
- function("qClipboardCopyTo", &qClipboardCopyTo);
- function("qClipboardPasteTo", &qClipboardPasteTo);
+EMSCRIPTEN_BINDINGS(qtClipboardModule) {
+ function("qtGetClipboardData", &getClipboardData);
+ function("qtGetClipboardFormat", &getClipboardFormat);
+ function("qtPasteClipboardData", &pasteClipboardData);
+ function("qtClipboardPromiseResolve", &qClipboardPromiseResolve);
+ function("qtClipboardCutTo", &qClipboardCutTo);
+ function("qtClipboardCopyTo", &qClipboardCopyTo);
+ function("qtClipboardPasteTo", &qClipboardPasteTo);
}
QWasmClipboard::QWasmClipboard()
@@ -200,11 +200,11 @@ void QWasmClipboard::installEventHandlers(const QString &canvasId)
// Fallback path for browsers which do not support direct clipboard access
val canvas = val::global(canvasId.toUtf8().constData());
canvas.call<void>("addEventListener", std::string("cut"),
- val::module_property("qClipboardCutTo"));
+ val::module_property("qtClipboardCutTo"));
canvas.call<void>("addEventListener", std::string("copy"),
- val::module_property("qClipboardCopyTo"));
+ val::module_property("qtClipboardCopyTo"));
canvas.call<void>("addEventListener", std::string("paste"),
- val::module_property("qClipboardPasteTo"));
+ val::module_property("qtClipboardPasteTo"));
}
void QWasmClipboard::readTextFromClipboard()
@@ -212,7 +212,7 @@ void QWasmClipboard::readTextFromClipboard()
if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) {
val navigator = val::global("navigator");
val textPromise = navigator["clipboard"].call<val>("readText");
- val readTextResolve = val::global("Module")["qClipboardPromiseResolve"];
+ val readTextResolve = val::global("Module")["qtClipboardPromiseResolve"];
textPromise.call<val>("then", readTextResolve);
}
}
@@ -221,8 +221,8 @@ void QWasmClipboard::writeTextToClipboard()
{
if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) {
val module = val::global("Module");
- val txt = module.call<val>("getClipboardData");
- val format = module.call<val>("getClipboardFormat");
+ val txt = module.call<val>("qtGetClipboardData");
+ val format = module.call<val>("qtGetClipboardFormat");
val navigator = val::global("navigator");
navigator["clipboard"].call<void>("writeText", txt.as<std::string>());
}
diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp
index 90cc20789d..e6a69c4814 100644
--- a/src/plugins/platforms/wasm/qwasmcompositor.cpp
+++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp
@@ -193,7 +193,7 @@ void QWasmCompositor::requestRedraw()
QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
}
-QWindow *QWasmCompositor::windowAt(QPoint p, int padding) const
+QWindow *QWasmCompositor::windowAt(QPoint globalPoint, int padding) const
{
int index = m_windowStack.count() - 1;
// qDebug() << "window at" << "point" << p << "window count" << index;
@@ -205,7 +205,7 @@ QWindow *QWasmCompositor::windowAt(QPoint p, int padding) const
QRect geometry = compositedWindow.window->windowFrameGeometry()
.adjusted(-padding, -padding, padding, padding);
- if (compositedWindow.visible && geometry.contains(p))
+ if (compositedWindow.visible && geometry.contains(globalPoint))
return m_windowStack.at(index)->window();
--index;
}
diff --git a/src/plugins/platforms/wasm/qwasmcompositor.h b/src/plugins/platforms/wasm/qwasmcompositor.h
index ed6facdcc3..3104573073 100644
--- a/src/plugins/platforms/wasm/qwasmcompositor.h
+++ b/src/plugins/platforms/wasm/qwasmcompositor.h
@@ -116,7 +116,7 @@ public:
void redrawWindowContent();
void requestRedraw();
- QWindow *windowAt(QPoint p, int padding = 0) const;
+ QWindow *windowAt(QPoint globalPoint, int padding = 0) const;
QWindow *keyWindow() const;
bool event(QEvent *event);
diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
index 63a764e741..f4ca49997a 100644
--- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
+++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
@@ -316,8 +316,8 @@ static void mouseWheelEvent(emscripten::val event) {
}
}
-EMSCRIPTEN_BINDINGS(mouse_module) {
- function("mouseWheelEvent", &mouseWheelEvent);
+EMSCRIPTEN_BINDINGS(qtMouseModule) {
+ function("qtMouseWheelEvent", &mouseWheelEvent);
}
QWasmEventTranslator::QWasmEventTranslator(QWasmScreen *screen)
@@ -358,7 +358,7 @@ void QWasmEventTranslator::initEventHandlers()
emscripten::val::global(canvasId).call<void>("addEventListener",
std::string("wheel"),
- val::module_property("mouseWheelEvent"));
+ val::module_property("qtMouseWheelEvent"));
}
}
@@ -549,22 +549,22 @@ void resizeWindow(QWindow *window, QWasmWindow::ResizeMode mode,
void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEvent *mouseEvent)
{
auto timestamp = mouseEvent->timestamp;
- QPoint point(mouseEvent->targetX, mouseEvent->targetY);
+ QPoint targetPoint(mouseEvent->targetX, mouseEvent->targetY);
+ QPoint globalPoint = screen()->geometry().topLeft() + targetPoint;
QEvent::Type buttonEventType = QEvent::None;
-
Qt::MouseButton button = translateMouseButton(mouseEvent->button);
Qt::KeyboardModifiers modifiers = translateMouseEventModifier(mouseEvent);
- QWindow *window2 = screen()->compositor()->windowAt(point, 5);
- if (window2 != nullptr)
- lastWindow = window2;
-
- QWasmWindow *htmlWindow = static_cast<QWasmWindow*>(window2->handle());
+ QWindow *window2 = screen()->compositor()->windowAt(globalPoint, 5);
+ if (window2 == nullptr)
+ return;
+ lastWindow = window2;
- bool interior = window2 && window2->geometry().contains(point);
+ QPoint localPoint = window2->mapFromGlobal(globalPoint);
+ bool interior = window2->geometry().contains(globalPoint);
- QPoint localPoint(point.x() - window2->geometry().x(), point.y() - window2->geometry().y());
+ QWasmWindow *htmlWindow = static_cast<QWasmWindow*>(window2->handle());
switch (eventType) {
case EMSCRIPTEN_EVENT_MOUSEDOWN:
{
@@ -580,18 +580,18 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven
pressedWindow = window2;
buttonEventType = QEvent::MouseButtonPress;
if (!(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized)) {
- if (htmlWindow && window2->flags().testFlag(Qt::WindowTitleHint) && htmlWindow->isPointOnTitle(point))
+ if (htmlWindow && window2->flags().testFlag(Qt::WindowTitleHint) && htmlWindow->isPointOnTitle(globalPoint))
draggedWindow = window2;
- else if (htmlWindow && htmlWindow->isPointOnResizeRegion(point)) {
+ else if (htmlWindow && htmlWindow->isPointOnResizeRegion(globalPoint)) {
draggedWindow = window2;
- resizeMode = htmlWindow->resizeModeAtPoint(point);
- resizePoint = point;
+ resizeMode = htmlWindow->resizeModeAtPoint(globalPoint);
+ resizePoint = globalPoint;
resizeStartRect = window2->geometry();
}
}
}
- htmlWindow->injectMousePressed(localPoint, point, button, modifiers);
+ htmlWindow->injectMousePressed(localPoint, globalPoint, button, modifiers);
break;
}
case EMSCRIPTEN_EVENT_MOUSEUP:
@@ -611,7 +611,7 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven
}
if (oldWindow)
- oldWindow->injectMouseReleased(localPoint, point, button, modifiers);
+ oldWindow->injectMouseReleased(localPoint, globalPoint, button, modifiers);
break;
}
case EMSCRIPTEN_EVENT_MOUSEMOVE: // drag event
@@ -640,7 +640,7 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven
}
if (window2 && interior) {
QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(
- window2, timestamp, localPoint, point, pressedButtons, button, buttonEventType, modifiers);
+ window2, timestamp, localPoint, globalPoint, pressedButtons, button, buttonEventType, modifiers);
}
}
@@ -675,11 +675,13 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh
QWasmEventTranslator *translator = (QWasmEventTranslator*)userData;
Qt::KeyboardModifiers modifiers = translator->translateMouseEventModifier(&mouseEvent);
auto timestamp = mouseEvent.timestamp;
- QPoint globalPoint(mouseEvent.canvasX, mouseEvent.canvasY);
+ QPoint targetPoint(mouseEvent.targetX, mouseEvent.targetY);
+ QPoint globalPoint = eventTranslator->screen()->geometry().topLeft() + targetPoint;
QWindow *window2 = eventTranslator->screen()->compositor()->windowAt(globalPoint, 5);
-
- QPoint localPoint(globalPoint.x() - window2->geometry().x(), globalPoint.y() - window2->geometry().y());
+ if (!window2)
+ return 0;
+ QPoint localPoint = window2->mapFromGlobal(globalPoint);
QPoint pixelDelta;
@@ -709,24 +711,28 @@ int QWasmEventTranslator::handleTouch(int eventType, const EmscriptenTouchEvent
const EmscriptenTouchPoint *touches = &touchEvent->touches[i];
- QPoint point(touches->targetX, touches->targetY);
- window2 = this->screen()->compositor()->windowAt(point, 5);
+ QPoint targetPoint(touches->targetX, touches->targetY);
+ QPoint globalPoint = screen()->geometry().topLeft() + targetPoint;
+
+ window2 = this->screen()->compositor()->windowAt(globalPoint, 5);
+ if (window2 == nullptr)
+ continue;
+
QWindowSystemInterface::TouchPoint touchPoint;
touchPoint.area = QRect(0, 0, 8, 8);
touchPoint.id = touches->identifier;
touchPoint.pressure = 1.0;
- const QPointF screenPos(point);
-
- touchPoint.area.moveCenter(screenPos);
+ touchPoint.area.moveCenter(globalPoint);
const auto tp = pressedTouchIds.constFind(touchPoint.id);
if (tp != pressedTouchIds.constEnd())
touchPoint.normalPosition = tp.value();
- QPointF normalPosition(screenPos.x() / window2->width(),
- screenPos.y() / window2->height());
+ QPointF localPoint = QPointF(window2->mapFromGlobal(globalPoint));
+ QPointF normalPosition(localPoint.x() / window2->width(),
+ localPoint.y() / window2->height());
const bool stationaryTouchPoint = (normalPosition == touchPoint.normalPosition);
touchPoint.normalPosition = normalPosition;
diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp
index 1964cefdad..e601d553f2 100644
--- a/src/plugins/platforms/wasm/qwasmintegration.cpp
+++ b/src/plugins/platforms/wasm/qwasmintegration.cpp
@@ -34,6 +34,7 @@
#include "qwasmopenglcontext.h"
#include "qwasmtheme.h"
#include "qwasmclipboard.h"
+#include "qwasmservices.h"
#include "qwasmwindow.h"
#ifndef QT_NO_OPENGL
@@ -56,21 +57,42 @@
using namespace emscripten;
QT_BEGIN_NAMESPACE
-void browserBeforeUnload(emscripten::val)
+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 void removeCanvasElement(emscripten::val canvas)
+{
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ QWasmIntegration::get()->removeScreen(canvasId);
+}
+
+static void resizeCanvasElement(emscripten::val canvas)
+{
+ QString canvasId = QString::fromStdString(canvas["id"].as<std::string>());
+ QWasmIntegration::get()->resizeScreen(canvasId);
+}
+
+EMSCRIPTEN_BINDINGS(qtQWasmIntegraton)
+{
+ function("qtBrowserBeforeUnload", &browserBeforeUnload);
+ function("qtAddCanvasElement", &addCanvasElement);
+ function("qtRemoveCanvasElement", &removeCanvasElement);
+ function("qtResizeCanvasElement", &resizeCanvasElement);
}
QWasmIntegration *QWasmIntegration::s_instance;
QWasmIntegration::QWasmIntegration()
: m_fontDb(nullptr),
- m_eventDispatcher(nullptr),
+ m_desktopServices(nullptr),
m_clipboard(new QWasmClipboard)
{
s_instance = this;
@@ -92,13 +114,18 @@ QWasmIntegration::QWasmIntegration()
addScreen(canvasId);
}
- emscripten::val::global("window").set("onbeforeunload", val::module_property("browserBeforeUnload"));
+ emscripten::val::global("window").set("onbeforeunload", val::module_property("qtBrowserBeforeUnload"));
}
QWasmIntegration::~QWasmIntegration()
{
delete m_fontDb;
- qDeleteAll(m_screens);
+ delete m_desktopServices;
+
+ for (auto it = m_screens.constBegin(); it != m_screens.constEnd(); ++it)
+ QWindowSystemInterface::handleScreenRemoved(*it);
+ m_screens.clear();
+
s_instance = nullptr;
}
@@ -113,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;
@@ -161,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");
@@ -176,22 +215,34 @@ QPlatformTheme *QWasmIntegration::createPlatformTheme(const QString &name) const
return QPlatformIntegration::createPlatformTheme(name);
}
-QPlatformClipboard* QWasmIntegration::clipboard() const
+QPlatformServices *QWasmIntegration::services() const
{
- return m_clipboard;
+ if (m_desktopServices == nullptr)
+ m_desktopServices = new QWasmServices();
+ return m_desktopServices;
}
-QVector<QWasmScreen *> QWasmIntegration::screens()
+QPlatformClipboard* QWasmIntegration::clipboard() const
{
- return m_screens;
+ return m_clipboard;
}
void QWasmIntegration::addScreen(const QString &canvasId)
{
QWasmScreen *screen = new QWasmScreen(canvasId);
m_clipboard->installEventHandlers(canvasId);
- m_screens.append(screen);
- screenAdded(screen);
+ m_screens.insert(canvasId, screen);
+ QWindowSystemInterface::handleScreenAdded(screen);
+}
+
+void QWasmIntegration::removeScreen(const QString &canvasId)
+{
+ QWindowSystemInterface::handleScreenRemoved(m_screens.take(canvasId));
+}
+
+void QWasmIntegration::resizeScreen(const QString &canvasId)
+{
+ m_screens.value(canvasId)->updateQScreenAndCanvasRenderSize();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h
index 5c0ac0b297..11d8d0f7f5 100644
--- a/src/plugins/platforms/wasm/qwasmintegration.h
+++ b/src/plugins/platforms/wasm/qwasmintegration.h
@@ -50,6 +50,7 @@ class QWasmScreen;
class QWasmCompositor;
class QWasmBackingStore;
class QWasmClipboard;
+class QWasmServices;
class QWasmIntegration : public QObject, public QPlatformIntegration
{
@@ -67,24 +68,26 @@ public:
QPlatformFontDatabase *fontDatabase() const override;
QAbstractEventDispatcher *createEventDispatcher() const override;
QVariant styleHint(QPlatformIntegration::StyleHint hint) const override;
+ Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const override;
QStringList themeNames() const override;
QPlatformTheme *createPlatformTheme(const QString &name) const override;
+ QPlatformServices *services() const override;
QPlatformClipboard *clipboard() const override;
-
- QVector<QWasmScreen *>screens();
QWasmClipboard *getWasmClipboard() { return m_clipboard; }
static QWasmIntegration *get() { return s_instance; }
static void QWasmBrowserExit();
-private:
void addScreen(const QString &canvasId);
+ void removeScreen(const QString &canvasId);
+ void resizeScreen(const QString &canvasId);
+private:
mutable QWasmFontDatabase *m_fontDb;
- mutable QWasmEventDispatcher *m_eventDispatcher;
+ mutable QWasmServices *m_desktopServices;
mutable QHash<QWindow *, QWasmBackingStore *> m_backingStores;
- QVector<QWasmScreen *> m_screens;
+ QHash<QString, QWasmScreen *> m_screens;
mutable QWasmClipboard *m_clipboard;
static QWasmIntegration *s_instance;
};
diff --git a/src/plugins/platforms/wasm/qwasmservices.cpp b/src/plugins/platforms/wasm/qwasmservices.cpp
new file mode 100644
index 0000000000..9328b8c065
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmservices.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwasmservices.h"
+#include <QtCore/QUrl>
+#include <QtCore/QDebug>
+
+#include <emscripten/val.h>
+
+QT_BEGIN_NAMESPACE
+
+bool QWasmServices::openUrl(const QUrl &url)
+{
+ QByteArray utf8Url = url.toString().toUtf8();
+ emscripten::val::global("window").call<void>("open", emscripten::val(utf8Url.constData()), emscripten::val("_blank"));
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmservices.h b/src/plugins/platforms/wasm/qwasmservices.h
new file mode 100644
index 0000000000..3b37f21f82
--- /dev/null
+++ b/src/plugins/platforms/wasm/qwasmservices.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 or (at your option) any later version
+** approved by the KDE Free Qt Foundation. The licenses are as published by
+** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWASMDESKTOPSERVICES_H
+#define QWASMDESKTOPSERVICES_H
+
+#include <qpa/qplatformservices.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWasmServices : public QPlatformServices
+{
+public:
+ bool openUrl(const QUrl &url) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWASMDESKTOPSERVICES_H
diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro
index 5aa6dfccf3..9b98445c68 100644
--- a/src/plugins/platforms/wasm/wasm.pro
+++ b/src/plugins/platforms/wasm/wasm.pro
@@ -19,7 +19,8 @@ SOURCES = \
qwasmcursor.cpp \
qwasmopenglcontext.cpp \
qwasmtheme.cpp \
- qwasmclipboard.cpp
+ qwasmclipboard.cpp \
+ qwasmservices.cpp
HEADERS = \
qwasmintegration.h \
@@ -33,7 +34,8 @@ HEADERS = \
qwasmcursor.h \
qwasmopenglcontext.h \
qwasmtheme.h \
- qwasmclipboard.h
+ qwasmclipboard.h \
+ qwasmservices.h
wasmfonts.files = \
../../../3rdparty/wasm/Vera.ttf \
diff --git a/src/plugins/platforms/wasm/wasm_shell.html b/src/plugins/platforms/wasm/wasm_shell.html
index 39bb711b6b..f7c856d63d 100644
--- a/src/plugins/platforms/wasm/wasm_shell.html
+++ b/src/plugins/platforms/wasm/wasm_shell.html
@@ -11,7 +11,7 @@
/* The contenteditable property is set to true for the canvas in order to support
clipboard events. Hide the resulting focus frame and set the cursor back to
the default cursor. */
- canvas { outline: 0px solid transparent; cursor:default }
+ canvas { outline: 0px solid transparent; caret-color: transparent; cursor:default }
</style>
</head>
<body onload="init()">
@@ -27,9 +27,9 @@
<script type='text/javascript'>
function init() {
- var spinner = document.getElementById('qtspinner');
- var canvas = document.getElementById('qtcanvas');
- var status = document.getElementById('qtstatus')
+ var spinner = document.querySelector('#qtspinner');
+ var canvas = document.querySelector('#qtcanvas');
+ var status = document.querySelector('#qtstatus')
var qtLoader = QtLoader({
canvasElements : [canvas],