Skip to content

Commit 8780330

Browse files
a-wallena-wallenloic-sharmagoderbauerditman
authored andcommitted
Remove single view assumptions from window.dart (flutter#38453)
* Refactor `window.dart` * Remove single window assumption from platform dispatcher * Expose viewId * Remove FlutterWindow from web_ui * Refactor EngineFlutterWindow to inherit from FlutterView * Rename window property * Undo Iterable -> Map conversion * Add window and deprecate it so that the change isn't breaking * Name resolution * Revisions * Doc changes * Refactor deprecation message * Newline * Expose getViewById, hide map interface * Fix compilaiton errors * Introduce addView API * Change deprecation message * Update lib/ui/window.dart Co-authored-by: Loïc Sharma <[email protected]> * Take greg's todos * Add mutual exclusion assertion * Fix trailing whitespace lint * Use only one property to store backing view * Add doc comment to view * Document view and window parameters in the constructor of ViewConfiguration * Sync web api * Refactor assertion * Improve deprecation message * Improve window documentation * Assert one of window/view is null in copyWith ViewConfiguration * Remove EngineFlutterWindowView * Make dartdoc happy * Refactor copyWith() * Change to internal map implementation * final private refactor Co-authored-by: Michael Goderbauer <[email protected]> * Deprecate window parameter in copyWith * Repl Window w/ View * Add tests for viewConfiguration * Make test descriptions better * Add ViewConfiguration initialization with window tests * Update lib/web_ui/lib/src/engine/window.dart Co-authored-by: David Iglesias <[email protected]> * Refactor TODO message * Add expectation :) * Fix viewId in window.dart * Remove double deprecation access * punctuation Co-authored-by: Loïc Sharma <[email protected]> * Add kSingletonWindowID const Co-authored-by: a-wallen <[email protected]> Co-authored-by: Loïc Sharma <[email protected]> Co-authored-by: Michael Goderbauer <[email protected]> Co-authored-by: David Iglesias <[email protected]>
1 parent a9ea00e commit 8780330

File tree

10 files changed

+187
-108
lines changed

10 files changed

+187
-108
lines changed

