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, DropData, Frame, KeyData, PointerDataPacket,
10    TextEditingValue, TextInputAction, ViewFocusEvent, ViewId,
11};
12
13/// Complete frames and typed view lifecycle notifications.
14///
15/// The platform updates its view registry before sending a lifecycle method,
16/// so the client can immediately query the affected view.
17pub trait EmbedderClient {
18    /// A screen refreshed at `frame.elapsed`: `views` are the views on it, in sight, that asked
19    /// for a frame ([`Platform::request_frame`](crate::Platform::request_frame)) before the
20    /// refresh began; one that asks during it is in the next.
21    ///
22    /// The host never calls it from inside another call into the client.
23    fn frame(&mut self, views: &[ViewId], frame: Frame);
24
25    /// A view arrived after launch: opened by the app, or given by the system. The views that
26    /// exist at launch are in `Platform::views` when the app starts, and none of them is
27    /// reported here.
28    fn view_added(&mut self, id: ViewId);
29
30    /// Flutter's window metrics event: something of `id`'s metrics changed, the screen it is on
31    /// included.
32    fn view_metrics_changed(&mut self, id: ViewId);
33
34    /// A view is gone; the app keeps running.
35    fn view_removed(&mut self, id: ViewId);
36
37    /// Flutter `FlutterEngineNotifyDisplayUpdate`: a screen was added, removed or changed, and
38    /// `Platform::screens` already answers the new list. A view that is on another screen now
39    /// is reported through `view_metrics_changed`. The default drops it.
40    fn screens_changed(&mut self) {}
41
42    /// Flutter `PlatformDispatcher.onViewFocusChange`.
43    fn view_focus_changed(&mut self, event: ViewFocusEvent) {
44        let _ = event;
45    }
46
47    /// Flutter `PlatformDispatcher.onPointerDataPacket`.
48    fn pointer_data_packet(&mut self, packet: PointerDataPacket);
49
50    /// Files dragged from outside the application entered, moved over, were dropped on or
51    /// left a view. No dart:ui hook; the default drops it.
52    fn drop_data(&mut self, data: DropData) {
53        let _ = data;
54    }
55
56    /// Flutter `PlatformDispatcher.onKeyData`.
57    ///
58    /// Returns whether the framework handled the event; a host that shares the
59    /// keyboard with other native components should not propagate a handled one.
60    fn key_data(&mut self, data: KeyData) -> bool;
61
62    /// The user asked to go back: Android's back button or back gesture, and whatever a
63    /// later host maps onto the same idea.
64    ///
65    /// Answers whether the application went back. `false` means there was nothing left to
66    /// go back to, and the host should then do what the platform does without the
67    /// application, which on Android is to close the activity.
68    ///
69    /// Flutter sends this as `popRoute` on `SystemChannels.navigation`, and has to ask the
70    /// framework in advance whether it handles back at all, because the answer cannot
71    /// cross its channel in time. This call answers on the spot instead.
72    fn pop_route(&mut self) -> bool {
73        false
74    }
75
76    /// The user asked to close `view`: its window's close button, or the system's Close
77    /// command. The host closes nothing itself; the application closes the window, through
78    /// [`HostWindow::close`](crate::HostWindow::close), or keeps it open, such as until its user
79    /// has chosen whether to save. Nothing waits for an answer.
80    ///
81    /// Flutter's engine reports this to the window's controller, whose delegate's
82    /// `onWindowCloseRequested` closes it by default. The default here keeps the view open.
83    fn view_close_requested(&mut self, view: ViewId) {
84        let _ = view;
85    }
86
87    /// The window of `view` was minimized or restored, became occluded or shown, or moved, and
88    /// its [`HostWindow`](crate::HostWindow) already answers how it is now: as Flutter's window
89    /// controllers notify their listeners at the platform's word. A resize is reported as a
90    /// metrics change alone (`view_metrics_changed`). The default drops it.
91    fn window_changed(&mut self, view: ViewId) {
92        let _ = view;
93    }
94
95    /// A request for a view ([`crate::Platform::request_view`]) got no view: the host could not
96    /// make its window. The default drops it.
97    fn view_request_failed(&mut self, request: crate::RequestId, error: crate::ViewError) {
98        let _ = (request, error);
99    }
100
101    /// The system asked the application to quit, and the application may refuse: the user
102    /// chose Quit, or is logging out. Every request comes here, a second one while the first is
103    /// still being decided included, so that the application decides each; `reply` takes its
104    /// answer, and the host quits on [`AppExitResponse::Exit`].
105    ///
106    /// The answer may take as long as the application needs, such as asking its user whether
107    /// to save first, and is given inside a call into this client: this one, or a later one.
108    ///
109    /// Flutter sends this as `System.requestAppExit` on `SystemChannels.platform` and replies
110    /// once `ServicesBinding.handleRequestAppExit`'s `Future` has completed. The default
111    /// answers `Exit` at once, as `ServicesBinding`'s own answer does.
112    fn request_app_exit(&mut self, reply: AppExitReply) {
113        reply.answer(AppExitResponse::Exit);
114    }
115
116    /// The application entered `state`: its views were shown, hidden, focused or unfocused, or
117    /// the system put it in the background or brought it back. The host sends the state it is
118    /// in, and the framework fills in the states between, as Flutter's `ServicesBinding` does.
119    ///
120    /// Flutter sends this as the state's name on `SystemChannels.lifecycle`. The default drops
121    /// it.
122    fn app_lifecycle_state_changed(&mut self, state: AppLifecycleState) {
123        let _ = state;
124    }
125
126    /// Flutter `PlatformDispatcher.onPlatformBrightnessChanged`: the host's light or dark
127    /// preference changed, and `Platform::platform_brightness` already answers the new one.
128    fn platform_brightness_changed(&mut self);
129
130    /// Flutter `PlatformDispatcher.onLocaleChanged`: the host's locale list changed, and
131    /// `Platform::locales` already answers the new one.
132    fn locales_changed(&mut self);
133
134    /// Flutter `PlatformDispatcher.onSystemFontsChanged`: the host registered faces the
135    /// framework did not have when text last laid out.
136    fn system_fonts_changed(&mut self) {}
137
138    /// The wake asked for through [`Dispatcher::wake_at`](crate::Dispatcher::wake_at) or
139    /// [`Dispatcher::wake_now`](crate::Dispatcher::wake_now).
140    ///
141    /// `elapsed` is the platform clock, the same one `Frame::elapsed` reports. Dart's
142    /// event loop runs due `Timer`s itself; here the client advances its own clock.
143    fn wake(&mut self, elapsed: Duration);
144
145    /// Flutter `TextInputClient.updateEditingValue`. The default drops it.
146    fn text_input_editing_value(&mut self, view: ViewId, value: TextEditingValue) {
147        let _ = (view, value);
148    }
149
150    /// Flutter `TextInputClient.performAction`. The default drops it.
151    fn text_input_action(&mut self, view: ViewId, action: TextInputAction) {
152        let _ = (view, action);
153    }
154
155    /// Flutter `TextInputClient.connectionClosed`. The default drops it.
156    fn text_input_closed(&mut self, view: ViewId) {
157        let _ = view;
158    }
159
160    /// Flutter `SystemContextMenuClient.handleSystemHide`. The default drops it.
161    fn system_context_menu_hidden(&mut self) {}
162
163    /// Flutter `SystemContextMenuClient.handleCustomContextMenuAction`. The default drops it.
164    fn custom_context_menu_action(&mut self, callback_id: &str) {
165        let _ = callback_id;
166    }
167}