Skip to content

[iPhone Duo] MediaQuery.sizeOf reports the whole screen inside a dialog confined to one half of a foldable #192667

Description

@diegolopezrm

Steps to reproduce

DisplayFeatureSubScreen confines a dialog, bottom sheet or popup to one sub-screen of a foldable and wraps it in MediaQuery(data: mediaQuery.removeDisplayFeatures(closestSubScreen)). removeDisplayFeatures adjusts padding, viewInsets and viewPadding, and filters displayFeatures. It does not adjust size.

So a widget inside the dialog reads the width of the whole screen while occupying half of it. This runs as a widget test and passes today:

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('MediaQuery.size is not reduced to the sub-screen', (
    WidgetTester tester,
  ) async {
    tester.view.devicePixelRatio = 1.0;
    tester.view.physicalSize = const Size(800, 900);
    // A 40px fold down the middle: the sub-screens are 0..380 and 420..800.
    tester.view.displayFeatures = <DisplayFeature>[
      const DisplayFeature(
        bounds: Rect.fromLTRB(380, 0, 420, 900),
        type: DisplayFeatureType.fold,
        state: DisplayFeatureState.postureHalfOpened,
      ),
    ];
    addTearDown(tester.view.reset);

    late Size reported;
    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) => ElevatedButton(
            onPressed: () => showDialog<void>(
              context: context,
              anchorPoint: Offset.zero,
              builder: (BuildContext inner) {
                reported = MediaQuery.sizeOf(inner);
                return const SizedBox.expand(key: Key('body'));
              },
            ),
            child: const Text('open'),
          ),
        ),
      ),
    );
    await tester.tap(find.text('open'));
    await tester.pumpAndSettle();

    final Rect body = tester.getRect(find.byKey(const Key('body')));
    print('the dialog occupies    -> ${body.width} x ${body.height}');
    print('MediaQuery.sizeOf says -> ${reported.width} x ${reported.height}');

    expect(body.width, 380);
    expect(reported.width, 800); // passes today; 380 is what a caller expects
  });
}

Expected results

MediaQuery.sizeOf inside the sub-screen reports the size the child actually has — 380×900 here — or the documentation says that it deliberately does not, so callers know to reach for LayoutBuilder instead.

Actual results

the dialog occupies    -> 380.0 x 900.0
MediaQuery.sizeOf says -> 800.0 x 900.0

Anything derived from it is off by the width of the other half plus the fold. A box asking for MediaQuery.sizeOf(context).width / 2 asks for 400 and is silently clamped to 380 — there is no overflow banner, just a layout that is quietly wrong.

Additional context

The doc comment on removeDisplayFeatures lists what it adjusts and does not mention size either way:

Creates a copy of this media query data by removing [displayFeatures] that are completely outside the given sub-screen and adjusting the [padding], [viewInsets] and [viewPadding] to be zero on the sides that are not included in the sub-screen.

Whether the fix is to narrow size or to document that it is not narrowed is a call for the team — the two have very different blast radii for apps already shipping on Android foldables.

Two things this is not, which I checked while measuring:

  • The asymmetric insets are handled correctly. With padding of l=20 t=59 r=5 b=34 and the same fold, a dialog on the left half lands at 20..380 and one on the right at 420..795, so each side is honoured independently.
  • It is not iOS-specific. It reproduces on Android foldables today. It is worth raising now because the same code path is what MediaQuery.displayFeatures would drive on iPhone Duo ([iPhone Duo] Proposal: populate MediaQuery.displayFeatures on iOS for iPhone Duo (foldable) #192515), which ships on 23 October, so the number of apps hitting it is about to grow.

Reproduced on 3.44.6 stable and on a master checkout (3.48.0-1.0.pre-702); removeDisplayFeatures is unchanged between them.

flutter doctor
[✓] Flutter (Channel stable, 3.44.6, on macOS 26.5.2 25F84 darwin-arm64, locale es-CO)
[✓] Android toolchain - develop for Android devices (Android SDK version 36.1.0)
[✓] Xcode - develop for iOS and macOS (Xcode 26.1.1)
[✓] Chrome - develop for the web
[✓] Connected device (4 available)
[✓] Network resources

Activity

  1. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    on Sep 14, 2026
  2. mbcorona commented on Sep 14, 2026

    @mbcorona
    Member

    Hi @diegolopezrm, thanks for reporting. Confirmed on master: removeDisplayFeatures copyWith passes padding, viewInsets, viewPadding and displayFeatures but not size, so size stays the full screen.
    Routing to the framework team for evaluation.

  3. changed the title [-]`MediaQuery.sizeOf` reports the whole screen inside a dialog confined to one half of a foldable[/-] [+][iPhone Duo] `MediaQuery.sizeOf` reports the whole screen inside a dialog confined to one half of a foldable[/+] on Sep 19, 2026
  4. added
    P2Important issues not at the top of the work list
    fyi-iosFor the attention of iOS platform team
    on Sep 22, 2026
  5. preethi0228-git commented on Sep 28, 2026

    @preethi0228-git

    Hi,

    I was able to reproduce the issue on the iPhone Duo Simulator. During my testing, I also observed some UI/layout issues with different components/screens, and I'm sharing a few screenshots as additional reference.

    Image Image Image Image

    Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work liste: device-specificOnly manifests on certain devicesframeworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions