-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[web] De-singletonize MouseCursor for multi-view #45295
Changes from all 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
/// | ||
/// In addition to everything defined in [ui.FlutterView], this class adds | ||
/// a few web-specific properties. | ||
abstract interface 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(rootElement); | ||
|
||
@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,40 @@ | ||
// 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'; | ||
|
||
void main() { | ||
internalBootstrapBrowserTest(() => testMain); | ||
} | ||
|
||
void testMain() { | ||
group('$MouseCursor', () { | ||
test('sets correct `cursor` style on root element', () { | ||
final DomElement rootViewElement = createDomElement('div'); | ||
final MouseCursor mouseCursor = MouseCursor(rootViewElement); | ||
|
||
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 MouseCursor mouseCursor = MouseCursor(rootViewElement); | ||
|
||
mouseCursor.activateSystemCursor('unknown'); | ||
expect(rootViewElement.style.cursor, 'default'); | ||
}); | ||
}); | ||
} |
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.
The only problem I can imagine with this is that if the
element
gets detached/deleted from the DOM, and then a system cursor event message comes, this might attempt to operate on a null instance. Since this is speculation and not a bug that we've seen so far, I say we don't worry about it for now.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.
That's not a problem at all! The element is non-nullable and cannot become null. Yes, it can be detached/removed from the DOM tree, but it is still a valid element. In fact, in
cursor_test.dart
, we are using detached elements to testMouseCursor
.