diff options
author | Morten Johan Sørvig <morten.sorvig@qt.io> | 2020-08-03 21:36:20 +0200 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@qt.io> | 2020-08-05 11:23:13 +0200 |
commit | e8997cb05e7f9da6c9c6951ea06262d937de4d72 (patch) | |
tree | 440aa6fd3ffbf30409c47b813bcad3bd2fdf5116 /src | |
parent | 9704cbaf03e99250040a166fbc32f33f6ba12658 (diff) |
wasm: factor visual viewport scale into dpr
By default, mobile browsers create a (layout) viewport
much wider than the visual viewport in order to be
compatible with web pages created with desktop browsers
in mind.
This means that the default view is zoomed out. This
zoom is not reflected in window.devicePixelRatio, and
Qt ends up setting the canvas render size to be larger
than actually needed.
The window.visualViewport.scale property reflects this
“mobile” zoom level: add it as a devicePixelRatio factor.
(The value will be less than 1 when zoomed out). User
pinch-to-zoom may change the zoom level and resize
the visual viewport; install a resize handler as well.
For now we limit the devicePixelRatio value in order
to avoid creating gigantic backing store images - this
is something we can revisit later on.
Pick-to: 5.15
Task-number: QTBUG-85662
Change-Id: I96db6121fe17a6c213216e04e4724efc93a9b66a
Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/platforms/wasm/qwasmintegration.cpp | 14 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmscreen.cpp | 23 |
2 files changed, 31 insertions, 6 deletions
diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index 0d196ec099..15d396f479 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -87,6 +87,12 @@ static void qtUpdateDpi() QWasmIntegration::get()->updateDpi(); } +static void resizeAllScreens(emscripten::val event) +{ + Q_UNUSED(event); + QWasmIntegration::get()->resizeAllScreens(); +} + EMSCRIPTEN_BINDINGS(qtQWasmIntegraton) { function("qtBrowserBeforeUnload", &browserBeforeUnload); @@ -94,6 +100,7 @@ EMSCRIPTEN_BINDINGS(qtQWasmIntegraton) function("qtRemoveCanvasElement", &removeCanvasElement); function("qtResizeCanvasElement", &resizeCanvasElement); function("qtUpdateDpi", &qtUpdateDpi); + function("qtResizeAllScreens", &resizeAllScreens); } QWasmIntegration *QWasmIntegration::s_instance; @@ -136,6 +143,13 @@ QWasmIntegration::QWasmIntegration() return 0; }; emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, nullptr, 1, onWindowResize); + + // install visualViewport resize handler which picks up size and scale change on mobile. + emscripten::val visualViewport = emscripten::val::global("window")["visualViewport"]; + if (!visualViewport.isUndefined()) { + visualViewport.call<void>("addEventListener", val("resize"), + val::module_property("qtResizeAllScreens")); + } } QWasmIntegration::~QWasmIntegration() diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp index 0f1fd886d0..be9d35cdef 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.cpp +++ b/src/plugins/platforms/wasm/qwasmscreen.cpp @@ -127,12 +127,23 @@ QDpi QWasmScreen::logicalDpi() const qreal QWasmScreen::devicePixelRatio() const { - // FIXME: The effective device pixel ratio may be different from the - // HTML window dpr if the OpenGL driver/GPU allocates a less than - // full resolution surface. Use emscripten_webgl_get_drawing_buffer_size() - // and compute the dpr instead. - double htmlWindowDpr = emscripten::val::global("window")["devicePixelRatio"].as<double>(); - return qreal(htmlWindowDpr); + // window.devicePixelRatio gives us the scale factor between CSS and device pixels. + // This property reflects hardware configuration, and also browser zoom on desktop. + // + // window.visualViewport.scale gives us the zoom factor on mobile. If the html page is + // configured with "<meta name="viewport" content="width=device-width">" then this scale + // factor will be 1. Omitting the viewport configuration typically results on a zoomed-out + // viewport, with a scale factor <1. User pinch-zoom will change the scale factor; an event + // handler is installed in the QWasmIntegration constructor. Changing zoom level on desktop + // does not appear to change visualViewport.scale. + // + // The effective devicePixelRatio is the product of these two scale factors, upper-bounded + // by window.devicePixelRatio in order to avoid e.g. allocating a 10x widget backing store. + double dpr = emscripten::val::global("window")["devicePixelRatio"].as<double>(); + emscripten::val visualViewport = emscripten::val::global("window")["visualViewport"]; + double scale = visualViewport.isUndefined() ? 1.0 : visualViewport["scale"].as<double>(); + double effectiveDevicePixelRatio = std::min(dpr * scale, dpr); + return qreal(effectiveDevicePixelRatio); } QString QWasmScreen::name() const |