inset_embedder/client.rs
1//! Flutter counterpart: `dart:ui` `hooks.dart`.
2//!
3//! Dart's hooks are isolate-global functions the engine calls. Here they are
4//! methods on the embedder client so a host crate need not name `App`.
5
6use std::time::Duration;
7
8use crate::{
9 AppExitReply, AppExitResponse, AppLifecycleState, ClipboardEvent, DragReport, EditCommand,
10 Frame, KeyData, MenuId, NotificationActivation, OpenRequest, PointerReport, TextEditingValue,
11 TextInputAction, TrayIconEvent, TrayIconId, ViewFocusEvent, ViewId,
12};
13
14/// Complete frames and typed view lifecycle notifications.
15///
16/// The platform updates its view registry before sending a lifecycle method,
17/// so the client can immediately query the affected view.
18pub trait EmbedderClient {
19 /// A screen refreshed at `frame.elapsed`: `views` are the views on it, in sight, that asked
20 /// for a frame ([`Platform::request_frame`](crate::Platform::request_frame)) before the
21 /// refresh began; one that asks during it is in the next.
22 ///
23 /// The host never calls it from inside another call into the client.
24 fn frame(&mut self, views: &[ViewId], frame: Frame);
25
26 /// A view arrived after launch: opened by the app, or given by the system. The views that
27 /// exist at launch are in `Platform::views` when the app starts, and none of them is
28 /// reported here.
29 fn view_added(&mut self, id: ViewId);
30
31 /// Flutter's window metrics event: something of `id`'s metrics changed, the screen it is on
32 /// included.
33 fn view_metrics_changed(&mut self, id: ViewId);
34
35 /// A view is gone; the app keeps running.
36 fn view_removed(&mut self, id: ViewId);
37
38 /// Flutter `FlutterEngineNotifyDisplayUpdate`: a screen was added, removed or changed, and
39 /// `Platform::screens` already answers the new list. A view that is on another screen now
40 /// is reported through `view_metrics_changed`. The default drops it.
41 fn screens_changed(&mut self) {}
42
43 /// Flutter `PlatformDispatcher.onViewFocusChange`.
44 fn view_focus_changed(&mut self, event: ViewFocusEvent) {
45 let _ = event;
46 }
47
48 /// What pointing devices did, as the system reported it, in the order it happened: the
49 /// embedder API's `FlutterEngineSendPointerEvent`. The client adds what the framework also
50 /// needs ([`PointerDataPacketConverter`](crate::PointerDataPacketConverter)) and hands the
51 /// result to `PlatformDispatcher.onPointerDataPacket`.
52 fn pointer_reports(&mut self, reports: Vec<PointerReport>);
53
54 /// What is dragged from outside the application entered, moved over, was dropped on or
55 /// left a view: the dropped report is the one its items are read in. No dart:ui hook; the
56 /// default drops it.
57 fn drag_report(&mut self, report: DragReport) {
58 let _ = report;
59 }
60
61 /// The user copied, cut or pasted in `view` through the platform's own command: the
62 /// browser's, or a desktop's Edit menu, which a key reaches only once the framework has left
63 /// it unhandled. No dart:ui hook; the default drops it.
64 fn clipboard_event(&mut self, view: ViewId, event: ClipboardEvent) {
65 let _ = (view, event);
66 }
67
68 /// The user chose an edit command for `view` from the system's own Edit menu, which a key
69 /// reaches only once the framework has left it unhandled: undo, redo, select all or delete.
70 /// No dart:ui hook; the default drops it.
71 fn edit_command(&mut self, view: ViewId, command: EditCommand) {
72 let _ = (view, command);
73 }
74
75 /// The user chose the item `id` of the app's menu bar (`MenuBar::set_menus`). Flutter's
76 /// `Menu.selectedCallback` on the `flutter/menu` channel. The default drops it.
77 fn menu_selected(&mut self, id: MenuId) {
78 let _ = id;
79 }
80
81 /// The user chose the item `id` of the Dock icon's menu (`DockMenu::set_menu`). No dart:ui
82 /// hook; the default drops it.
83 fn dock_menu_selected(&mut self, id: MenuId) {
84 let _ = id;
85 }
86
87 /// Something happened to the tray icon `icon`, as its system reports it. No dart:ui hook; the
88 /// default drops it.
89 fn tray_icon_event(&mut self, icon: TrayIconId, event: TrayIconEvent) {
90 let _ = (icon, event);
91 }
92
93 /// The system asks the app to open files and links: from the file manager, another app or
94 /// the command line, at launch or while it runs. A launch's request comes once the client
95 /// exists. No dart:ui hook: Flutter's embedders hand these to their plugins. The default drops
96 /// it.
97 fn open_requested(&mut self, request: OpenRequest) {
98 let _ = request;
99 }
100
101 /// The user clicked a notification the app posted, or one of its actions, or replied: while
102 /// the app runs, or to start it, when the activation comes once the client exists. No dart:ui
103 /// hook: Flutter's apps hear these through plugins. The default drops it.
104 fn notification_activated(&mut self, activation: NotificationActivation) {
105 let _ = activation;
106 }
107
108 /// Flutter `PlatformDispatcher.onKeyData`.
109 ///
110 /// Returns whether the framework handled the event; a host that shares the
111 /// keyboard with other native components should not propagate a handled one.
112 fn key_data(&mut self, data: KeyData) -> bool;
113
114 /// The user asked to go back: Android's back button or back gesture, and whatever a
115 /// later host maps onto the same idea.
116 ///
117 /// Answers whether the application went back. `false` means there was nothing left to
118 /// go back to, and the host should then do what the platform does without the
119 /// application, which on Android is to close the activity.
120 ///
121 /// Flutter sends this as `popRoute` on `SystemChannels.navigation`, and has to ask the
122 /// framework in advance whether it handles back at all, because the answer cannot
123 /// cross its channel in time. This call answers on the spot instead.
124 fn pop_route(&mut self) -> bool {
125 false
126 }
127
128 /// The user asked to close `view`: its window's close button, or the system's Close
129 /// command. The host closes nothing itself; the application closes the window, through
130 /// [`HostWindow::close`](crate::HostWindow::close), or keeps it open, such as until its user
131 /// has chosen whether to save. Nothing waits for an answer.
132 ///
133 /// Flutter's engine reports this to the window's controller, whose delegate's
134 /// `onWindowCloseRequested` closes it by default. The default here keeps the view open.
135 fn view_close_requested(&mut self, view: ViewId) {
136 let _ = view;
137 }
138
139 /// The window of `view` was minimized or restored, became occluded or shown, or moved, and
140 /// its [`HostWindow`](crate::HostWindow) already answers how it is now: as Flutter's window
141 /// controllers notify their listeners at the platform's word. A resize is reported as a
142 /// metrics change alone (`view_metrics_changed`). The default drops it.
143 fn window_changed(&mut self, view: ViewId) {
144 let _ = view;
145 }
146
147 /// A request for a view ([`crate::Platform::request_view`]) got no view: the host could not
148 /// make its window. The default drops it.
149 fn view_request_failed(&mut self, request: crate::RequestId, error: crate::ViewError) {
150 let _ = (request, error);
151 }
152
153 /// The system asked the application to quit, and the application may refuse: the user
154 /// chose Quit, or is logging out. Every request comes here, a second one while the first is
155 /// still being decided included, so that the application decides each; `reply` takes its
156 /// answer, and the host quits on [`AppExitResponse::Exit`].
157 ///
158 /// The answer may take as long as the application needs, such as asking its user whether
159 /// to save first, and is given inside a call into this client: this one, or a later one.
160 ///
161 /// Flutter sends this as `System.requestAppExit` on `SystemChannels.platform` and replies
162 /// once `ServicesBinding.handleRequestAppExit`'s `Future` has completed. The default
163 /// answers `Exit` at once, as `ServicesBinding`'s own answer does.
164 fn request_app_exit(&mut self, reply: AppExitReply) {
165 reply.answer(AppExitResponse::Exit);
166 }
167
168 /// The application entered `state`: its views were shown, hidden, focused or unfocused, or
169 /// the system put it in the background or brought it back. The host sends the state it is
170 /// in, and the framework fills in the states between, as Flutter's `ServicesBinding` does.
171 ///
172 /// Flutter sends this as the state's name on `SystemChannels.lifecycle`. The default drops
173 /// it.
174 fn app_lifecycle_state_changed(&mut self, state: AppLifecycleState) {
175 let _ = state;
176 }
177
178 /// Flutter `PlatformDispatcher.onPlatformBrightnessChanged`: the host's light or dark
179 /// preference changed, and `Platform::platform_brightness` already answers the new one.
180 fn platform_brightness_changed(&mut self);
181
182 /// Flutter `PlatformDispatcher.onLocaleChanged`: the host's locale list changed, and
183 /// `Platform::locales` already answers the new one.
184 fn locales_changed(&mut self);
185
186 /// Flutter `PlatformDispatcher.onSystemFontsChanged`: the host registered faces the
187 /// framework did not have when text last laid out.
188 fn system_fonts_changed(&mut self) {}
189
190 /// Another app changed what is on the clipboard, or the host cleared a copy of this app's that
191 /// expired, as far as the host can tell: at the moments its system says so, or lets it check.
192 /// The app's own writes are not reported, as it made them, but where the system tells them
193 /// apart from no other change, as a browser does not. No dart:ui hook; the default drops it.
194 fn clipboard_changed(&mut self) {}
195
196 /// The wake asked for through [`Dispatcher::wake_at`](crate::Dispatcher::wake_at) or
197 /// [`Dispatcher::wake_now`](crate::Dispatcher::wake_now).
198 ///
199 /// `elapsed` is the platform clock, the same one `Frame::elapsed` reports. Dart's
200 /// event loop runs due `Timer`s itself; here the client advances its own clock.
201 fn wake(&mut self, elapsed: Duration);
202
203 /// Flutter `TextInputClient.updateEditingValue`. The default drops it.
204 fn text_input_editing_value(&mut self, view: ViewId, value: TextEditingValue) {
205 let _ = (view, value);
206 }
207
208 /// Flutter `TextInputClient.performAction`. The default drops it.
209 fn text_input_action(&mut self, view: ViewId, action: TextInputAction) {
210 let _ = (view, action);
211 }
212
213 /// Flutter `TextInputClient.connectionClosed`. The default drops it.
214 fn text_input_closed(&mut self, view: ViewId) {
215 let _ = view;
216 }
217
218 /// Flutter `SystemContextMenuClient.handleSystemHide`. The default drops it.
219 fn system_context_menu_hidden(&mut self) {}
220
221 /// Flutter `SystemContextMenuClient.handleCustomContextMenuAction`. The default drops it.
222 fn custom_context_menu_action(&mut self, callback_id: &str) {
223 let _ = callback_id;
224 }
225}