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'