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'