diff --git a/lib/web_ui/lib/src/engine/dom_renderer.dart b/lib/web_ui/lib/src/engine/dom_renderer.dart index df5c03b8a12bd59a26e94788dca2d0f07ca9088d..9c91b5c8098a09cf2b3efe1f43c53c3b45eb6ce4 100644 --- a/lib/web_ui/lib/src/engine/dom_renderer.dart +++ b/lib/web_ui/lib/src/engine/dom_renderer.dart @@ -393,12 +393,21 @@ flt-glass-pane * { // is 1.0. window.debugOverrideDevicePixelRatio(1.0); - if (browserEngine == BrowserEngine.webkit) { + if (html.window.visualViewport == null && + browserEngine == BrowserEngine.webkit) { // Safari sometimes gives us bogus innerWidth/innerHeight values when the // page loads. When it changes the values to correct ones it does not // notify of the change via `onResize`. As a workaround, we setup a // temporary periodic timer that polls innerWidth and triggers the // resizeListener so that the framework can react to the change. + // + // Safari 13 has implemented visualViewport API so it doesn't need this + // timer. + // + // VisualViewport API is not enabled in Firefox as well. On the other hand + // Firefox returns correct values for innerHeight, innerWidth. + // Firefox also triggers html.window.onResize therefore we don't need this + // timer setup for Firefox. final int initialInnerWidth = html.window.innerWidth; // Counts how many times we checked screen size. We check up to 5 times. int checkCount = 0; @@ -422,7 +431,12 @@ flt-glass-pane * { html.document.head.append(_canvasKitScript); } - _resizeSubscription = html.window.onResize.listen(_metricsDidChange); + if (html.window.visualViewport != null) { + _resizeSubscription = + html.window.visualViewport.onResize.listen(_metricsDidChange); + } else { + _resizeSubscription = html.window.onResize.listen(_metricsDidChange); + } } /// Called immediately after browser window metrics change. diff --git a/lib/web_ui/lib/src/engine/window.dart b/lib/web_ui/lib/src/engine/window.dart index 6e422b1aacd2983dec0631a9dd48123026f4c9d9..16cfe749ca5571c6e7eb074d4eca14a9b1303213 100644 --- a/lib/web_ui/lib/src/engine/window.dart +++ b/lib/web_ui/lib/src/engine/window.dart @@ -51,9 +51,15 @@ class EngineWindow extends ui.Window { }()); if (!override) { - final double windowInnerWidth = html.window.innerWidth * devicePixelRatio; - final double windowInnerHeight = - html.window.innerHeight * devicePixelRatio; + double windowInnerWidth; + double windowInnerHeight; + if (html.window.visualViewport != null) { + windowInnerWidth = html.window.visualViewport.width * devicePixelRatio; + windowInnerHeight = html.window.visualViewport.height * devicePixelRatio; + } else { + windowInnerWidth = html.window.innerWidth * devicePixelRatio; + windowInnerHeight = html.window.innerHeight * devicePixelRatio; + } if (windowInnerWidth != _lastKnownWindowInnerWidth || windowInnerHeight != _lastKnownWindowInnerHeight) { _lastKnownWindowInnerWidth = windowInnerWidth; diff --git a/lib/web_ui/test/dom_renderer_test.dart b/lib/web_ui/test/dom_renderer_test.dart index acada0e30e7e3aadeea877b22a83888612d53851..724cc318e6f13eebe8695c0388a5bf6076036e97 100644 --- a/lib/web_ui/test/dom_renderer_test.dart +++ b/lib/web_ui/test/dom_renderer_test.dart @@ -98,6 +98,14 @@ void main() { renderer.attachBeforeElement(parent, childD, childC); expect(parent.innerHtml, ''); }); + + test('inneheight/innerWidth are equal to visualViewport height and width', () { + if (html.window.visualViewport != null) { + expect(html.window.visualViewport.width, html.window.innerWidth); + expect(html.window.visualViewport.height, html.window.innerHeight); + } + }); + test('replaces viewport meta tags during style reset', () { final html.MetaElement existingMeta = html.MetaElement() ..name = 'viewport'