lib/ui/platform_dispatcher.dart

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,10 @@ class PlatformDispatcher {
222222
final ViewConfiguration previousConfiguration =
223223
_viewConfigurations[id] ?? const ViewConfiguration();
224224
if (!_views.containsKey(id)) {
225-
_views[id] = FlutterWindow._(id, this);
225+
_views[id] = FlutterView._(id, this);
226226
}
227227
_viewConfigurations[id] = previousConfiguration.copyWith(
228-
window: _views[id],
228+
view: _views[id],
229229
devicePixelRatio: devicePixelRatio,
230230
geometry: Rect.fromLTWH(0.0, 0.0, width, height),
231231
viewPadding: WindowPadding._(
@@ -1289,8 +1289,18 @@ class PlatformConfiguration {
12891289
/// An immutable view configuration.
12901290
class ViewConfiguration {
12911291
/// A const constructor for an immutable [ViewConfiguration].
1292+
///
1293+
/// When constructing a view configuration, supply either the [view] or the
1294+
/// [window] property, but not both since the [view] and [window] property
1295+
/// are backed by the same instance variable.
12921296
const ViewConfiguration({
1293-
this.window,
1297+
FlutterView? view,
1298+
@Deprecated('''
1299+
Use the `view` property instead.
1300+
This change is related to adding multi-view support in Flutter.
1301+
This feature was deprecated after 3.7.0-1.2.pre.
1302+
''')
1303+
FlutterView? window,
12941304
this.devicePixelRatio = 1.0,
12951305
this.geometry = Rect.zero,
12961306
this.visible = false,
@@ -1300,10 +1310,17 @@ class ViewConfiguration {
13001310
this.padding = WindowPadding.zero,
13011311
this.gestureSettings = const GestureSettings(),
13021312
this.displayFeatures = const <DisplayFeature>[],
1303-
});
1313+
}) : assert(window == null || view == null),
1314+
_view = view ?? window;
13041315

13051316
/// Copy this configuration with some fields replaced.
13061317
ViewConfiguration copyWith({
1318+
FlutterView? view,
1319+
@Deprecated('''
1320+
Use the `view` property instead.
1321+
This change is related to adding multi-view support in Flutter.
1322+
This feature was deprecated after 3.7.0-1.2.pre.
1323+
''')
13071324
FlutterView? window,
13081325
double? devicePixelRatio,
13091326
Rect? geometry,
@@ -1315,8 +1332,9 @@ class ViewConfiguration {
13151332
GestureSettings? gestureSettings,
13161333
List<DisplayFeature>? displayFeatures,
13171334
}) {
1335+
assert(view == null || window == null);
13181336
return ViewConfiguration(
1319-
window: window ?? this.window,
1337+
view: view ?? window ?? _view,
13201338
devicePixelRatio: devicePixelRatio ?? this.devicePixelRatio,
13211339
geometry: geometry ?? this.geometry,
13221340
visible: visible ?? this.visible,
@@ -1329,11 +1347,22 @@ class ViewConfiguration {
13291347
);
13301348
}
13311349

1332-
/// The top level view into which the view is placed and its geometry is
1333-
/// relative to.
1350+
/// The top level view for which this [ViewConfiguration]'s properties apply to.
1351+
///
1352+
/// If this property is null, this [ViewConfiguration] is a top level view.
1353+
@Deprecated('''
1354+
Use the `view` property instead.
1355+
This change is related to adding multi-view support in Flutter.
1356+
This feature was deprecated after 3.7.0-1.2.pre.
1357+
''')
1358+
FlutterView? get window => _view;
1359+
1360+
/// The top level view for which this [ViewConfiguration]'s properties apply to.
13341361
///
1335-
/// If null, then this configuration represents a top level view itself.
1336-
final FlutterView? window;
1362+
/// If this property is null, this [ViewConfiguration] is a top level view.
1363+
FlutterView? get view => _view;
1364+
1365+
final FlutterView? _view;
13371366

13381367
/// The pixel density of the output surface.
13391368
final double devicePixelRatio;
@@ -1427,7 +1456,7 @@ class ViewConfiguration {
14271456

14281457
@override
14291458
String toString() {
1430-
return '$runtimeType[window: $window, geometry: $geometry]';
1459+
return '$runtimeType[view: $view, geometry: $geometry]';
14311460
}
14321461
}
14331462

@@ -1666,7 +1695,7 @@ enum AppLifecycleState {
16661695
/// On Android, this corresponds to an app or the Flutter host view running
16671696
/// in the foreground inactive state. Apps transition to this state when
16681697
/// another activity is focused, such as a split-screen app, a phone call,
1669-
/// a picture-in-picture app, a system dialog, or another window.
1698+
/// a picture-in-picture app, a system dialog, or another view.
16701699
///
16711700
/// Apps in this state should assume that they may be [paused] at any time.
16721701
inactive,

lib/ui/window.dart

Lines changed: 15 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ part of dart.ui;
55

66
/// A view into which a Flutter [Scene] is drawn.
77
///
8-
/// Each [FlutterView] has its own layer tree that is rendered into an area
9-
/// inside of a [FlutterWindow] whenever [render] is called with a [Scene].
8+
/// Each [FlutterView] has its own layer tree that is rendered
9+
/// whenever [render] is called on it with a [Scene].
1010
///
1111
/// ## Insets and Padding
1212
///
@@ -51,18 +51,21 @@ part of dart.ui;
5151
/// the [viewPadding] anyway, so there is no need to account for
5252
/// that in the [padding], which is always safe to use for such
5353
/// calculations.
54-
///
55-
/// See also:
56-
///
57-
/// * [FlutterWindow], a special case of a [FlutterView] that is represented on
58-
/// the platform as a separate window which can host other [FlutterView]s.
59-
abstract class FlutterView {
54+
class FlutterView {
55+
FlutterView._(this.viewId, this.platformDispatcher);
56+
57+
/// The opaque ID for this view.
58+
final Object viewId;
59+
6060
/// The platform dispatcher that this view is registered with, and gets its
6161
/// information from.
62-
PlatformDispatcher get platformDispatcher;
62+
final PlatformDispatcher platformDispatcher;
6363

6464
/// The configuration of this view.
65-
ViewConfiguration get viewConfiguration;
65+
ViewConfiguration get viewConfiguration {
66+
assert(platformDispatcher._viewConfigurations.containsKey(viewId));
67+
return platformDispatcher._viewConfigurations[viewId]!;
68+
}
6669

6770
/// The number of device pixels for each logical pixel for the screen this
6871
/// view is displayed on.
@@ -281,39 +284,7 @@ abstract class FlutterView {
281284
external static void _updateSemantics(SemanticsUpdate update);
282285
}
283286

284-
/// A top-level platform window displaying a Flutter layer tree drawn from a
285-
/// [Scene].
286-
///
287-
/// The current list of all Flutter views for the application is available from
288-
/// `WidgetsBinding.instance.platformDispatcher.views`. Only views that are of type
289-
/// [FlutterWindow] are top level platform windows.
290-
///
291-
/// There is also a [PlatformDispatcher.instance] singleton object in `dart:ui`
292-
/// if `WidgetsBinding` is unavailable, but we strongly advise avoiding a static
293-
/// reference to it. See the documentation for [PlatformDispatcher.instance] for
294-
/// more details about why it should be avoided.
295-
///
296-
/// See also:
297-
///
298-
/// * [PlatformDispatcher], which manages the current list of [FlutterView] (and
299-
/// thus [FlutterWindow]) instances.
300-
class FlutterWindow extends FlutterView {
301-
FlutterWindow._(this._windowId, this.platformDispatcher);
302-
303-
/// The opaque ID for this view.
304-
final Object _windowId;
305-
306-
@override
307-
final PlatformDispatcher platformDispatcher;
308-
309-
@override
310-
ViewConfiguration get viewConfiguration {
311-
assert(platformDispatcher._viewConfigurations.containsKey(_windowId));
312-
return platformDispatcher._viewConfigurations[_windowId]!;
313-
}
314-
}
315-
316-
/// A [FlutterWindow] that includes access to setting callbacks and retrieving
287+
/// A [FlutterView] that includes access to setting callbacks and retrieving
317288
/// properties that reside on the [PlatformDispatcher].
318289
///
319290
/// It is the type of the global [window] singleton used by applications that
@@ -328,7 +299,7 @@ class FlutterWindow extends FlutterView {
328299
/// `WidgetsBinding.instance.platformDispatcher` over a static reference to
329300
/// [window], or [PlatformDispatcher.instance]. See the documentation for
330301
/// [PlatformDispatcher.instance] for more details about this recommendation.
331-
class SingletonFlutterWindow extends FlutterWindow {
302+
class SingletonFlutterWindow extends FlutterView {
332303
SingletonFlutterWindow._(super.windowId, super.platformDispatcher)
333304
: super._();
334305

lib/web_ui/lib/platform_dispatcher.dart

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,13 @@ class PlatformConfiguration {
190190

191191
class ViewConfiguration {
192192
const ViewConfiguration({
193-
this.window,
193+
FlutterView? view,
194+
@Deprecated('''
195+
Use the `view` property instead.
196+
This change is related to adding multi-view support in Flutter.
197+
This feature was deprecated after 3.7.0-1.2.pre.
198+
''')
199+
FlutterView? window,
194200
this.devicePixelRatio = 1.0,
195201
this.geometry = Rect.zero,
196202
this.visible = false,
@@ -200,10 +206,17 @@ class ViewConfiguration {
200206
this.padding = WindowPadding.zero,
201207
this.gestureSettings = const GestureSettings(),
202208
this.displayFeatures = const <DisplayFeature>[],
203-
});
209+
}) : assert(window == null || view == null),
210+
_view = view ?? window;
204211

205212
ViewConfiguration copyWith({
206-
FlutterWindow? window,
213+
FlutterView? view,
214+
@Deprecated('''
215+
Use the `view` property instead.
216+
This change is related to adding multi-view support in Flutter.
217+
This feature was deprecated after 3.7.0-1.2.pre.
218+
''')
219+
FlutterView? window,
207220
double? devicePixelRatio,
208221
Rect? geometry,
209222
bool? visible,
@@ -214,8 +227,9 @@ class ViewConfiguration {
214227
GestureSettings? gestureSettings,
215228
List<DisplayFeature>? displayFeatures,
216229
}) {
230+
assert(view == null || window == null);
217231
return ViewConfiguration(
218-
window: window ?? this.window,
232+
view: view ?? window ?? _view,
219233
devicePixelRatio: devicePixelRatio ?? this.devicePixelRatio,
220234
geometry: geometry ?? this.geometry,
221235
visible: visible ?? this.visible,
@@ -228,7 +242,14 @@ class ViewConfiguration {
228242
);
229243
}
230244

231-
final FlutterWindow? window;
245+
@Deprecated('''
246+
Use the `view` property instead.
247+
This change is related to adding multi-view support in Flutter.
248+
This feature was deprecated after 3.7.0-1.2.pre.
249+
''')
250+
FlutterView? get window => _view;
251+
FlutterView? get view => _view;
252+
final FlutterView? _view;
232253
final double devicePixelRatio;
233254
final Rect geometry;
234255
final bool visible;
@@ -241,7 +262,7 @@ class ViewConfiguration {
241262

242263
@override
243264
String toString() {
244-
return '$runtimeType[window: $window, geometry: $geometry]';
265+
return '$runtimeType[view: $view, geometry: $geometry]';
245266
}
246267
}
247268

lib/web_ui/lib/src/engine/platform_dispatcher.dart

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,10 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
136136
_onPlatformConfigurationChanged, _onPlatformConfigurationChangedZone);
137137
}
138138

139-
/// The current list of windows,
139+
/// The current list of windows.
140140
@override
141-
Iterable<ui.FlutterView> get views => _windows.values;
142-
Map<Object, ui.FlutterWindow> get windows => _windows;
143-
final Map<Object, ui.FlutterWindow> _windows = <Object, ui.FlutterWindow>{};
141+
Iterable<ui.FlutterView> get views => viewData.values;
142+
final Map<Object, ui.FlutterView> viewData = <Object, ui.FlutterView>{};
144143

145144
/// A map of opaque platform window identifiers to window configurations.
146145
///
@@ -478,10 +477,10 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
478477
final MethodCall decoded = codec.decodeMethodCall(data);
479478
switch (decoded.method) {
480479
case 'SystemNavigator.pop':
481-
// TODO(gspencergoog): As multi-window support expands, the pop call
482-
// will need to include the window ID. Right now only one window is
480+
// TODO(a-wallen): As multi-window support expands, the pop call
481+
// will need to include the view ID. Right now only one view is
483482
// supported.
484-
(_windows[0]! as EngineFlutterWindow)
483+
(viewData[kSingletonViewId]! as EngineFlutterWindow)
485484
.browserHistory
486485
.exit()
487486
.then((_) {
@@ -568,10 +567,10 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
568567
return;
569568

570569
case 'flutter/navigation':
571-
// TODO(gspencergoog): As multi-window support expands, the navigation call
572-
// will need to include the window ID. Right now only one window is
570+
// TODO(a-wallen): As multi-window support expands, the navigation call
571+
// will need to include the view ID. Right now only one view is
573572
// supported.
574-
(_windows[0]! as EngineFlutterWindow)
573+
(viewData[kSingletonViewId]! as EngineFlutterWindow)
575574
.handleNavigationMessage(data)
576575
.then((bool handled) {
577576
if (handled) {
@@ -1160,7 +1159,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
11601159
@override
11611160
String get defaultRouteName {
11621161
return _defaultRouteName ??=
1163-
(_windows[0]! as EngineFlutterWindow).browserHistory.currentPath;
1162+
(viewData[kSingletonViewId]! as EngineFlutterWindow).browserHistory.currentPath;
11641163
}
11651164

11661165
/// Lazily initialized when the `defaultRouteName` getter is invoked.

0 commit comments

Comments
 (0)