Skip to main content

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}