From 1b4a5af63f984a7eef40761e25f27cb5785c2351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 29 May 2020 14:05:29 +0200 Subject: wasm: detect canvas resize using ResizeObserver API The ResizeObserver API is now available on the major desktop browsers (Safari, Chrome, Firefox), and can be used to handle canvas resize. (Previously, we got a callback on viewport resize only) Pick-to: 5.15 Change-Id: I8737285416bef70641f90da793c85efcb24f3623 Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmscreen.cpp | 42 ++++++++++++++++++++++++++++++ src/plugins/platforms/wasm/qwasmscreen.h | 3 +++ 2 files changed, 45 insertions(+) (limited to 'src/plugins/platforms/wasm') diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp index be9d35cdef..7b1fc0d42e 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.cpp +++ b/src/plugins/platforms/wasm/qwasmscreen.cpp @@ -50,17 +50,21 @@ using namespace emscripten; QT_BEGIN_NAMESPACE +const char * QWasmScreen::m_canvasResizeObserverCallbackContextPropertyName = "data-qtCanvasResizeObserverCallbackContext"; + QWasmScreen::QWasmScreen(const emscripten::val &canvas) : m_canvas(canvas) { m_compositor = new QWasmCompositor(this); m_eventTranslator = new QWasmEventTranslator(this); + installCanvasResizeObserver(); updateQScreenAndCanvasRenderSize(); m_canvas.call("focus"); } QWasmScreen::~QWasmScreen() { + m_canvas.set(m_canvasResizeObserverCallbackContextPropertyName, emscripten::val(intptr_t(0))); destroy(); } @@ -216,4 +220,42 @@ void QWasmScreen::updateQScreenAndCanvasRenderSize() m_compositor->redrawWindowContent(); } +void QWasmScreen::canvasResizeObserverCallback(emscripten::val entries, emscripten::val) +{ + int count = entries["length"].as(); + if (count == 0) + return; + emscripten::val entry = entries[0]; + QWasmScreen *screen = + reinterpret_cast(entry["target"][m_canvasResizeObserverCallbackContextPropertyName].as()); + if (!screen) { + qWarning() << "QWasmScreen::canvasResizeObserverCallback: missing screen pointer"; + return; + } + + // We could access contentBoxSize|contentRect|devicePixelContentBoxSize on the entry here, but + // these are not universally supported across all browsers. Get the sizes from the canvas instead. + screen->updateQScreenAndCanvasRenderSize(); +} + +EMSCRIPTEN_BINDINGS(qtCanvasResizeObserverCallback) { + emscripten::function("qtCanvasResizeObserverCallback", &QWasmScreen::canvasResizeObserverCallback); +} + +void QWasmScreen::installCanvasResizeObserver() +{ + emscripten::val ResizeObserver = emscripten::val::global("ResizeObserver"); + if (ResizeObserver == emscripten::val::undefined()) + return; // ResizeObserver API is not available + emscripten::val resizeObserver = ResizeObserver.new_(emscripten::val::module_property("qtCanvasResizeObserverCallback")); + if (resizeObserver == emscripten::val::undefined()) + return; // Something went horribly wrong + + // We need to get back to this instance from the (static) resize callback; + // set a "data-" property on the canvas element. + m_canvas.set(m_canvasResizeObserverCallbackContextPropertyName, emscripten::val(intptr_t(this))); + + resizeObserver.call("observe", m_canvas); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmscreen.h b/src/plugins/platforms/wasm/qwasmscreen.h index ea7ffc4193..14d5a2f7d1 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.h +++ b/src/plugins/platforms/wasm/qwasmscreen.h @@ -78,6 +78,8 @@ public: void invalidateSize(); void updateQScreenAndCanvasRenderSize(); + void installCanvasResizeObserver(); + static void canvasResizeObserverCallback(emscripten::val entries, emscripten::val); public slots: void setGeometry(const QRect &rect); @@ -90,6 +92,7 @@ private: int m_depth = 32; QImage::Format m_format = QImage::Format_RGB32; QWasmCursor m_cursor; + static const char * m_canvasResizeObserverCallbackContextPropertyName; }; QT_END_NAMESPACE -- cgit v1.2.3