summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2020-02-13 09:14:09 +0100
committerAlexandru Croitor <alexandru.croitor@qt.io>2020-02-13 18:31:40 +0100
commit6b2535ea15cdbdb2355416b604f072fc13ff36b2 (patch)
tree4bf1560bab77c8b315850c5337ba31a0ea87b5f0 /src/plugins/platforms/wasm
parent54c2cebabdda0280b8443c6947b6fee02445e138 (diff)
parent67491e2df5357706dbf88ddaf1f030ff095b4528 (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts: examples/widgets/graphicsview/boxes/scene.h src/corelib/Qt5CoreMacros.cmake src/corelib/Qt6CoreMacros.cmake src/network/ssl/qsslsocket.cpp src/network/ssl/qsslsocket.h src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp src/testlib/CMakeLists.txt src/testlib/.prev_CMakeLists.txt tests/auto/corelib/tools/qscopeguard/tst_qscopeguard.cpp Disabled building manual tests with CMake for now, because qmake doesn't do it, and it confuses people. Done-With: Alexandru Croitor <alexandru.croitor@qt.io> Done-With: Volker Hilsheimer <volker.hilsheimer@qt.io> Change-Id: I865ae347bd01f4e59f16d007b66d175a52f1f152
Diffstat (limited to 'src/plugins/platforms/wasm')
-rw-r--r--src/plugins/platforms/wasm/qwasmclipboard.cpp5
-rw-r--r--src/plugins/platforms/wasm/qwasmclipboard.h3
-rw-r--r--src/plugins/platforms/wasm/qwasmcursor.cpp4
-rw-r--r--src/plugins/platforms/wasm/qwasmeventtranslator.cpp29
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.cpp69
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.h10
-rw-r--r--src/plugins/platforms/wasm/qwasmopenglcontext.cpp3
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp33
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.h7
-rw-r--r--src/plugins/platforms/wasm/qwasmstring.cpp5
10 files changed, 87 insertions, 81 deletions
diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp
index f02c2c6ccb..890b01fa3c 100644
--- a/src/plugins/platforms/wasm/qwasmclipboard.cpp
+++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp
@@ -192,15 +192,12 @@ void QWasmClipboard::initClipboardEvents()
permissions.call<val>("query", writePermissionsMap);
}
-void QWasmClipboard::installEventHandlers(const QString &canvasId)
+void QWasmClipboard::installEventHandlers(const emscripten::val &canvas)
{
if (hasClipboardApi)
return;
// Fallback path for browsers which do not support direct clipboard access
- val document = val::global("document");
- val canvas = document.call<val>("getElementById", QWasmString::fromQString(canvasId));
-
canvas.call<void>("addEventListener", val("cut"),
val::module_property("qtClipboardCutTo"));
canvas.call<void>("addEventListener", val("copy"),
diff --git a/src/plugins/platforms/wasm/qwasmclipboard.h b/src/plugins/platforms/wasm/qwasmclipboard.h
index 00aae8fead..3b28e2c381 100644
--- a/src/plugins/platforms/wasm/qwasmclipboard.h
+++ b/src/plugins/platforms/wasm/qwasmclipboard.h
@@ -36,6 +36,7 @@
#include <QMimeData>
#include <emscripten/bind.h>
+#include <emscripten/val.h>
class QWasmClipboard : public QObject, public QPlatformClipboard
{
@@ -51,7 +52,7 @@ public:
static void qWasmClipboardPaste(QMimeData *mData);
void initClipboardEvents();
- void installEventHandlers(const QString &canvasId);
+ void installEventHandlers(const emscripten::val &canvas);
bool hasClipboardApi;
void readTextFromClipboard();
void writeTextToClipboard();
diff --git a/src/plugins/platforms/wasm/qwasmcursor.cpp b/src/plugins/platforms/wasm/qwasmcursor.cpp
index 616456b2fa..61204517ce 100644
--- a/src/plugins/platforms/wasm/qwasmcursor.cpp
+++ b/src/plugins/platforms/wasm/qwasmcursor.cpp
@@ -57,9 +57,7 @@ void QWasmCursor::changeCursor(QCursor *windowCursor, QWindow *window)
htmlCursorName = "auto";
// Set cursor on the canvas
- val jsCanvasId = QWasmString::fromQString(QWasmScreen::get(screen)->canvasId());
- val document = val::global("document");
- val canvas = document.call<val>("getElementById", jsCanvasId);
+ val canvas = QWasmScreen::get(screen)->canvas();
val canvasStyle = canvas["style"];
canvasStyle.set("cursor", val(htmlCursorName.constData()));
}
diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
index d99c202c48..3e6043b083 100644
--- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
+++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
@@ -339,8 +339,7 @@ QWasmEventTranslator::QWasmEventTranslator(QWasmScreen *screen)
void QWasmEventTranslator::initEventHandlers()
{
- QByteArray _canvasId = screen()->canvasId().toUtf8();
- const char *canvasId = _canvasId.constData();
+ QByteArray canvasSelector = "#" + screen()->canvasId().toUtf8();
// The Platform Detect: expand coverage and move as needed
enum Platform {
@@ -355,30 +354,28 @@ void QWasmEventTranslator::initEventHandlers()
g_useNaturalScrolling = false; // make this !default on macOS
if (emscripten::val::global("window")["safari"].isUndefined()) {
- val document = val::global("document");
- val jsCanvasId = QWasmString::fromQString(screen()->canvasId());
- val canvas = document.call<val>("getElementById", jsCanvasId);
+ val canvas = screen()->canvas();
canvas.call<void>("addEventListener",
val("wheel"),
val::module_property("qtMouseWheelEvent"));
}
}
- emscripten_set_keydown_callback(canvasId, (void *)this, 1, &keyboard_cb);
- emscripten_set_keyup_callback(canvasId, (void *)this, 1, &keyboard_cb);
+ emscripten_set_keydown_callback(canvasSelector.constData(), (void *)this, 1, &keyboard_cb);
+ emscripten_set_keyup_callback(canvasSelector.constData(), (void *)this, 1, &keyboard_cb);
- emscripten_set_mousedown_callback(canvasId, (void *)this, 1, &mouse_cb);
- emscripten_set_mouseup_callback(canvasId, (void *)this, 1, &mouse_cb);
- emscripten_set_mousemove_callback(canvasId, (void *)this, 1, &mouse_cb);
+ emscripten_set_mousedown_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb);
+ emscripten_set_mouseup_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb);
+ emscripten_set_mousemove_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb);
- emscripten_set_focus_callback(canvasId, (void *)this, 1, &focus_cb);
+ emscripten_set_focus_callback(canvasSelector.constData(), (void *)this, 1, &focus_cb);
- emscripten_set_wheel_callback(canvasId, (void *)this, 1, &wheel_cb);
+ emscripten_set_wheel_callback(canvasSelector.constData(), (void *)this, 1, &wheel_cb);
- emscripten_set_touchstart_callback(canvasId, (void *)this, 1, &touchCallback);
- emscripten_set_touchend_callback(canvasId, (void *)this, 1, &touchCallback);
- emscripten_set_touchmove_callback(canvasId, (void *)this, 1, &touchCallback);
- emscripten_set_touchcancel_callback(canvasId, (void *)this, 1, &touchCallback);
+ emscripten_set_touchstart_callback(canvasSelector.constData(), (void *)this, 1, &touchCallback);
+ emscripten_set_touchend_callback(canvasSelector.constData(), (void *)this, 1, &touchCallback);
+ emscripten_set_touchmove_callback(canvasSelector.constData(), (void *)this, 1, &touchCallback);
+ emscripten_set_touchcancel_callback(canvasSelector.constData(), (void *)this, 1, &touchCallback);
}
template <typename Event>
diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp
index ce83ad4e2f..d1901d840e 100644
--- a/src/plugins/platforms/wasm/qwasmintegration.cpp
+++ b/src/plugins/platforms/wasm/qwasmintegration.cpp
@@ -69,20 +69,17 @@ static void browserBeforeUnload(emscripten::val)
static void addCanvasElement(emscripten::val canvas)
{
- QString canvasId = QWasmString::toQString(canvas["id"]);
- QWasmIntegration::get()->addScreen(canvasId);
+ QWasmIntegration::get()->addScreen(canvas);
}
static void removeCanvasElement(emscripten::val canvas)
{
- QString canvasId = QWasmString::toQString(canvas["id"]);
- QWasmIntegration::get()->removeScreen(canvasId);
+ QWasmIntegration::get()->removeScreen(canvas);
}
static void resizeCanvasElement(emscripten::val canvas)
{
- QString canvasId = QWasmString::toQString(canvas["id"]);
- QWasmIntegration::get()->resizeScreen(canvasId);
+ QWasmIntegration::get()->resizeScreen(canvas);
}
static void qtUpdateDpi()
@@ -109,20 +106,18 @@ QWasmIntegration::QWasmIntegration()
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");
+ emscripten::val canvas = val::module_property("canvas"); // TODO: remove for Qt 6.0
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 = QWasmString::toQString(canvas["id"]);
- addScreen(canvasId);
+ addScreen(qtCanvaseElements[i].as<emscripten::val>());
}
- } else if (!canvas.isUndefined()){
- QString canvasId = QWasmString::toQString(canvas["id"]);
- addScreen(canvasId);
+ } else if (!canvas.isUndefined()) {
+ qWarning() << "Module.canvas is deprecated. A future version of Qt will stop reading this property. "
+ << "Instead, set Module.qtCanvasElements to be an array of canvas elements, or use qtloader.js.";
+ addScreen(canvas);
}
emscripten::val::global("window").set("onbeforeunload", val::module_property("qtBrowserBeforeUnload"));
@@ -134,13 +129,13 @@ QWasmIntegration::QWasmIntegration()
Q_UNUSED(userData);
// This resize event is called when the HTML window is resized. Depending
- // on the page layout the the canvas(es) might also have been resized, so we
+ // on the page layout the canvas(es) might also have been resized, so we
// update the Qt screen sizes (and canvas render sizes).
if (QWasmIntegration *integration = QWasmIntegration::get())
integration->resizeAllScreens();
return 0;
};
- emscripten_set_resize_callback(nullptr, nullptr, 1, onWindowResize);
+ emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, nullptr, 1, onWindowResize);
}
QWasmIntegration::~QWasmIntegration()
@@ -148,8 +143,8 @@ QWasmIntegration::~QWasmIntegration()
delete m_fontDb;
delete m_desktopServices;
- for (auto it = m_screens.constBegin(); it != m_screens.constEnd(); ++it)
- QWindowSystemInterface::handleScreenRemoved(*it);
+ for (const auto &canvasAndScreen : m_screens)
+ QWindowSystemInterface::handleScreenRemoved(canvasAndScreen.second);
m_screens.clear();
s_instance = nullptr;
@@ -272,24 +267,37 @@ QPlatformClipboard* QWasmIntegration::clipboard() const
return m_clipboard;
}
-void QWasmIntegration::addScreen(const QString &canvasId)
+void QWasmIntegration::addScreen(const emscripten::val &canvas)
{
- QWasmScreen *screen = new QWasmScreen(canvasId);
- m_clipboard->installEventHandlers(canvasId);
- m_screens.insert(canvasId, screen);
+ QWasmScreen *screen = new QWasmScreen(canvas);
+ m_screens.append(qMakePair(canvas, screen));
+ m_clipboard->installEventHandlers(canvas);
QWindowSystemInterface::handleScreenAdded(screen);
}
-void QWasmIntegration::removeScreen(const QString &canvasId)
+void QWasmIntegration::removeScreen(const emscripten::val &canvas)
{
- QWasmScreen *exScreen = m_screens.take(canvasId);
+ auto it = std::find_if(m_screens.begin(), m_screens.end(),
+ [&] (const QPair<emscripten::val, QWasmScreen *> &candidate) { return candidate.first.equals(canvas); });
+ if (it == m_screens.end()) {
+ qWarning() << "Attempting to remove non-existing screen for canvas" << QWasmString::toQString(canvas["id"]);;
+ return;
+ }
+ QWasmScreen *exScreen = it->second;
+ m_screens.erase(it);
exScreen->destroy(); // clean up before deleting the screen
QWindowSystemInterface::handleScreenRemoved(exScreen);
}
-void QWasmIntegration::resizeScreen(const QString &canvasId)
+void QWasmIntegration::resizeScreen(const emscripten::val &canvas)
{
- m_screens.value(canvasId)->updateQScreenAndCanvasRenderSize();
+ auto it = std::find_if(m_screens.begin(), m_screens.end(),
+ [&] (const QPair<emscripten::val, QWasmScreen *> &candidate) { return candidate.first.equals(canvas); });
+ if (it == m_screens.end()) {
+ qWarning() << "Attempting to resize non-existing screen for canvas" << QWasmString::toQString(canvas["id"]);;
+ return;
+ }
+ it->second->updateQScreenAndCanvasRenderSize();
}
void QWasmIntegration::updateDpi()
@@ -298,15 +306,14 @@ void QWasmIntegration::updateDpi()
if (dpi.isUndefined())
return;
qreal dpiValue = dpi.as<qreal>();
- for (QWasmScreen *screen : m_screens)
- QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen->screen(), dpiValue, dpiValue);
+ for (const auto &canvasAndScreen : m_screens)
+ QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(canvasAndScreen.second->screen(), dpiValue, dpiValue);
}
void QWasmIntegration::resizeAllScreens()
{
- qDebug() << "resizeAllScreens";
- for (QWasmScreen *screen : m_screens)
- screen->updateQScreenAndCanvasRenderSize();
+ for (const auto &canvasAndScreen : m_screens)
+ canvasAndScreen.second->updateQScreenAndCanvasRenderSize();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h
index 2102f5c226..08b68cb5f7 100644
--- a/src/plugins/platforms/wasm/qwasmintegration.h
+++ b/src/plugins/platforms/wasm/qwasmintegration.h
@@ -40,6 +40,7 @@
#include <emscripten.h>
#include <emscripten/html5.h>
+#include <emscripten/val.h>
QT_BEGIN_NAMESPACE
@@ -83,9 +84,9 @@ public:
static QWasmIntegration *get() { return s_instance; }
static void QWasmBrowserExit();
- void addScreen(const QString &canvasId);
- void removeScreen(const QString &canvasId);
- void resizeScreen(const QString &canvasId);
+ void addScreen(const emscripten::val &canvas);
+ void removeScreen(const emscripten::val &canvas);
+ void resizeScreen(const emscripten::val &canvas);
void resizeAllScreens();
void updateDpi();
@@ -93,8 +94,7 @@ private:
mutable QWasmFontDatabase *m_fontDb;
mutable QWasmServices *m_desktopServices;
mutable QHash<QWindow *, QWasmBackingStore *> m_backingStores;
-
- QHash<QString, QWasmScreen *> m_screens;
+ QVector<QPair<emscripten::val, QWasmScreen *>> m_screens;
mutable QWasmClipboard *m_clipboard;
qreal m_fontDpi = -1;
mutable QScopedPointer<QPlatformInputContext> m_inputContext;
diff --git a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
index 501ab99116..4ddd56fd8c 100644
--- a/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
+++ b/src/plugins/platforms/wasm/qwasmopenglcontext.cpp
@@ -106,7 +106,8 @@ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE QWasmOpenGLContext::createEmscriptenContext(cons
attributes.depth = useDepthStencil;
attributes.stencil = useDepthStencil;
- EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(canvasId.toUtf8().constData(), &attributes);
+ QByteArray convasSelector = "#" + canvasId.toUtf8();
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(convasSelector.constData(), &attributes);
return context;
}
diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
index 5e6f94b9ed..a2bcd4fcb4 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.cpp
+++ b/src/plugins/platforms/wasm/qwasmscreen.cpp
@@ -50,15 +50,13 @@ using namespace emscripten;
QT_BEGIN_NAMESPACE
-QWasmScreen::QWasmScreen(const QString &canvasId)
- : m_canvasId(canvasId)
-
+QWasmScreen::QWasmScreen(const emscripten::val &canvas)
+ : m_canvas(canvas)
{
m_compositor = new QWasmCompositor(this);
m_eventTranslator = new QWasmEventTranslator(this);
updateQScreenAndCanvasRenderSize();
- emscripten::val canvas = emscripten::val::global(m_canvasId.toUtf8().constData());
- canvas.call<void>("focus");
+ m_canvas.call<void>("focus");
}
QWasmScreen::~QWasmScreen()
@@ -91,9 +89,14 @@ QWasmEventTranslator *QWasmScreen::eventTranslator()
return m_eventTranslator;
}
+emscripten::val QWasmScreen::canvas() const
+{
+ return m_canvas;
+}
+
QString QWasmScreen::canvasId() const
{
- return m_canvasId;
+ return QWasmString::toQString(m_canvas["id"]);
}
QRect QWasmScreen::geometry() const
@@ -134,7 +137,7 @@ qreal QWasmScreen::devicePixelRatio() const
QString QWasmScreen::name() const
{
- return m_canvasId;
+ return canvasId();
}
QPlatformCursor *QWasmScreen::cursor() const
@@ -180,24 +183,22 @@ void QWasmScreen::updateQScreenAndCanvasRenderSize()
// Setting the render size to a value larger than the CSS size enables high-dpi
// rendering.
- QByteArray canvasId = m_canvasId.toUtf8();
+ QByteArray canvasSelector = "#" + canvasId().toUtf8();
double css_width;
double css_height;
- emscripten_get_element_css_size(canvasId.constData(), &css_width, &css_height);
+ emscripten_get_element_css_size(canvasSelector.constData(), &css_width, &css_height);
QSizeF cssSize(css_width, css_height);
QSizeF canvasSize = cssSize * devicePixelRatio();
- val document = val::global("document");
- val canvas = document.call<val>("getElementById", QWasmString::fromQString(m_canvasId));
- canvas.set("width", canvasSize.width());
- canvas.set("height", canvasSize.height());
+ m_canvas.set("width", canvasSize.width());
+ m_canvas.set("height", canvasSize.height());
QPoint offset;
- offset.setX(canvas["offsetTop"].as<int>());
- offset.setY(canvas["offsetLeft"].as<int>());
+ offset.setX(m_canvas["offsetTop"].as<int>());
+ offset.setY(m_canvas["offsetLeft"].as<int>());
- emscripten::val rect = canvas.call<emscripten::val>("getBoundingClientRect");
+ emscripten::val rect = m_canvas.call<emscripten::val>("getBoundingClientRect");
QPoint position(rect["left"].as<int>() - offset.x(), rect["top"].as<int>() - offset.y());
setGeometry(QRect(position, cssSize.toSize()));
diff --git a/src/plugins/platforms/wasm/qwasmscreen.h b/src/plugins/platforms/wasm/qwasmscreen.h
index fcf693681c..ea7ffc4193 100644
--- a/src/plugins/platforms/wasm/qwasmscreen.h
+++ b/src/plugins/platforms/wasm/qwasmscreen.h
@@ -37,6 +37,8 @@
#include <QtCore/qscopedpointer.h>
#include <QtCore/qtextstream.h>
+#include <emscripten/val.h>
+
QT_BEGIN_NAMESPACE
class QPlatformOpenGLContext;
@@ -50,12 +52,13 @@ class QWasmScreen : public QObject, public QPlatformScreen
{
Q_OBJECT
public:
- QWasmScreen(const QString &canvasId);
+ QWasmScreen(const emscripten::val &canvas);
~QWasmScreen();
void destroy();
static QWasmScreen *get(QPlatformScreen *screen);
static QWasmScreen *get(QScreen *screen);
+ emscripten::val canvas() const;
QString canvasId() const;
QWasmCompositor *compositor();
@@ -80,7 +83,7 @@ public slots:
void setGeometry(const QRect &rect);
private:
- QString m_canvasId;
+ emscripten::val m_canvas;
QWasmCompositor *m_compositor = nullptr;
QWasmEventTranslator *m_eventTranslator = nullptr;
QRect m_geometry = QRect(0, 0, 100, 100);
diff --git a/src/plugins/platforms/wasm/qwasmstring.cpp b/src/plugins/platforms/wasm/qwasmstring.cpp
index 05b571c459..b1be405eeb 100644
--- a/src/plugins/platforms/wasm/qwasmstring.cpp
+++ b/src/plugins/platforms/wasm/qwasmstring.cpp
@@ -52,9 +52,10 @@ QString QWasmString::toQString(const val &v)
val::global("Module")["stringToUTF16"]);
static const val length("length");
- result.resize(v[length].as<int>());
+ int len = v[length].as<int>();
+ result.resize(len);
auto ptr = quintptr(result.utf16());
- stringToUTF16(v, val(ptr));
+ stringToUTF16(v, val(ptr), val((len + 1) * 2));
return result;
}