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 <lorn.potter@gmail.com>
This commit is contained in:
Morten Johan Sørvig 2020-05-29 14:05:29 +02:00
parent d7205a7cae
commit 1b4a5af63f
2 changed files with 45 additions and 0 deletions

View File

@ -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<void>("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<int>();
if (count == 0)
return;
emscripten::val entry = entries[0];
QWasmScreen *screen =
reinterpret_cast<QWasmScreen *>(entry["target"][m_canvasResizeObserverCallbackContextPropertyName].as<intptr_t>());
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<void>("observe", m_canvas);
}
QT_END_NAMESPACE

View File

@ -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