wasm: reliably determine QScreen position

Fix bug where QWindow content would be drawn with an
offset from the QScreen’s topLeft if the page was scrolled.

On Qt for WebAssembly, screen geometry is equivalent
to canvas geometry, where the canvas position is the
position of the canvas on the document body.

getBoundingClientRect() is the correct function to use
here, however it returns a rect relative to the viewport.
Offsetting this rect by offsetLeft/Top can work in some
bases, but this offset is relative to HTMLElement.offsetParent
and not necessarily to the document body.

Determine the correct QScreen position by subtracting
the body position from the canvas position (both relative
to the viewport).

Change-Id: Ifb7fd28adedbf997d63f79f9b626cfcf3664ff54
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
This commit is contained in:
Morten Johan Sørvig 2022-02-14 17:19:40 +01:00
parent 17c7af722c
commit 738a11eeac

View File

@ -226,14 +226,15 @@ void QWasmScreen::updateQScreenAndCanvasRenderSize()
m_canvas.set("width", canvasSize.width());
m_canvas.set("height", canvasSize.height());
QPoint offset;
offset.setX(m_canvas["offsetLeft"].as<int>());
offset.setY(m_canvas["offsetTop"].as<int>());
// Returns the html elments document/body position
auto getElementBodyPosition = [](const emscripten::val &element) -> QPoint {
emscripten::val bodyRect = element["ownerDocument"]["body"].call<emscripten::val>("getBoundingClientRect");
emscripten::val canvasRect = element.call<emscripten::val>("getBoundingClientRect");
return QPoint (canvasRect["left"].as<int>() - bodyRect["left"].as<int>(),
canvasRect["top"].as<int>() - bodyRect["top"].as<int>());
};
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()));
setGeometry(QRect(getElementBodyPosition(m_canvas), cssSize.toSize()));
m_compositor->requestUpdateAllWindows();
}