-
Notifications
You must be signed in to change notification settings - Fork 6k
[web] De-singletonize MouseCursor for multi-view #45295
Changes from 5 commits
231aedd
f4b93f7
6348d51
567299e
b803c12
c109a91
b29c5f6
1b949ec
48c2216
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,8 @@ import 'package:ui/ui_web/src/ui_web.dart' as ui_web; | |
| import '../engine.dart' show DimensionsProvider, registerHotRestartListener, renderer; | ||
| import 'display.dart'; | ||
| import 'dom.dart'; | ||
| import 'embedder.dart'; | ||
| import 'mouse/cursor.dart'; | ||
| import 'navigation/history.dart'; | ||
| import 'platform_dispatcher.dart'; | ||
| import 'services.dart'; | ||
|
|
@@ -29,8 +31,17 @@ const bool debugPrintPlatformMessages = false; | |
| /// The view ID for the implicit flutter view provided by the platform. | ||
| const int kImplicitViewId = 0; | ||
|
|
||
| /// Represents all views in the Flutter Web Engine. | ||
| /// | ||
| /// In addition to everything defined in [ui.FlutterView], this class adds | ||
| /// a few web-specific properties. | ||
| abstract class EngineFlutterView extends ui.FlutterView { | ||
|
||
| MouseCursor get mouseCursor; | ||
| DomElement get rootElement; | ||
| } | ||
|
|
||
| /// The Web implementation of [ui.SingletonFlutterWindow]. | ||
| class EngineFlutterWindow extends ui.SingletonFlutterWindow { | ||
| class EngineFlutterWindow extends ui.SingletonFlutterWindow implements EngineFlutterView { | ||
| EngineFlutterWindow(this.viewId, this.platformDispatcher) { | ||
| platformDispatcher.viewData[viewId] = this; | ||
| platformDispatcher.windowConfigurations[viewId] = const ViewConfiguration(); | ||
|
|
@@ -53,6 +64,12 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { | |
| @override | ||
| final EnginePlatformDispatcher platformDispatcher; | ||
|
|
||
| @override | ||
| late final MouseCursor mouseCursor = MouseCursor(this); | ||
ditman marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| @override | ||
| DomElement get rootElement => flutterViewEmbedder.flutterViewElement; | ||
|
|
||
| /// Handles the browser history integration to allow users to use the back | ||
| /// button, etc. | ||
| BrowserHistory get browserHistory { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| import 'package:test/bootstrap/browser.dart'; | ||
| import 'package:test/test.dart'; | ||
| import 'package:ui/src/engine.dart'; | ||
| import 'package:ui/ui.dart' as ui; | ||
|
|
||
| void main() { | ||
| internalBootstrapBrowserTest(() => testMain); | ||
| } | ||
|
|
||
| void testMain() { | ||
| group('$MouseCursor', () { | ||
| test('sets correct `cursor` style on root element', () { | ||
| final DomElement rootViewElement = createDomElement('div'); | ||
| final MockFlutterView view = MockFlutterView() | ||
| ..rootElement = rootViewElement; | ||
| final MouseCursor mouseCursor = MouseCursor(view); | ||
|
|
||
| mouseCursor.activateSystemCursor('alias'); | ||
| expect(rootViewElement.style.cursor, 'alias'); | ||
|
|
||
| mouseCursor.activateSystemCursor('move'); | ||
| expect(rootViewElement.style.cursor, 'move'); | ||
|
|
||
| mouseCursor.activateSystemCursor('precise'); | ||
| expect(rootViewElement.style.cursor, 'crosshair'); | ||
|
|
||
| mouseCursor.activateSystemCursor('resizeDownRight'); | ||
| expect(rootViewElement.style.cursor, 'se-resize'); | ||
| }); | ||
|
|
||
| test('handles unknown cursor type', () { | ||
| final DomElement rootViewElement = createDomElement('div'); | ||
| final MockFlutterView view = MockFlutterView() | ||
| ..rootElement = rootViewElement; | ||
| final MouseCursor mouseCursor = MouseCursor(view); | ||
|
|
||
| mouseCursor.activateSystemCursor('unknown'); | ||
| expect(rootViewElement.style.cursor, 'default'); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| class MockFlutterView implements EngineFlutterView { | ||
| @override | ||
| late DomElement rootElement; | ||
|
|
||
| @override | ||
| double get devicePixelRatio => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| ui.Display get display => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| List<ui.DisplayFeature> get displayFeatures => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| ui.GestureSettings get gestureSettings => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| MouseCursor get mouseCursor => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| ViewPadding get padding => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| ui.Rect get physicalGeometry => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| ui.Size get physicalSize => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| ui.PlatformDispatcher get platformDispatcher => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| void render(ui.Scene scene) { | ||
| throw UnimplementedError(); | ||
| } | ||
|
|
||
| @override | ||
| ViewPadding get systemGestureInsets => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| void updateSemantics(ui.SemanticsUpdate update) { | ||
| throw UnimplementedError(); | ||
| } | ||
|
|
||
| @override | ||
| int get viewId => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| ViewPadding get viewInsets => throw UnimplementedError(); | ||
|
|
||
| @override | ||
| ViewPadding get viewPadding => throw UnimplementedError(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that the class that represents all views in the Flutter Web Engine is
EngineFlutterWindow(that's the type that was used to define theimplicitView, for example), right?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EngineFlutterWindowis a misnomer. It should be calledEngineSingletonFlutterWindow(it actually extendsui.SingletonFlutterWindow). Views in the multi-view world shouldn't inherit from this singleton class. They should inherit directly fromui.FlutterView(and implementEngineFlutterViewto satisfy all the web-specific needs).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a follow up PR to rename this class to make it clear that it's a singleton: #45981