summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2020-02-02 01:22:24 +0100
committerMorten Johan Sørvig <morten.sorvig@qt.io>2020-02-12 14:50:47 +0000
commit2b0af50c8ba534a6032a31297f1915b50a100241 (patch)
treeb61daeccd0e857147ccbc0d7f83a71ad6060c98b /src
parente290ebae9ff2fe6064fdf2f5107221faff04f28b (diff)
wasm: store and pass canvases as emscripten::val
Store and pass canvases as emscripten::val instead of a QString containing the element id. This simplifies code which interacts with the canvas using the emscripten::val API, by removing the need to look up with getElementById. The Emscripten C event API does not accept emscripten::val, and using the element id is still needed here. emscripten::val does not provide a hash key suitable for use with QHash, but does provide an equality-compare in the form of val::equals(). Change the canvas->screen mapping code to use a QVector instead of a QHash. Change-Id: I1dbdbbc8fb06bb869031f1500e83ae2d64780a7f Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
Diffstat (limited to 'src')
-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.cpp4
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.cpp58
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.h10
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.cpp31
-rw-r--r--src/plugins/platforms/wasm/qwasmscreen.h7
8 files changed, 63 insertions, 59 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 62ada796db..3e6043b083 100644
--- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
+++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp
@@ -354,9 +354,7 @@ 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"));
diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp
index 9934f5ac19..45bc49e382 100644
--- a/src/plugins/platforms/wasm/qwasmintegration.cpp
+++ b/src/plugins/platforms/wasm/qwasmintegration.cpp
@@ -68,20 +68,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()
@@ -114,15 +111,12 @@ QWasmIntegration::QWasmIntegration()
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()) {
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.";
- QString canvasId = QWasmString::toQString(canvas["id"]);
- addScreen(canvasId);
+ addScreen(canvas);
}
emscripten::val::global("window").set("onbeforeunload", val::module_property("qtBrowserBeforeUnload"));
@@ -148,8 +142,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;
@@ -271,24 +265,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()
@@ -297,15 +304,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/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp
index ba14421255..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 canvasSelector = "#" + m_canvasId.toUtf8();
+ QByteArray canvasSelector = "#" + canvasId().toUtf8();
double css_width;
double 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);