diff options
Diffstat (limited to 'src/plugins/platforms/wasm')
-rw-r--r-- | src/plugins/platforms/wasm/qwasmclipboard.cpp | 5 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmclipboard.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmcursor.cpp | 4 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmeventtranslator.cpp | 29 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmintegration.cpp | 69 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmintegration.h | 10 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmopenglcontext.cpp | 3 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmscreen.cpp | 33 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmscreen.h | 7 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmstring.cpp | 5 |
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; } |