From cc3b6e4b07a0fd7c1e5187d54e52bbb705173d9f Mon Sep 17 00:00:00 2001 From: ferhatb Date: Mon, 3 May 2021 13:58:22 -0700 Subject: [PATCH 1/4] Fix incorrect physical size due to visualviewport api on iOS --- lib/web_ui/lib/src/engine/dom_renderer.dart | 14 +++++----- lib/web_ui/lib/src/engine/window.dart | 29 ++++++++++++++++++--- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/lib/web_ui/lib/src/engine/dom_renderer.dart b/lib/web_ui/lib/src/engine/dom_renderer.dart index 74d5334a269cf..302368a366301 100644 --- a/lib/web_ui/lib/src/engine/dom_renderer.dart +++ b/lib/web_ui/lib/src/engine/dom_renderer.dart @@ -480,11 +480,11 @@ flt-glass-pane * { setElementAttribute(_sceneHostElement!, 'aria-hidden', 'true'); if (html.window.visualViewport == null && isWebKit) { - // 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 set up a - // temporary periodic timer that polls innerWidth and triggers the - // resizeListener so that the framework can react to the change. + // Older Safari versions sometimes give 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 + // set up 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. @@ -606,12 +606,12 @@ flt-glass-pane * { void _metricsDidChange(html.Event? event) { updateSemanticsScreenProperties(); if (isMobile && !window.isRotation() && textEditing.isEditing) { - window.computeOnScreenKeyboardInsets(); + window.computeOnScreenKeyboardInsets(true); EnginePlatformDispatcher.instance.invokeOnMetricsChanged(); } else { window._computePhysicalSize(); // When physical size changes this value has to be recalculated. - window.computeOnScreenKeyboardInsets(); + window.computeOnScreenKeyboardInsets(false); EnginePlatformDispatcher.instance.invokeOnMetricsChanged(); } } diff --git a/lib/web_ui/lib/src/engine/window.dart b/lib/web_ui/lib/src/engine/window.dart index 13f881ea50109..a40e0ed638e63 100644 --- a/lib/web_ui/lib/src/engine/window.dart +++ b/lib/web_ui/lib/src/engine/window.dart @@ -182,8 +182,24 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { double windowInnerHeight; final html.VisualViewport? viewport = html.window.visualViewport; if (viewport != null) { - windowInnerWidth = viewport.width!.toDouble() * devicePixelRatio; - windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio; + if (browserEngine == BrowserEngine.webkit && + operatingSystem == OperatingSystem.iOs) { + /// Chrome on iOS reports incorrect viewport.height when app + /// starts in portrait orientation and the phone is rotated to + /// landscape. + /// + /// We instead use documentElement clientWidth/Height to read + /// accurate physical size. VisualViewport api is only used during + /// text editing to make sure inset is correctly reported to + /// framework. + final double docWidth = html.document.documentElement!.clientWidth.toDouble(); + final double docHeight = html.document.documentElement!.clientHeight.toDouble(); + windowInnerWidth = docWidth * devicePixelRatio; + windowInnerHeight = docHeight * devicePixelRatio; + } else { + windowInnerWidth = viewport.width!.toDouble() * devicePixelRatio; + windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio; + } } else { windowInnerWidth = html.window.innerWidth! * devicePixelRatio; windowInnerHeight = html.window.innerHeight! * devicePixelRatio; @@ -195,11 +211,16 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { } } - void computeOnScreenKeyboardInsets() { + void computeOnScreenKeyboardInsets(bool isEditingOnMobile) { double windowInnerHeight; final html.VisualViewport? viewport = html.window.visualViewport; if (viewport != null) { - windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio; + if (browserEngine == BrowserEngine.webkit && + operatingSystem == OperatingSystem.iOs && isEditingOnMobile) { + windowInnerHeight = html.document.documentElement!.clientHeight! * devicePixelRatio; + } else { + windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio; + } } else { windowInnerHeight = html.window.innerHeight! * devicePixelRatio; } From 4da9185734e359e75b65ec82bba10c4987c206c8 Mon Sep 17 00:00:00 2001 From: ferhatb Date: Tue, 4 May 2021 17:57:06 -0700 Subject: [PATCH 2/4] Fix edit check --- lib/web_ui/lib/src/engine/window.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/web_ui/lib/src/engine/window.dart b/lib/web_ui/lib/src/engine/window.dart index a40e0ed638e63..458f9812a40bf 100644 --- a/lib/web_ui/lib/src/engine/window.dart +++ b/lib/web_ui/lib/src/engine/window.dart @@ -181,6 +181,7 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { double windowInnerWidth; double windowInnerHeight; final html.VisualViewport? viewport = html.window.visualViewport; + if (viewport != null) { if (browserEngine == BrowserEngine.webkit && operatingSystem == OperatingSystem.iOs) { @@ -216,7 +217,7 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { final html.VisualViewport? viewport = html.window.visualViewport; if (viewport != null) { if (browserEngine == BrowserEngine.webkit && - operatingSystem == OperatingSystem.iOs && isEditingOnMobile) { + operatingSystem == OperatingSystem.iOs && !isEditingOnMobile) { windowInnerHeight = html.document.documentElement!.clientHeight! * devicePixelRatio; } else { windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio; From 359bad23f75c4eff92ee298bb09f0c265df3a1f4 Mon Sep 17 00:00:00 2001 From: ferhatb Date: Wed, 5 May 2021 12:26:11 -0700 Subject: [PATCH 3/4] Fix null warning --- lib/web_ui/lib/src/engine/window.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web_ui/lib/src/engine/window.dart b/lib/web_ui/lib/src/engine/window.dart index 458f9812a40bf..9ab5b32182c39 100644 --- a/lib/web_ui/lib/src/engine/window.dart +++ b/lib/web_ui/lib/src/engine/window.dart @@ -218,7 +218,7 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { if (viewport != null) { if (browserEngine == BrowserEngine.webkit && operatingSystem == OperatingSystem.iOs && !isEditingOnMobile) { - windowInnerHeight = html.document.documentElement!.clientHeight! * devicePixelRatio; + windowInnerHeight = html.document.documentElement!.clientHeight * devicePixelRatio; } else { windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio; } From 46bb070ee89b769e544f153307995aeed0aa376c Mon Sep 17 00:00:00 2001 From: ferhatb Date: Thu, 6 May 2021 09:21:35 -0700 Subject: [PATCH 4/4] address reviewer comments --- lib/web_ui/lib/src/engine/window.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/web_ui/lib/src/engine/window.dart b/lib/web_ui/lib/src/engine/window.dart index 9ab5b32182c39..846d6ab89f190 100644 --- a/lib/web_ui/lib/src/engine/window.dart +++ b/lib/web_ui/lib/src/engine/window.dart @@ -183,8 +183,7 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { final html.VisualViewport? viewport = html.window.visualViewport; if (viewport != null) { - if (browserEngine == BrowserEngine.webkit && - operatingSystem == OperatingSystem.iOs) { + if (operatingSystem == OperatingSystem.iOs) { /// Chrome on iOS reports incorrect viewport.height when app /// starts in portrait orientation and the phone is rotated to /// landscape. @@ -216,8 +215,7 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { double windowInnerHeight; final html.VisualViewport? viewport = html.window.visualViewport; if (viewport != null) { - if (browserEngine == BrowserEngine.webkit && - operatingSystem == OperatingSystem.iOs && !isEditingOnMobile) { + if (operatingSystem == OperatingSystem.iOs && !isEditingOnMobile) { windowInnerHeight = html.document.documentElement!.clientHeight * devicePixelRatio; } else { windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio;