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}