Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 72c2fda

Browse files
authored
[web] Fix incorrect physical size due to visualviewport api on iOS (#25895)
1 parent 406c4da commit 72c2fda

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

lib/web_ui/lib/src/engine/dom_renderer.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -480,11 +480,11 @@ flt-glass-pane * {
480480
setElementAttribute(_sceneHostElement!, 'aria-hidden', 'true');
481481

482482
if (html.window.visualViewport == null && isWebKit) {
483-
// Safari sometimes gives us bogus innerWidth/innerHeight values when the
484-
// page loads. When it changes the values to correct ones it does not
485-
// notify of the change via `onResize`. As a workaround, we set up a
486-
// temporary periodic timer that polls innerWidth and triggers the
487-
// resizeListener so that the framework can react to the change.
483+
// Older Safari versions sometimes give us bogus innerWidth/innerHeight
484+
// values when the page loads. When it changes the values to correct ones
485+
// it does not notify of the change via `onResize`. As a workaround, we
486+
// set up a temporary periodic timer that polls innerWidth and triggers
487+
// the resizeListener so that the framework can react to the change.
488488
//
489489
// Safari 13 has implemented visualViewport API so it doesn't need this
490490
// timer.
@@ -606,12 +606,12 @@ flt-glass-pane * {
606606
void _metricsDidChange(html.Event? event) {
607607
updateSemanticsScreenProperties();
608608
if (isMobile && !window.isRotation() && textEditing.isEditing) {
609-
window.computeOnScreenKeyboardInsets();
609+
window.computeOnScreenKeyboardInsets(true);
610610
EnginePlatformDispatcher.instance.invokeOnMetricsChanged();
611611
} else {
612612
window._computePhysicalSize();
613613
// When physical size changes this value has to be recalculated.
614-
window.computeOnScreenKeyboardInsets();
614+
window.computeOnScreenKeyboardInsets(false);
615615
EnginePlatformDispatcher.instance.invokeOnMetricsChanged();
616616
}
617617
}

lib/web_ui/lib/src/engine/window.dart

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,25 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow {
181181
double windowInnerWidth;
182182
double windowInnerHeight;
183183
final html.VisualViewport? viewport = html.window.visualViewport;
184+
184185
if (viewport != null) {
185-
windowInnerWidth = viewport.width!.toDouble() * devicePixelRatio;
186-
windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio;
186+
if (operatingSystem == OperatingSystem.iOs) {
187+
/// Chrome on iOS reports incorrect viewport.height when app
188+
/// starts in portrait orientation and the phone is rotated to
189+
/// landscape.
190+
///
191+
/// We instead use documentElement clientWidth/Height to read
192+
/// accurate physical size. VisualViewport api is only used during
193+
/// text editing to make sure inset is correctly reported to
194+
/// framework.
195+
final double docWidth = html.document.documentElement!.clientWidth.toDouble();
196+
final double docHeight = html.document.documentElement!.clientHeight.toDouble();
197+
windowInnerWidth = docWidth * devicePixelRatio;
198+
windowInnerHeight = docHeight * devicePixelRatio;
199+
} else {
200+
windowInnerWidth = viewport.width!.toDouble() * devicePixelRatio;
201+
windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio;
202+
}
187203
} else {
188204
windowInnerWidth = html.window.innerWidth! * devicePixelRatio;
189205
windowInnerHeight = html.window.innerHeight! * devicePixelRatio;
@@ -195,11 +211,15 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow {
195211
}
196212
}
197213

198-
void computeOnScreenKeyboardInsets() {
214+
void computeOnScreenKeyboardInsets(bool isEditingOnMobile) {
199215
double windowInnerHeight;
200216
final html.VisualViewport? viewport = html.window.visualViewport;
201217
if (viewport != null) {
202-
windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio;
218+
if (operatingSystem == OperatingSystem.iOs && !isEditingOnMobile) {
219+
windowInnerHeight = html.document.documentElement!.clientHeight * devicePixelRatio;
220+
} else {
221+
windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio;
222+
}
203223
} else {
204224
windowInnerHeight = html.window.innerHeight! * devicePixelRatio;
205225
}

0 commit comments

Comments
 (0)