Skip to content

Commit

Permalink
Remove single view assumptions from window.dart (flutter#38453)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
5 people authored and Ricardo Amador committed Jan 25, 2023
1 parent a9ea00e commit 8780330
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 108 deletions.
51 changes: 40 additions & 11 deletions lib/ui/platform_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,10 @@ class PlatformDispatcher {
final ViewConfiguration previousConfiguration =
_viewConfigurations[id] ?? const ViewConfiguration();
if (!_views.containsKey(id)) {
_views[id] = FlutterWindow._(id, this);
_views[id] = FlutterView._(id, this);
}
_viewConfigurations[id] = previousConfiguration.copyWith(
window: _views[id],
view: _views[id],
devicePixelRatio: devicePixelRatio,
geometry: Rect.fromLTWH(0.0, 0.0, width, height),
viewPadding: WindowPadding._(
Expand Down Expand Up @@ -1289,8 +1289,18 @@ class PlatformConfiguration {
/// An immutable view configuration.
class ViewConfiguration {
/// A const constructor for an immutable [ViewConfiguration].
///
/// When constructing a view configuration, supply either the [view] or the
/// [window] property, but not both since the [view] and [window] property
/// are backed by the same instance variable.
const ViewConfiguration({
this.window,
FlutterView? view,
@Deprecated('''
Use the `view` property instead.
This change is related to adding multi-view support in Flutter.
This feature was deprecated after 3.7.0-1.2.pre.
''')
FlutterView? window,
this.devicePixelRatio = 1.0,
this.geometry = Rect.zero,
this.visible = false,
Expand All @@ -1300,10 +1310,17 @@ class ViewConfiguration {
this.padding = WindowPadding.zero,
this.gestureSettings = const GestureSettings(),
this.displayFeatures = const <DisplayFeature>[],
});
}) : assert(window == null || view == null),
_view = view ?? window;

/// Copy this configuration with some fields replaced.
ViewConfiguration copyWith({
FlutterView? view,
@Deprecated('''
Use the `view` property instead.
This change is related to adding multi-view support in Flutter.
This feature was deprecated after 3.7.0-1.2.pre.
''')
FlutterView? window,
double? devicePixelRatio,
Rect? geometry,
Expand All @@ -1315,8 +1332,9 @@ class ViewConfiguration {
GestureSettings? gestureSettings,
List<DisplayFeature>? displayFeatures,
}) {
assert(view == null || window == null);
return ViewConfiguration(
window: window ?? this.window,
view: view ?? window ?? _view,
devicePixelRatio: devicePixelRatio ?? this.devicePixelRatio,
geometry: geometry ?? this.geometry,
visible: visible ?? this.visible,
Expand All @@ -1329,11 +1347,22 @@ class ViewConfiguration {
);
}

/// The top level view into which the view is placed and its geometry is
/// relative to.
/// The top level view for which this [ViewConfiguration]'s properties apply to.
///
/// If this property is null, this [ViewConfiguration] is a top level view.
@Deprecated('''
Use the `view` property instead.
This change is related to adding multi-view support in Flutter.
This feature was deprecated after 3.7.0-1.2.pre.
''')
FlutterView? get window => _view;

/// The top level view for which this [ViewConfiguration]'s properties apply to.
///
/// If null, then this configuration represents a top level view itself.
final FlutterView? window;
/// If this property is null, this [ViewConfiguration] is a top level view.
FlutterView? get view => _view;

final FlutterView? _view;

/// The pixel density of the output surface.
final double devicePixelRatio;
Expand Down Expand Up @@ -1427,7 +1456,7 @@ class ViewConfiguration {

@override
String toString() {
return '$runtimeType[window: $window, geometry: $geometry]';
return '$runtimeType[view: $view, geometry: $geometry]';
}
}

Expand Down Expand Up @@ -1666,7 +1695,7 @@ enum AppLifecycleState {
/// On Android, this corresponds to an app or the Flutter host view running
/// in the foreground inactive state. Apps transition to this state when
/// another activity is focused, such as a split-screen app, a phone call,
/// a picture-in-picture app, a system dialog, or another window.
/// a picture-in-picture app, a system dialog, or another view.
///
/// Apps in this state should assume that they may be [paused] at any time.
inactive,
Expand Down
59 changes: 15 additions & 44 deletions lib/ui/window.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ part of dart.ui;

/// A view into which a Flutter [Scene] is drawn.
///
/// Each [FlutterView] has its own layer tree that is rendered into an area
/// inside of a [FlutterWindow] whenever [render] is called with a [Scene].
/// Each [FlutterView] has its own layer tree that is rendered
/// whenever [render] is called on it with a [Scene].
///
/// ## Insets and Padding
///
Expand Down Expand Up @@ -51,18 +51,21 @@ part of dart.ui;
/// the [viewPadding] anyway, so there is no need to account for
/// that in the [padding], which is always safe to use for such
/// calculations.
///
/// See also:
///
/// * [FlutterWindow], a special case of a [FlutterView] that is represented on
/// the platform as a separate window which can host other [FlutterView]s.
abstract class FlutterView {
class FlutterView {
FlutterView._(this.viewId, this.platformDispatcher);

/// The opaque ID for this view.
final Object viewId;

/// The platform dispatcher that this view is registered with, and gets its
/// information from.
PlatformDispatcher get platformDispatcher;
final PlatformDispatcher platformDispatcher;

/// The configuration of this view.
ViewConfiguration get viewConfiguration;
ViewConfiguration get viewConfiguration {
assert(platformDispatcher._viewConfigurations.containsKey(viewId));
return platformDispatcher._viewConfigurations[viewId]!;
}

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

/// A top-level platform window displaying a Flutter layer tree drawn from a
/// [Scene].
///
/// The current list of all Flutter views for the application is available from
/// `WidgetsBinding.instance.platformDispatcher.views`. Only views that are of type
/// [FlutterWindow] are top level platform windows.
///
/// There is also a [PlatformDispatcher.instance] singleton object in `dart:ui`
/// if `WidgetsBinding` is unavailable, but we strongly advise avoiding a static
/// reference to it. See the documentation for [PlatformDispatcher.instance] for
/// more details about why it should be avoided.
///
/// See also:
///
/// * [PlatformDispatcher], which manages the current list of [FlutterView] (and
/// thus [FlutterWindow]) instances.
class FlutterWindow extends FlutterView {
FlutterWindow._(this._windowId, this.platformDispatcher);

/// The opaque ID for this view.
final Object _windowId;

@override
final PlatformDispatcher platformDispatcher;

@override
ViewConfiguration get viewConfiguration {
assert(platformDispatcher._viewConfigurations.containsKey(_windowId));
return platformDispatcher._viewConfigurations[_windowId]!;
}
}

/// A [FlutterWindow] that includes access to setting callbacks and retrieving
/// A [FlutterView] that includes access to setting callbacks and retrieving
/// properties that reside on the [PlatformDispatcher].
///
/// It is the type of the global [window] singleton used by applications that
Expand All @@ -328,7 +299,7 @@ class FlutterWindow extends FlutterView {
/// `WidgetsBinding.instance.platformDispatcher` over a static reference to
/// [window], or [PlatformDispatcher.instance]. See the documentation for
/// [PlatformDispatcher.instance] for more details about this recommendation.
class SingletonFlutterWindow extends FlutterWindow {
class SingletonFlutterWindow extends FlutterView {
SingletonFlutterWindow._(super.windowId, super.platformDispatcher)
: super._();

Expand Down
33 changes: 27 additions & 6 deletions lib/web_ui/lib/platform_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,13 @@ class PlatformConfiguration {

class ViewConfiguration {
const ViewConfiguration({
this.window,
FlutterView? view,
@Deprecated('''
Use the `view` property instead.
This change is related to adding multi-view support in Flutter.
This feature was deprecated after 3.7.0-1.2.pre.
''')
FlutterView? window,
this.devicePixelRatio = 1.0,
this.geometry = Rect.zero,
this.visible = false,
Expand All @@ -200,10 +206,17 @@ class ViewConfiguration {
this.padding = WindowPadding.zero,
this.gestureSettings = const GestureSettings(),
this.displayFeatures = const <DisplayFeature>[],
});
}) : assert(window == null || view == null),
_view = view ?? window;

ViewConfiguration copyWith({
FlutterWindow? window,
FlutterView? view,
@Deprecated('''
Use the `view` property instead.
This change is related to adding multi-view support in Flutter.
This feature was deprecated after 3.7.0-1.2.pre.
''')
FlutterView? window,
double? devicePixelRatio,
Rect? geometry,
bool? visible,
Expand All @@ -214,8 +227,9 @@ class ViewConfiguration {
GestureSettings? gestureSettings,
List<DisplayFeature>? displayFeatures,
}) {
assert(view == null || window == null);
return ViewConfiguration(
window: window ?? this.window,
view: view ?? window ?? _view,
devicePixelRatio: devicePixelRatio ?? this.devicePixelRatio,
geometry: geometry ?? this.geometry,
visible: visible ?? this.visible,
Expand All @@ -228,7 +242,14 @@ class ViewConfiguration {
);
}

final FlutterWindow? window;
@Deprecated('''
Use the `view` property instead.
This change is related to adding multi-view support in Flutter.
This feature was deprecated after 3.7.0-1.2.pre.
''')
FlutterView? get window => _view;
FlutterView? get view => _view;
final FlutterView? _view;
final double devicePixelRatio;
final Rect geometry;
final bool visible;
Expand All @@ -241,7 +262,7 @@ class ViewConfiguration {

@override
String toString() {
return '$runtimeType[window: $window, geometry: $geometry]';
return '$runtimeType[view: $view, geometry: $geometry]';
}
}

Expand Down
21 changes: 10 additions & 11 deletions lib/web_ui/lib/src/engine/platform_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,10 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
_onPlatformConfigurationChanged, _onPlatformConfigurationChangedZone);
}

/// The current list of windows,
/// The current list of windows.
@override
Iterable<ui.FlutterView> get views => _windows.values;
Map<Object, ui.FlutterWindow> get windows => _windows;
final Map<Object, ui.FlutterWindow> _windows = <Object, ui.FlutterWindow>{};
Iterable<ui.FlutterView> get views => viewData.values;
final Map<Object, ui.FlutterView> viewData = <Object, ui.FlutterView>{};

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

case 'flutter/navigation':
// TODO(gspencergoog): As multi-window support expands, the navigation call
// will need to include the window ID. Right now only one window is
// TODO(a-wallen): As multi-window support expands, the navigation call
// will need to include the view ID. Right now only one view is
// supported.
(_windows[0]! as EngineFlutterWindow)
(viewData[kSingletonViewId]! as EngineFlutterWindow)
.handleNavigationMessage(data)
.then((bool handled) {
if (handled) {
Expand Down Expand Up @@ -1160,7 +1159,7 @@ class EnginePlatformDispatcher extends ui.PlatformDispatcher {
@override
String get defaultRouteName {
return _defaultRouteName ??=
(_windows[0]! as EngineFlutterWindow).browserHistory.currentPath;
(viewData[kSingletonViewId]! as EngineFlutterWindow).browserHistory.currentPath;
}

/// Lazily initialized when the `defaultRouteName` getter is invoked.
Expand Down
Loading

0 comments on commit 8780330

Please sign in to comment.