@@ -11,15 +11,18 @@ import 'package:meta/meta.dart';
11
11
12
12
extension WindowApi on PlatformDispatcher {
13
13
Iterable <FlutterWindow > get windows => _WindowManager .instance.windows;
14
+ FlutterWindow ? window ({required int id}) => _WindowManager .instance.window (id: id);
14
15
Future <FlutterWindow > createWindow (FlutterWindowRequest request) {
15
16
return _WindowManager .instance.createWindow (request);
16
17
}
17
- VoidCallback ? get onWindowsChanged => _WindowManager .instance.onWindowsChanged;
18
- set onWindowsChanged (VoidCallback ? value) {
18
+ WindowsChangedCallback ? get onWindowsChanged => _WindowManager .instance.onWindowsChanged;
19
+ set onWindowsChanged (WindowsChangedCallback ? value) {
19
20
_WindowManager .instance.onWindowsChanged = value;
20
21
}
21
22
}
22
23
24
+ typedef WindowsChangedCallback = void Function (Iterable <int > windowIds);
25
+
23
26
// This should live on the PlatformDispatcher.
24
27
class _WindowManager {
25
28
_WindowManager ._() {
@@ -32,6 +35,8 @@ class _WindowManager {
32
35
Iterable <FlutterWindow > get windows => _windows.values;
33
36
final Map <int , FlutterWindow > _windows = < int , FlutterWindow > {};
34
37
38
+ FlutterWindow ? window ({required int id}) => _windows[id];
39
+
35
40
Future <FlutterWindow > createWindow (FlutterWindowRequest request) async {
36
41
final int ? windowId = await _windowChannel.invokeMethod <int >('create' , request._encode ());
37
42
if (windowId == null ) {
@@ -44,12 +49,12 @@ class _WindowManager {
44
49
return window;
45
50
}
46
51
47
- VoidCallback ? onWindowsChanged;
52
+ WindowsChangedCallback ? onWindowsChanged;
48
53
49
54
static const MethodChannel _windowChannel = MethodChannel ('flutter/window' );
50
55
51
56
Future <Object ?> _handleChannelInvocation (MethodCall call) async {
52
- bool invokeCallback = true ;
57
+ final List < int > ids = < int > [] ;
53
58
switch (call.method) {
54
59
case 'update' :
55
60
final Map <String , Object > args = call.arguments as Map <String , Object >;
@@ -62,20 +67,24 @@ class _WindowManager {
62
67
} else {
63
68
_windows[windowId] = FlutterWindow ._(windowId, config, view);
64
69
}
70
+ ids.add (windowId);
65
71
case 'delete' :
66
- invokeCallback = _windows.remove (call.arguments) != null ;
72
+ final int windowId = call.arguments as int ;
73
+ if (_windows.remove (windowId) != null ) {
74
+ ids.add (windowId);
75
+ }
67
76
}
68
- if (invokeCallback ) {
69
- onWindowsChanged? .call ();
77
+ if (ids.isNotEmpty ) {
78
+ onWindowsChanged? .call (ids );
70
79
}
71
80
return null ;
72
81
}
73
82
}
74
83
75
84
class FlutterWindow {
76
- FlutterWindow ._(this ._id , this ._config, this ._view);
85
+ FlutterWindow ._(this .id , this ._config, this ._view);
77
86
78
- final int _id ;
87
+ final int id ;
79
88
_FlutterWindowConfiguration _config;
80
89
FlutterView _view;
81
90
@@ -86,28 +95,33 @@ class FlutterWindow {
86
95
87
96
FlutterView get view => _view;
88
97
Size get contentSize => _config.contentSize;
98
+ RelativeOffset get contentLocation => _config.contentLocation;
89
99
90
100
Future <void > requestUpdate (FlutterWindowRequest request) async {
91
- await _WindowManager ._windowChannel.invokeMethod ('update' , < String , Object ? > {'id' : _id , 'request' : request._encode ()});
101
+ await _WindowManager ._windowChannel.invokeMethod ('update' , < String , Object ? > {'id' : id , 'request' : request._encode ()});
92
102
}
93
103
94
104
Future <void > close () async {
95
- await _WindowManager ._windowChannel.invokeMethod ('close' , _id );
105
+ await _WindowManager ._windowChannel.invokeMethod ('close' , id );
96
106
}
97
107
}
98
108
99
109
// Everything is in physical pixel!
100
110
@immutable
101
111
class FlutterWindowRequest {
102
- const FlutterWindowRequest ({this .contentOffset, this .contentConstraints, this .allowPointerEvents});
112
+ const FlutterWindowRequest ({
113
+ this .contentLocation,
114
+ this .contentConstraints,
115
+ this .allowPointerEvents,
116
+ });
103
117
104
- final RelativeOffset ? contentOffset ;
118
+ final RelativeOffset ? contentLocation ;
105
119
final ViewConstraints ? contentConstraints;
106
120
final bool ? allowPointerEvents;
107
121
108
122
Object ? _encode () {
109
123
return < String , Object ? > {
110
- 'offset ' : contentOffset ? ._encode (),
124
+ 'location ' : contentLocation ? ._encode (),
111
125
'constraint_min_width' : contentConstraints? .minWidth,
112
126
'constraint_max_width' : contentConstraints? .maxWidth,
113
127
'constraint_min_height' : contentConstraints? .minHeight,
@@ -122,27 +136,28 @@ class _FlutterWindowConfiguration {
122
136
const _FlutterWindowConfiguration ({
123
137
required this .viewId,
124
138
required this .contentSize,
125
- required this .contentOffset ,
139
+ required this .contentLocation ,
126
140
});
127
141
128
142
factory _FlutterWindowConfiguration .decode (Object encoded) {
129
143
final Map <String , Object ?> decoded = encoded as Map <String , Object ?>;
130
144
return _FlutterWindowConfiguration (
131
145
viewId: decoded['viewId' ]! as int ,
132
146
contentSize: Size (decoded['width' ]! as double , decoded['height' ]! as double ),
133
- contentOffset : RelativeOffset ._decode (decoded['offset' ]! ),
147
+ contentLocation : RelativeOffset ._decode (decoded['offset' ]! ),
134
148
);
135
149
}
136
150
137
151
final int viewId;
138
152
final Size contentSize;
139
- final RelativeOffset contentOffset ;
153
+ final RelativeOffset contentLocation ;
140
154
}
141
155
142
156
@immutable
143
157
class RelativeOffset {
144
158
const RelativeOffset .display (Display this .display, this .offset) : view = null ;
145
159
const RelativeOffset .view (FlutterView this .view, this .offset) : display = null ;
160
+ const RelativeOffset ._(this .view, this .display, this .offset) : assert (view == null || display == null );
146
161
147
162
factory RelativeOffset ._decode (Object encoded) {
148
163
final Map <String , Object ?> decoded = encoded as Map <String , Object ?>;
@@ -169,6 +184,9 @@ class RelativeOffset {
169
184
170
185
double get devicePixelRatio => view? .devicePixelRatio ?? display? .devicePixelRatio ?? 1.0 ;
171
186
187
+ RelativeOffset operator * (double operand) => RelativeOffset ._(view, display, offset * operand);
188
+ RelativeOffset operator / (double operand) => RelativeOffset ._(view, display, offset / operand);
189
+
172
190
Object _encode () {
173
191
return < String , Object ? > {
174
192
'type' : view == null ? 'display' : 'view' ,
0 commit comments