Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
617 changes: 473 additions & 144 deletions lib/ui/channel_buffers.dart

Large diffs are not rendered by default.

31 changes: 29 additions & 2 deletions lib/ui/hooks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,9 @@ void _updateAccessibilityFeatures(int values) {
// ignore: unused_element
void _dispatchPlatformMessage(String name, ByteData? data, int responseId) {
if (name == ChannelBuffers.kControlChannelName) {
// TODO(ianh): move this logic into ChannelBuffers once we remove onPlatformMessage
try {
channelBuffers.handleMessage(data!);
} catch (ex) {
_printDebug('Message to "$name" caused exception $ex');
} finally {
window._respondToPlatformMessage(responseId, null);
}
Expand Down Expand Up @@ -247,6 +246,10 @@ void _invoke(void callback()?, Zone zone) {
}

/// Invokes [callback] inside the given [zone] passing it [arg].
///
/// The 1 in the name refers to the number of arguments expected by
/// the callback (and thus passed to this function, in addition to the
/// callback itself and the zone in which the callback is executed).
void _invoke1<A>(void callback(A a)?, Zone zone, A arg) {
if (callback == null)
return;
Expand All @@ -260,7 +263,31 @@ void _invoke1<A>(void callback(A a)?, Zone zone, A arg) {
}
}

/// Invokes [callback] inside the given [zone] passing it [arg1] and [arg2].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd note arity 2 inside the docstring to immediately communicate the meaning of 2 in the name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

///
/// The 2 in the name refers to the number of arguments expected by
/// the callback (and thus passed to this function, in addition to the
/// callback itself and the zone in which the callback is executed).
void _invoke2<A1, A2>(void callback(A1 a1, A2 a2)?, Zone zone, A1 arg1, A2 arg2) {
if (callback == null)
return;

assert(zone != null); // ignore: unnecessary_null_comparison

if (identical(zone, Zone.current)) {
callback(arg1, arg2);
} else {
zone.runGuarded(() {
callback(arg1, arg2);
});
}
}

/// Invokes [callback] inside the given [zone] passing it [arg1], [arg2], and [arg3].
///
/// The 3 in the name refers to the number of arguments expected by
/// the callback (and thus passed to this function, in addition to the
/// callback itself and the zone in which the callback is executed).
void _invoke3<A1, A2, A3>(void callback(A1 a1, A2 a2, A3 a3)?, Zone zone, A1 arg1, A2 arg2, A3 arg3) {
if (callback == null)
return;
Expand Down
17 changes: 12 additions & 5 deletions lib/ui/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2273,11 +2273,18 @@ final ByteData _fontChangeMessage = utf8.encoder.convert(
).buffer.asByteData();

FutureOr<void> _sendFontChangeMessage() async {
window.onPlatformMessage?.call(
'flutter/system',
_fontChangeMessage,
(_) {},
);
const String kSystemChannelName = 'flutter/system';
if (window.onPlatformMessage != null) {
_invoke3<String, ByteData?, PlatformMessageResponseCallback>(
window.onPlatformMessage,
window._onPlatformMessageZone,
kSystemChannelName,
_fontChangeMessage,
(ByteData? responseData) { },
);
} else {
channelBuffers.push(kSystemChannelName, _fontChangeMessage, (ByteData? responseData) { });
}
}

String _loadFontFromList(Uint8List list, _Callback<void> callback, String? fontFamily) native 'loadFontFromList';
2 changes: 2 additions & 0 deletions lib/ui/window.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef SemanticsActionCallback = void Function(int id, SemanticsAction action,
typedef PlatformMessageResponseCallback = void Function(ByteData? data);

/// Signature for [Window.onPlatformMessage].
// TODO(ianh): deprecate once framework uses [ChannelBuffers.setListener].
typedef PlatformMessageCallback = void Function(String name, ByteData? data, PlatformMessageResponseCallback? callback);

// Signature for _setNeedsReportTimings.
Expand Down Expand Up @@ -1205,6 +1206,7 @@ class Window {
///
/// The framework invokes this callback in the same zone in which the
/// callback was set.
// TODO(ianh): deprecate once framework uses [ChannelBuffers.setListener].
PlatformMessageCallback? get onPlatformMessage => _onPlatformMessage;
PlatformMessageCallback? _onPlatformMessage;
Zone _onPlatformMessageZone = Zone.root;
Expand Down
4 changes: 0 additions & 4 deletions lib/web_ui/lib/src/engine/keyboard.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,6 @@ class Keyboard {

final html.KeyboardEvent keyboardEvent = event;

if (window._onPlatformMessage == null) {
return;
}

if (_shouldPreventDefault(event)) {
event.preventDefault();
}
Expand Down
48 changes: 21 additions & 27 deletions lib/web_ui/lib/src/engine/navigation/history.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,15 @@ class MultiEntriesBrowserHistory extends BrowserHistory {
currentPath);
}
_lastSeenSerialCount = _currentSerialCount;
if (window._onPlatformMessage != null) {
window.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(
MethodCall('pushRouteInformation', <dynamic, dynamic>{
'location': currentPath,
'state': event.state?['state'],
})),
(_) {},
);
}
window.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(
MethodCall('pushRouteInformation', <dynamic, dynamic>{
'location': currentPath,
'state': event.state?['state'],
})),
(_) {},
);
}

@override
Expand Down Expand Up @@ -272,13 +270,11 @@ class SingleEntryBrowserHistory extends BrowserHistory {
_setupFlutterEntry(urlStrategy!);

// 2. Send a 'popRoute' platform message so the app can handle it accordingly.
if (window._onPlatformMessage != null) {
window.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(_popRouteMethodCall),
(_) {},
);
}
window.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(_popRouteMethodCall),
(_) {},
);
} else if (_isFlutterEntry(event.state)) {
// We get into this scenario when the user changes the url manually. It
// causes a new entry to be pushed on top of our "flutter" one. When this
Expand All @@ -291,15 +287,13 @@ class SingleEntryBrowserHistory extends BrowserHistory {
_userProvidedRouteName = null;

// Send a 'pushRoute' platform message so the app handles it accordingly.
if (window._onPlatformMessage != null) {
window.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(
MethodCall('pushRoute', newRouteName),
),
(_) {},
);
}
window.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(
MethodCall('pushRoute', newRouteName),
),
(_) {},
);
} else {
// The user has pushed a new entry on top of our flutter entry. This could
// happen when the user modifies the hash part of the url directly, for
Expand Down
88 changes: 40 additions & 48 deletions lib/web_ui/lib/src/engine/text_editing/text_editing.dart
Original file line number Diff line number Diff line change
Expand Up @@ -276,21 +276,19 @@ class EngineAutofillForm {

/// Sends the 'TextInputClient.updateEditingStateWithTag' message to the framework.
void _sendAutofillEditingState(String? tag, EditingState editingState) {
if (window._onPlatformMessage != null) {
window.invokeOnPlatformMessage(
'flutter/textinput',
const JSONMethodCodec().encodeMethodCall(
MethodCall(
'TextInputClient.updateEditingStateWithTag',
<dynamic>[
0,
<String?, dynamic>{tag: editingState.toFlutter()}
],
),
window.invokeOnPlatformMessage(
'flutter/textinput',
const JSONMethodCodec().encodeMethodCall(
MethodCall(
'TextInputClient.updateEditingStateWithTag',
<dynamic>[
0,
<String?, dynamic>{tag: editingState.toFlutter()}
],
),
_emptyCallback,
);
}
),
_emptyCallback,
);
}
}

Expand Down Expand Up @@ -1392,50 +1390,44 @@ class TextEditingChannel {

/// Sends the 'TextInputClient.updateEditingState' message to the framework.
void updateEditingState(int? clientId, EditingState? editingState) {
if (window._onPlatformMessage != null) {
window.invokeOnPlatformMessage(
'flutter/textinput',
const JSONMethodCodec().encodeMethodCall(
MethodCall('TextInputClient.updateEditingState', <dynamic>[
clientId,
editingState!.toFlutter(),
]),
),
_emptyCallback,
);
}
window.invokeOnPlatformMessage(
'flutter/textinput',
const JSONMethodCodec().encodeMethodCall(
MethodCall('TextInputClient.updateEditingState', <dynamic>[
clientId,
editingState!.toFlutter(),
]),
),
_emptyCallback,
);
}

/// Sends the 'TextInputClient.performAction' message to the framework.
void performAction(int? clientId, String? inputAction) {
if (window._onPlatformMessage != null) {
window.invokeOnPlatformMessage(
'flutter/textinput',
const JSONMethodCodec().encodeMethodCall(
MethodCall(
'TextInputClient.performAction',
<dynamic>[clientId, inputAction],
),
window.invokeOnPlatformMessage(
'flutter/textinput',
const JSONMethodCodec().encodeMethodCall(
MethodCall(
'TextInputClient.performAction',
<dynamic>[clientId, inputAction],
),
_emptyCallback,
);
}
),
_emptyCallback,
);
}

/// Sends the 'TextInputClient.onConnectionClosed' message to the framework.
void onConnectionClosed(int? clientId) {
if (window._onPlatformMessage != null) {
window.invokeOnPlatformMessage(
'flutter/textinput',
const JSONMethodCodec().encodeMethodCall(
MethodCall(
'TextInputClient.onConnectionClosed',
<dynamic>[clientId],
),
window.invokeOnPlatformMessage(
'flutter/textinput',
const JSONMethodCodec().encodeMethodCall(
MethodCall(
'TextInputClient.onConnectionClosed',
<dynamic>[clientId],
),
_emptyCallback,
);
}
),
_emptyCallback,
);
}
}

Expand Down
25 changes: 12 additions & 13 deletions lib/web_ui/lib/src/engine/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -482,19 +482,18 @@ final ByteData? _fontChangeMessage = JSONMessageCodec().encodeMessage(<String, d
bool _fontChangeScheduled = false;

FutureOr<void> sendFontChangeMessage() async {
if (window._onPlatformMessage != null)
if (!_fontChangeScheduled) {
_fontChangeScheduled = true;
// Batch updates into next animationframe.
html.window.requestAnimationFrame((num _) {
_fontChangeScheduled = false;
window.invokeOnPlatformMessage(
'flutter/system',
_fontChangeMessage,
(_) {},
);
});
}
if (!_fontChangeScheduled) {
_fontChangeScheduled = true;
// Batch updates into next animationframe.
html.window.requestAnimationFrame((num _) {
_fontChangeScheduled = false;
window.invokeOnPlatformMessage(
'flutter/system',
_fontChangeMessage,
(_) {},
);
});
}
}

// Stores matrix in a form that allows zero allocation transforms.
Expand Down
Loading