Skip to content

Windowing implementation of showDialog that uses a native desktop window to display the content #181861

Merged
mattkae merged 56 commits intoflutter:masterfrom
canonical:feature/material_dialogs_multi_window
Mar 5, 2026
Merged

Windowing implementation of showDialog that uses a native desktop window to display the content #181861
mattkae merged 56 commits intoflutter:masterfrom
canonical:feature/material_dialogs_multi_window

Conversation

@mattkae
Copy link
Contributor

@mattkae mattkae commented Feb 3, 2026

image image

What's new?

  • Added the MaterialWindowingManager which will render all of the sub-windows that the material app relies
  • The MaterialWindowingManager provides the MaterialWindowRegistry which enables its descendants to create and remove windows from the windowing manager
  • Implemented a windowing path for showDialog which uses that Navigator to push a true window to the navigation stack
  • In material_window_manager.dart, the dialog will be rendered appropriately with inherited theming, text direction, and other media query data
  • Added the api_multiwindow example application to demonstrate the new behavior for both fullscreen and non-fullscreen dialogs
  • Added tests to the api_multiwindow example application
  • Updated the documentation of showDialog to explain how each field works when windowing is enabled
  • Made it so that we fallback to the regular showDialog implementation if the windowing implementation fails

How to test

On Win32, macOS, and Linux:

  1. fluter config --enable-windowing
  2. In examples/api_multiwindow: flutter run lib/material/dialog/dialog.0.dart
  3. Click the two buttons and see the true dialogs

Also, run flutter test and see that the tests pass

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. d: examples Sample code and demos a: desktop Running on desktop labels Feb 3, 2026
@mattkae mattkae changed the title An implementation of showDialog that relies on native desktop dialog windows An implementation of showDialog that uses a native desktop to display the content Feb 3, 2026
@mattkae mattkae marked this pull request as ready for review February 3, 2026 19:33
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an experimental implementation of showDialog that uses native desktop windows. It adds a useWindowing flag to MaterialApp which, when enabled, makes showDialog create a new window instead of an overlay. A new MaterialWindowingManager widget is introduced to manage these windows. The implementation includes a fallback to the traditional dialog behavior if windowing is not supported. A new example application, api_multiwindow, is also added to demonstrate and test this new functionality.

@mattkae mattkae changed the title An implementation of showDialog that uses a native desktop to display the content Windowing implementation of showDialog that uses a native desktop window to display the content Feb 3, 2026
@mattkae mattkae requested a review from loic-sharma March 4, 2026 21:26
final WidgetBuilder builder;
}

/// The window manager provides a convient way to render windows
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// The window manager provides a convient way to render windows
/// The window manager provides a convenient way to render windows

}

@override
Widget build(BuildContext context) {
Copy link
Member

@loic-sharma loic-sharma Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it'd be worth checking that _WindowRegistryScopes aren't nested? For example, you might get unexpected behavior if you use MaterialApp and then manually add your own WindowManager to the widget tree. I don't feel strongly about this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sounds like an unnecessary restriction. You may even want it in some places I imagine. Let's leave it like this for now, and if it proves to be a problem, we can go back and add the restriction :)

final List<WindowEntry> _windows = <WindowEntry>[];

/// The list of registered windows.
List<WindowEntry> get windows => List<WindowEntry>.unmodifiable(_windows);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be internal with the experimental docs macro?

///
/// See also:
///
/// * [WindowManager], responsible for listening for new windows and rendering them.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd consider moving the 5th paragraph - which explains when WindowRegistry is useful - up to the 2nd paragraph. I think that's useful context when reading the rest of the docs.

Maybe something like:

Suggested change
/// * [WindowManager], responsible for listening for new windows and rendering them.
/// A registry used to render top-level windows.
///
/// The registry is often used to render top-level windows
/// that are logically nested under a widget deep in the tree.
///
/// The [WindowManager] provides a [WindowRegistry] to its descendents.
///
/// Descendents of the manager can use [WindowRegistry.maybeOf] to access the
/// registry. With the registry, they can call [WindowRegistry.register] to
/// add a new window to the registry and [WindowRegistry.unregister] to remove
/// a window from the registry.
///
/// {@macro flutter.widgets.windowing.experimental}
///
/// See also:
///
/// * [WindowManager], responsible for listening for new windows and rendering them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it!

Comment on lines +1958 to +1964
late final WindowRegistry _registry;

@override
void initState() {
super.initState();
_registry = WindowRegistry();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, my suggestion to create this in initState was unnecessary, you can just initialize the field directly:

Suggested change
late final WindowRegistry _registry;
@override
void initState() {
super.initState();
_registry = WindowRegistry();
}
final WindowRegistry _registry = WindowRegistry();

Or if you're feeling fancy:

Suggested change
late final WindowRegistry _registry;
@override
void initState() {
super.initState();
_registry = WindowRegistry();
}
final WindowRegistry _registry = .new();

return navigator.push<T>(route);
}

// TODO(justinmc): This was copied from Material, is it needed?
Copy link
Member

@loic-sharma loic-sharma Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattkae Bubbling up this comment, it looks like it got missed since it's on an old thread: https://github.com/flutter/flutter/pull/181861/changes#r2879491013

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We certainly need this in Material. I think we can remove it at this layer though. It needs to happen before much of the build in showDialog

Copy link
Member

@loic-sharma loic-sharma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

@mattkae mattkae force-pushed the feature/material_dialogs_multi_window branch from 827eb77 to 6538a43 Compare March 5, 2026 19:26
@mattkae mattkae added this pull request to the merge queue Mar 5, 2026
Merged via the queue into flutter:master with commit ea02c5f Mar 5, 2026
72 checks passed
@mattkae mattkae deleted the feature/material_dialogs_multi_window branch March 5, 2026 21:43
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 6, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 6, 2026
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Mar 6, 2026
Roll Flutter from d3dd7744e81f to d18214307703 (33 revisions)

flutter/flutter@d3dd774...d182143

