这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@mattkae
Copy link
Contributor

@mattkae mattkae commented Aug 13, 2025

What's new?

  • Implement and test _window_win32.dart, the Win32 implementation of _window.dart 🎉
  • Wrote a bunch of tests in window_win32_test.dart which uses a mock API barrier to mock the native Win32 layer
  • Update BaseWindowController to extend ChangeNotifier and use it to inform the WindowScope of when things change
  • Made RegularWindowController.empty() a non-internal constructor, as it is needed by implementations
  • Added a large example application for windowing where users can test out different windowing concepts and see how they work!

To test, simply run the tests or try out the example app!

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 a: tests "flutter test", flutter_test, or one of our tests framework flutter/packages/flutter repository. See also f: labels. d: examples Sample code and demos a: desktop Running on desktop labels Aug 13, 2025
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 support for regular windows on the Win32 platform, along with a comprehensive example application to demonstrate the new multi-windowing API. The changes include a new _window_win32.dart file with the platform-specific implementation using FFI, modifications to _window.dart to integrate the new platform, and a full example project. The implementation is well-structured, using a WindowingOwner pattern and providing a clean interface for creating and managing windows. The example app is a great addition for understanding the API usage.

I have a few minor suggestions to improve code clarity and consistency, mainly around removing unnecessary async keywords in the example app and ensuring consistency with BoxConstraints in the framework code. Overall, this is a solid contribution that significantly expands Flutter's desktop capabilities.

Comment on lines 163 to 165
onPressed: () async {
controller.controller.destroy();
},
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The async keyword is unnecessary here as controller.controller.destroy() is a synchronous method and is not awaited. Removing it improves code clarity.1

                        onPressed: () {
                          controller.controller.destroy();
                        },

Style Guide References

Footnotes

  1. Code should be written for readability. Unnecessary 'async' keywords can make the code harder to understand as it implies asynchronicity where there is none. (link)

Comment on lines 170 to 174
onPressed: () async {
final RegularWindowController regular = controller
.controller as RegularWindowController;
regular.setFullscreen(!regular.isFullscreen);
},
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The async keyword is not needed here because regular.setFullscreen() is synchronous and not awaited. Removing it makes the code cleaner.1

                          onPressed: () {
                            final RegularWindowController regular = controller
                                .controller as RegularWindowController;
                            regular.setFullscreen(!regular.isFullscreen);
                          },

Style Guide References

Footnotes

  1. Code should be written for readability. Unnecessary 'async' keywords can make the code harder to understand as it implies asynchronicity where there is none. (link)

Comment on lines 237 to 251
onPressed: () async {
final UniqueKey key = UniqueKey();
windowManagerModel.add(
KeyedWindowController(
key: key,
controller: RegularWindowController(
delegate: CallbackRegularWindowControllerDelegate(
onDestroyed: () => windowManagerModel.remove(key),
),
title: "Regular",
preferredSize: windowSettings.regularSize,
),
),
);
},
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The async keyword is unnecessary in this onPressed callback since no asynchronous operations are being awaited. Removing it simplifies the code and improves readability.1

                  onPressed: () {
                    final UniqueKey key = UniqueKey();
                    windowManagerModel.add(
                      KeyedWindowController(
                        key: key,
                        controller: RegularWindowController(
                          delegate: CallbackRegularWindowControllerDelegate(
                            onDestroyed: () => windowManagerModel.remove(key),
                          ),
                          title: "Regular",
                          preferredSize: windowSettings.regularSize,
                        ),
                      ),
                    );
                  },

Style Guide References

Footnotes

  1. Code should be written for readability. Unnecessary 'async' keywords can make the code harder to understand as it implies asynchronicity where there is none. (link)

Comment on lines +824 to +830
void from(BoxConstraints? constraints) {
hasConstraints = constraints != null;
minWidth = constraints?.minWidth ?? 0;
minHeight = constraints?.minHeight ?? 0;
maxWidth = constraints?.maxWidth ?? double.maxFinite;
maxHeight = constraints?.maxHeight ?? double.maxFinite;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The BoxConstraints class uses double.infinity to represent unconstrained dimensions. This implementation uses double.maxFinite instead. While double.maxFinite is a very large number, using double.infinity would be more consistent with BoxConstraints and better represent an unconstrained value. If double.infinity cannot be passed over FFI, this should be documented with a comment.1

  void from(BoxConstraints? constraints) {
    hasConstraints = constraints != null;
    minWidth = constraints?.minWidth ?? 0;
    minHeight = constraints?.minHeight ?? 0;
    maxWidth = constraints?.maxWidth ?? double.infinity;
    maxHeight = constraints?.maxHeight ?? double.infinity;
  }

Style Guide References

Footnotes

  1. The style guide encourages writing code correctly and consistently. Using 'double.infinity' aligns with the 'BoxConstraints' implementation, improving consistency. (link)

Copy link
Member

Choose a reason for hiding this comment

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

@mattkae What do you think of this? This suggestion seems nice, but I don't mind either ways.

Copy link
Contributor

Choose a reason for hiding this comment

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

Same. Could be nice as long as it doesn't make the FFI transition a pain.

@mattkae mattkae marked this pull request as ready for review August 13, 2025 15:59
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 29, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 29, 2025
@mattkae mattkae deleted the regular_windows_win32 branch September 29, 2025 15:27
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 29, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 29, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 29, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 29, 2025
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Sep 29, 2025
Roll Flutter from 6cc976ec26d3 to 96fe3b3df509 (32 revisions)

flutter/flutter@6cc976e...96fe3b3

2025-09-29 engine-flutter-autoroll@skia.org Roll Packages from 389c678 to 34eec78 (6 revisions) (flutter/flutter#176205)
2025-09-29 engine-flutter-autoroll@skia.org Roll Skia from 9b2b942d1eb1 to bb3b6bd4be0d (4 revisions) (flutter/flutter#176201)
2025-09-29 bkonyi@google.com [ Widget Preview ] Improve IDE integration support (flutter/flutter#176114)
2025-09-29 robert.ancell@canonical.com Fix name of driver file (flutter/flutter#176186)
2025-09-29 engine-flutter-autoroll@skia.org Roll Skia from beb673968802 to 9b2b942d1eb1 (3 revisions) (flutter/flutter#176190)
2025-09-28 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from 0Z45OXT_Wb8aWI3a0... to 8zjcJic_DtvB2Bo2x... (flutter/flutter#176158)
2025-09-28 flar@google.com Revert "[Impeller] Optimize scale translate rectangle transforms" (flutter/flutter#176161)
2025-09-27 engine-flutter-autoroll@skia.org Roll Skia from 2e5da5c0a9cd to beb673968802 (1 revision) (flutter/flutter#176145)
2025-09-27 flar@google.com [Impeller] Optimize scale translate rectangle transforms (flutter/flutter#176123)
2025-09-27 engine-flutter-autoroll@skia.org Roll Skia from d8422aaf8f89 to 2e5da5c0a9cd (2 revisions) (flutter/flutter#176141)
2025-09-27 mdebbar@google.com [web] Remove mention of non-existent `canvaskit_lock.yaml` (flutter/flutter#176108)
2025-09-27 engine-flutter-autoroll@skia.org Roll Skia from 96b73f61fe61 to d8422aaf8f89 (2 revisions) (flutter/flutter#176118)
2025-09-27 sokolovskyi.konstantin@gmail.com [a11y] Add `expanded` flag support to Android. (flutter/flutter#174981)
2025-09-26 ahmedsameha1@gmail.com Make sure that a DesktopTextSelectionToolbar doesn't crash in 0x0 env… (flutter/flutter#173928)
2025-09-26 engine-flutter-autoroll@skia.org Roll Dart SDK from 899c7340cc4c to af31d2637b6b (11 revisions) (flutter/flutter#176056)
2025-09-26 1063596+reidbaker@users.noreply.github.com Update java version ranges with the top end limitation for java pre 17 (flutter/flutter#176049)
2025-09-26 1063596+reidbaker@users.noreply.github.com Add warn java evaluation to android_workflow (flutter/flutter#176097)
2025-09-26 katelovett@google.com Removes type annotations in templates (flutter/flutter#176106)
2025-09-26 fluttergithubbot@gmail.com Marks Linux_pixel_7pro static_path_stroke_tessellation_perf__timeline_summary to be unflaky (flutter/flutter#175917)
2025-09-26 1063596+reidbaker@users.noreply.github.com Add kotlin/kgp 2.2.* evaluation criteria.  (flutter/flutter#176094)
2025-09-26 32538273+ValentinVignal@users.noreply.github.com Migrate to `WidgetStateMouseCursor` (flutter/flutter#175981)
2025-09-26 engine-flutter-autoroll@skia.org Roll Packages from 117bf63 to 389c678 (4 revisions) (flutter/flutter#176092)
2025-09-26 34871572+gmackall@users.noreply.github.com Fix link to .gclient setup instructions (flutter/flutter#176046)
2025-09-26 matt.kosarek@canonical.com Implement Regular Windows for the win32 framework + add an example application for regular windows (flutter/flutter#173715)
2025-09-26 engine-flutter-autoroll@skia.org Roll Skia from 5d99c3fc7c83 to 96b73f61fe61 (3 revisions) (flutter/flutter#176075)
2025-09-26 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from naeytagBIBEpKgZNZ... to 0Z45OXT_Wb8aWI3a0... (flutter/flutter#176068)
2025-09-26 100504385+AlsoShantanuBorkar@users.noreply.github.com Add itemClipBehavior property for CarouselView's children (flutter/flutter#175324)
2025-09-26 engine-flutter-autoroll@skia.org Roll Skia from 55436d87e414 to 5d99c3fc7c83 (4 revisions) (flutter/flutter#176060)
2025-09-26 flar@google.com Revert "[Impeller] Optimize scale translate rectangle transforms" (flutter/flutter#176061)
2025-09-25 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Reapply "Update the AccessibilityPlugin::Announce method to account f… (#174365)" (flutter/flutter#176059)
2025-09-25 ahmedsameha1@gmail.com Make sure that a CupertinoDesktopTextSelectionToolbarButton doesn't c… (flutter/flutter#173894)
2025-09-25 mohellebiabdessalem@gmail.com Improve code quality in `SensitiveContentPluginTest.java` (flutter/flutter#175721)

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 stuartmorgan@google.com 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:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
...
bufffun pushed a commit to bufffun/flutter that referenced this pull request Oct 3, 2025
…plication for regular windows (flutter#173715)

## What's new?
- Implement and test `_window_win32.dart`, the Win32 implementation of
`_window.dart` 🎉
- Wrote a bunch of tests in `window_win32_test.dart` which uses a mock
API barrier to mock the native Win32 layer
- Update `BaseWindowController` to extend `ChangeNotifier` and use it to
inform the `WindowScope` of when things change
- Made `RegularWindowController.empty()` a non-internal constructor, as
it is needed by implementations
- Added a _large_ example application for windowing where users can test
out different windowing concepts and see how they work!

To test, simply run the tests or try out the example app!

## 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.
@MominRaza
Copy link

Example app is giving below error

flutter run
Launching lib\main.dart on Windows in debug mode...
Building Windows application...                                     9.1s
✓ Built build\windows\x64\runner\Debug\multiple_windows.exe
[ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: 'package:flutter/src/widgets/binding.dart': Failed assertion: line 1752 pos 12: '_child != null': is not true.
#0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:67:4)
#1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:49:5)
#2      RootElement.mount (package:flutter/src/widgets/binding.dart:1752:12)
#3      RootWidget.attach.<anonymous closure> (package:flutter/src/widgets/binding.dart:1704:18)
#4      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:3101:19)
#5      RootWidget.attach (package:flutter/src/widgets/binding.dart:1703:13)
#6      WidgetsBinding.attachToBuildOwner (package:flutter/src/widgets/binding.dart:1379:27)
#7      WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:1364:5)
#8      WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:1350:7)
#9      Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
#10     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:423:19)
#11     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:454:5)
#12     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)

Syncing files to device Windows...                                 101ms

@mattkae
Copy link
Contributor Author

mattkae commented Oct 10, 2025

Example app is giving below error

flutter run
Launching lib\main.dart on Windows in debug mode...
Building Windows application...                                     9.1s
✓ Built build\windows\x64\runner\Debug\multiple_windows.exe
[ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: 'package:flutter/src/widgets/binding.dart': Failed assertion: line 1752 pos 12: '_child != null': is not true.
#0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:67:4)
#1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:49:5)
#2      RootElement.mount (package:flutter/src/widgets/binding.dart:1752:12)
#3      RootWidget.attach.<anonymous closure> (package:flutter/src/widgets/binding.dart:1704:18)
#4      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:3101:19)
#5      RootWidget.attach (package:flutter/src/widgets/binding.dart:1703:13)
#6      WidgetsBinding.attachToBuildOwner (package:flutter/src/widgets/binding.dart:1379:27)
#7      WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:1364:5)
#8      WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:1350:7)
#9      Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
#10     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:423:19)
#11     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:454:5)
#12     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)

Syncing files to device Windows...                                 101ms

You will have to run this against the locally built engine and pass the feature.

Did you do flutter config --enable-windowing on your machine?

engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: desktop Running on desktop a: tests "flutter test", flutter_test, or one of our tests d: examples Sample code and demos framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants