From 6cf07525bfaee03e1fb836b46a004e2e74aafbcf Mon Sep 17 00:00:00 2001 From: Nurhan Turgut <50856934+nturgut@users.noreply.github.com> Date: Thu, 31 Oct 2019 15:10:38 -0700 Subject: [PATCH] =?UTF-8?q?[web]=20Get=20the=20size=20from=20visualviewpor?= =?UTF-8?q?t=20instead=20of=20window.innerHeight/innerW=E2=80=A6=20(flutte?= =?UTF-8?q?r/engine#13462)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * get the size from visualviewport instead of window.innerHeight/innerWidth. * merging 2 if statements to one. * add more comments --- .../web_ui/lib/src/engine/dom_renderer.dart | 18 ++++++++++++++++-- .../lib/web_ui/lib/src/engine/window.dart | 12 +++++++++--- .../lib/web_ui/test/dom_renderer_test.dart | 8 ++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/dom_renderer.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/dom_renderer.dart index df5c03b8a12..9c91b5c8098 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/dom_renderer.dart +++ b/engine/src/flutter/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/engine/src/flutter/lib/web_ui/lib/src/engine/window.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/window.dart index 6e422b1aacd..16cfe749ca5 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/window.dart +++ b/engine/src/flutter/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/engine/src/flutter/lib/web_ui/test/dom_renderer_test.dart b/engine/src/flutter/lib/web_ui/test/dom_renderer_test.dart index acada0e30e7..724cc318e6f 100644 --- a/engine/src/flutter/lib/web_ui/test/dom_renderer_test.dart +++ b/engine/src/flutter/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'