2026-03-06 [email protected] Roll Packages from 8d5c5cd to fe3de64 (2 revisions) (flutter/flutter#183308)
2026-03-06 [email protected] Roll Dart SDK from 1b51451cdb99 to 7c7c1e3d024d (2 revisions) (flutter/flutter#183294)
2026-03-06 [email protected] Roll Dart SDK from 9ac06cdd1801 to 1b51451cdb99 (9 revisions) (flutter/flutter#183289)
2026-03-06 [email protected] Add GitHub workflows to assist with release tasks (flutter/flutter#181978)
2026-03-06 [email protected] [Impeller] Fix new convex path shadow generation in perspective (flutter/flutter#183187)
2026-03-06 [email protected] Roll pub packages (flutter/flutter#183178)
2026-03-05 [email protected] fix: use double quotes in settings.gradle.kts template (flutter/flutter#183081)
2026-03-05 [email protected] Add fallbackColor for PredictiveBackPageTransitionBuilder and PredictiveBackFullscreenPageTransitionBuilder (flutter/flutter#182690)
2026-03-05 [email protected] Simplify TesterContextGLES (multithreading logic not needed), and enable some tests that now pass (flutter/flutter#183250)
2026-03-05 [email protected] Roll Skia from a94df1cdabb0 to a69ef43650ee (14 revisions) (flutter/flutter#183280)
2026-03-05 [email protected] Windowing implementation of `showDialog` that uses a native desktop window to display the content  (flutter/flutter#181861)
2026-03-05 [email protected] Build CocoaPod plugin frameworks for Add to App FlutterPluginRegistrant (flutter/flutter#183239)
2026-03-05 [email protected] Extend the Linux web_skwasm_tests_1 timeout to 45 minutes (flutter/flutter#183247)
2026-03-05 [email protected] Update Dart to 3.12 beta 2 (flutter/flutter#183251)
2026-03-05 [email protected] Replace the rest of the references to `flutter/engine` with `flutter/flutter` (flutter/flutter#182938)
2026-03-05 [email protected] chore: convert android_verified_input to pub-workspace (flutter/flutter#183175)
2026-03-05 [email protected] Add await to flutter_test callsites (flutter/flutter#182983)
2026-03-05 [email protected] [iOS] Skip gesture recognizer reset workaround on iOS 26+  (flutter/flutter#183186)
2026-03-05 [email protected] Add warning for plugins not migrated to UIScene (flutter/flutter#182826)
2026-03-05 [email protected] Roll Fuchsia Linux SDK from JJw5EJ87vLGqFVl4h... to 8ay15_eQOEgPHCypm... (flutter/flutter#183255)
2026-03-05 [email protected] Roll Skia from ada0b7628c79 to a94df1cdabb0 (2 revisions) (flutter/flutter#183249)
2026-03-05 [email protected] Roll Packages from 82baf93 to 8d5c5cd (2 revisions) (flutter/flutter#183269)
2026-03-05 [email protected] Add `UnlabaledLeafNodeEvaluation` (flutter/flutter#182872)
2026-03-04 [email protected] Re-specify the ndk version in various test apps, to prevent ndk download (flutter/flutter#183134)
2026-03-04 [email protected] Eliminate rebuilds for Scaffold FAB animation (flutter/flutter#182331)
2026-03-04 [email protected] Add Michal Kucharski to AUTHORS (flutter/flutter#182366)
2026-03-04 [email protected] Merge changelog from 3.41.4 stable. (flutter/flutter#183243)
2026-03-04 [email protected] Allow stylus support on windows (flutter/flutter#165323)
2026-03-04 [email protected] Fix docs on SingletonFlutterWindow.supportsShowingSystemContextMenu (flutter/flutter#183142)
2026-03-04 [email protected] Roll Packages from 9083bc9 to 82baf93 (5 revisions) (flutter/flutter#183240)
2026-03-04 [email protected] Fixes FocusHighlightMode on Android when typing in software keyboard (flutter/flutter#180753)
2026-03-04 [email protected] Make compileShader() retry without sksl if it fails with sksl. (flutter/flutter#183146)
2026-03-04 [email protected] [web] Use pointer-events: auto for non-interactive leaf semantics nodes (flutter/flutter#183077)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
...
xxxOVALxxx pushed a commit to xxxOVALxxx/flutter that referenced this pull request Mar 10, 2026
…indow to display the content (flutter#181861)

<img width="800" height="635" alt="image"
src="proxy.php?url=https://github.com/user-attachments/assets/54315175-2091-4508-a61f-337b35ef35e8"
/>

<img width="800" height="635" alt="image"
src="proxy.php?url=https://github.com/user-attachments/assets/9f627624-b008-48e1-a281-aabb15b9418e"
/>


## What's new?
- Added the `MaterialWindowingManager` which will render all of the
sub-windows that the material app relies
- The `MaterialWindowingManager` provides the `MaterialWindowRegistry`
which enables its descendants to create and remove windows from the
windowing manager
- Implemented a windowing path for `showDialog` which uses that
`Navigator` to push a true window to the navigation stack
- In `material_window_manager.dart`, the dialog will be rendered
appropriately with inherited theming, text direction, and other media
query data
- Added the `api_multiwindow` example application to demonstrate the new
behavior for both fullscreen and non-fullscreen dialogs
- Added tests to the `api_multiwindow` example application
- Updated the documentation of `showDialog` to explain how each field
works when windowing is enabled
- Made it so that we fallback to the regular `showDialog` implementation
if the windowing implementation fails

## How to test
On Win32, macOS, and Linux:

1. `fluter config --enable-windowing`
2. In `examples/api_multiwindow`: `flutter run
lib/material/dialog/dialog.0.dart`
3. Click the two buttons and see the true dialogs

Also, run `flutter test` and see that the tests pass

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

---------

Co-authored-by: Justin McCandless <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: desktop Running on desktop d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants