Fix broken listener code in WindowScope#189208
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request updates WindowScope to capture snapshots of its controller's aspect values at construction time, enabling proper change detection in updateShouldNotify and updateShouldNotifyDependent when the same controller instance notifies of changes. It also introduces helper methods to compute these aspect values and adds a test verifying that dependents rebuild upon controller notifications. The review feedback highlights several violations of the Flutter Repository Style Guide, pointing out that private members and helper methods should use triple-slash (///) comments instead of double-slash (//) comments for public-quality documentation.
1653937 to
b11a36a
Compare
WindowScope is an InheritedModel that is rebuilt with the same controller instance whenever the controller notifies its listeners. Its updateShouldNotify and updateShouldNotifyDependent compared the live controller's values against oldWidget.controller's values, but since the controller is the same object across rebuilds, those comparisons were always false and dependents never rebuilt. Capture a snapshot of each aspect value in the WindowScope constructor so the old and new widgets hold independent values that can be compared to detect which aspects changed. The per-aspect value computations are extracted into static helpers shared with the *Of accessors.
b11a36a to
3ffcf0b
Compare
| _isActivated = _isActivatedValue(controller), | ||
| _isMaximized = _isMaximizedValue(controller), | ||
| _isMinimized = _isMinimizedValue(controller), | ||
| _isFullscreen = _isFullscreenValue(controller) { |
There was a problem hiding this comment.
Copying my message from the original PR: #189061 (comment)
This isn't a blocker for this PR though, please feel free to land this without addressing this comment.
I see that all our window widgets wrap the controller in a ListenableBuilder to ensure WindowScope rebuilds when the controller changes:
flutter/packages/flutter/lib/src/widgets/_window.dart
Lines 1584 to 1590 in 7152f2b
A drawback of this approach is that if an app developer - for some reason - decides to create a WindowScope manually but forgets the ListenableBuilder, that WindowScope will have stale values.
Would it make sense to instead have WindowScope create the ListenableBuilder itself? That would ensure that you cannot use WindowScope incorrectly.
There was a problem hiding this comment.
Yes, although I also dislike that WindowScope has a public API to begin with, since it really has no reason to be created by someone else most of the time :)
flutter/flutter@dc2a870...f7b66f3 2026-07-10 P.akhrameev@gmail.com [iOS][test] Fix VSyncClient display link deallocation test on iOS 27 (flutter/flutter#188627) 2026-07-10 matt.kosarek@canonical.com Fix broken listener code in WindowScope (flutter/flutter#189208) 2026-07-10 zhongliu88889@gmail.com [web] Preserve text field focus across tab switches (flutter/flutter#188738) 2026-07-10 bdero@google.com [Impeller] Recycle HostBuffer arena entries only after GPU completion (flutter/flutter#188965) 2026-07-10 256906086+mvincentong@users.noreply.github.com Assert TextStyle height is not NaN (flutter/flutter#186617) 2026-07-10 engine-flutter-autoroll@skia.org Roll Fuchsia Test Scripts from dFkTCiDxEtPxYK5Nn... to wLST_A-xfOeGT_5mj... (flutter/flutter#189259) 2026-07-10 engine-flutter-autoroll@skia.org Roll Dart SDK from a11fb7ed40a5 to 0fc1668c4af4 (5 revisions) (flutter/flutter#189257) 2026-07-10 52160996+FMorschel@users.noreply.github.com Adds a missing `await` to a `FutureOr` (flutter/flutter#189198) 2026-07-10 burak.karahan@mail.ru [web] Repair RenderCanvas CSS size drift (flutter/flutter#188797) 2026-07-10 engine-flutter-autoroll@skia.org Roll Fuchsia Test Scripts from s5_gZFJ8De9AJalTw... to dFkTCiDxEtPxYK5Nn... (flutter/flutter#189215) 2026-07-10 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from QcRFUtvCw2EobfJ8s... to czpzDg9ABY2oKLAOY... (flutter/flutter#189222) 2026-07-10 jesswon@google.com Update Depdencies Used By `flutter_engine_group_performance` (flutter/flutter#189229) 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 boetger@google.com,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
What's new?
WindowScope is an InheritedModel that is rebuilt with the same controller instance whenever the controller notifies its listeners. Its updateShouldNotify and updateShouldNotifyDependent compared the live controller's values against oldWidget.controller's values, but since the controller is the same object across rebuilds, those comparisons were always false and dependents never rebuilt.
Capture a snapshot of each aspect value in the WindowScope constructor so the old and new widgets hold independent values that can be compared to detect which aspects changed. The per-aspect value computations are extracted into static helpers shared with the *Of accessors.
Pre-launch Checklist
///).