1use crate::{
2 AnyView, AnyWindowHandle, App, AppContext, AsyncApp, DispatchPhase, Effect, EntityId,
3 EventEmitter, FocusHandle, FocusOutEvent, Focusable, Global, KeystrokeObserver, Reservation,
4 SubscriberSet, Subscription, Task, WeakEntity, WeakFocusHandle, Window, WindowHandle,
5};
6use anyhow::Result;
7use derive_more::{Deref, DerefMut};
8use futures::FutureExt;
9use std::{
10 any::{Any, TypeId},
11 borrow::{Borrow, BorrowMut},
12 future::Future,
13 sync::Arc,
14};
15
16use super::{AsyncWindowContext, Entity, KeystrokeEvent};
17
18/// The app context, with specialized behavior for the given model.
19#[derive(Deref, DerefMut)]
20pub struct Context<'a, T> {
21 #[deref]
22 #[deref_mut]
23 app: &'a mut App,
24 model_state: WeakEntity<T>,
25}
26
27impl<'a, T: 'static> Context<'a, T> {
28 pub(crate) fn new_context(app: &'a mut App, model_state: WeakEntity<T>) -> Self {
29 Self { app, model_state }
30 }
31
32 /// The entity id of the model backing this context.
33 pub fn entity_id(&self) -> EntityId {
34 self.model_state.entity_id
35 }
36
37 /// Returns a handle to the model belonging to this context.
38 pub fn entity(&self) -> Entity<T> {
39 self.weak_entity()
40 .upgrade()
41 .expect("The entity must be alive if we have a model context")
42 }
43
44 /// Returns a weak handle to the model belonging to this context.
45 pub fn weak_entity(&self) -> WeakEntity<T> {
46 self.model_state.clone()
47 }
48
49 /// Arranges for the given function to be called whenever [`ModelContext::notify`] or
50 /// [`ViewContext::notify`](crate::ViewContext::notify) is called with the given model or view.
51 pub fn observe<W>(
52 &mut self,
53 entity: &Entity<W>,
54 mut on_notify: impl FnMut(&mut T, Entity<W>, &mut Context<'_, T>) + 'static,
55 ) -> Subscription
56 where
57 T: 'static,
58 W: 'static,
59 {
60 let this = self.weak_entity();
61 self.app.observe_internal(entity, move |e, cx| {
62 if let Some(this) = this.upgrade() {
63 this.update(cx, |this, cx| on_notify(this, e, cx));
64 true
65 } else {
66 false
67 }
68 })
69 }
70
71 /// Subscribe to an event type from another model or view
72 pub fn subscribe<T2, Evt>(
73 &mut self,
74 entity: &Entity<T2>,
75 mut on_event: impl FnMut(&mut T, Entity<T2>, &Evt, &mut Context<'_, T>) + 'static,
76 ) -> Subscription
77 where
78 T: 'static,
79 T2: 'static + EventEmitter<Evt>,
80 Evt: 'static,
81 {
82 let this = self.weak_entity();
83 self.app.subscribe_internal(entity, move |e, event, cx| {
84 if let Some(this) = this.upgrade() {
85 this.update(cx, |this, cx| on_event(this, e, event, cx));
86 true
87 } else {
88 false
89 }
90 })
91 }
92
93 /// Register a callback to be invoked when GPUI releases this model.
94 pub fn on_release(&self, on_release: impl FnOnce(&mut T, &mut App) + 'static) -> Subscription
95 where
96 T: 'static,
97 {
98 let (subscription, activate) = self.app.release_listeners.insert(
99 self.model_state.entity_id,
100 Box::new(move |this, cx| {
101 let this = this.downcast_mut().expect("invalid entity type");
102 on_release(this, cx);
103 }),
104 );
105 activate();
106 subscription
107 }
108
109 /// Register a callback to be run on the release of another model or view
110 pub fn observe_release<T2>(
111 &self,
112 entity: &Entity<T2>,
113 on_release: impl FnOnce(&mut T, &mut T2, &mut Context<'_, T>) + 'static,
114 ) -> Subscription
115 where
116 T: Any,
117 T2: 'static,
118 {
119 let entity_id = entity.entity_id();
120 let this = self.weak_entity();
121 let (subscription, activate) = self.app.release_listeners.insert(
122 entity_id,
123 Box::new(move |entity, cx| {
124 let entity = entity.downcast_mut().expect("invalid entity type");
125 if let Some(this) = this.upgrade() {
126 this.update(cx, |this, cx| on_release(this, entity, cx));
127 }
128 }),
129 );
130 activate();
131 subscription
132 }
133
134 /// Register a callback to for updates to the given global
135 pub fn observe_global<G: 'static>(
136 &mut self,
137 mut f: impl FnMut(&mut T, &mut Context<'_, T>) + 'static,
138 ) -> Subscription
139 where
140 T: 'static,
141 {
142 let handle = self.weak_entity();
143 let (subscription, activate) = self.global_observers.insert(
144 TypeId::of::<G>(),
145 Box::new(move |cx| handle.update(cx, |view, cx| f(view, cx)).is_ok()),
146 );
147 self.defer(move |_| activate());
148 subscription
149 }
150
151 /// Arrange for the given function to be invoked whenever the application is quit.
152 /// The future returned from this callback will be polled for up to [crate::SHUTDOWN_TIMEOUT] until the app fully quits.
153 pub fn on_app_quit<Fut>(
154 &self,
155 mut on_quit: impl FnMut(&mut T, &mut Context<T>) -> Fut + 'static,
156 ) -> Subscription
157 where
158 Fut: 'static + Future<Output = ()>,
159 T: 'static,
160 {
161 let handle = self.weak_entity();
162 let (subscription, activate) = self.app.quit_observers.insert(
163 (),
164 Box::new(move |cx| {
165 let future = handle.update(cx, |entity, cx| on_quit(entity, cx)).ok();
166 async move {
167 if let Some(future) = future {
168 future.await;
169 }
170 }
171 .boxed_local()
172 }),
173 );
174 activate();
175 subscription
176 }
177
178 /// Tell GPUI that this model has changed and observers of it should be notified.
179 pub fn notify(&mut self) {
180 self.app.notify(self.model_state.entity_id);
181 }
182
183 /// Spawn the future returned by the given function.
184 /// The function is provided a weak handle to the model owned by this context and a context that can be held across await points.
185 /// The returned task must be held or detached.
186 pub fn spawn<Fut, R>(&self, f: impl FnOnce(WeakEntity<T>, AsyncApp) -> Fut) -> Task<R>
187 where
188 T: 'static,
189 Fut: Future<Output = R> + 'static,
190 R: 'static,
191 {
192 let this = self.weak_entity();
193 self.app.spawn(|cx| f(this, cx))
194 }
195
196 /// Convenience method for accessing view state in an event callback.
197 ///
198 /// Many GPUI callbacks take the form of `Fn(&E, &mut Window, &mut AppContext)`,
199 /// but it's often useful to be able to access view state in these
200 /// callbacks. This method provides a convenient way to do so.
201 pub fn listener<E: ?Sized>(
202 &self,
203 f: impl Fn(&mut T, &E, &mut Window, &mut Context<T>) + 'static,
204 ) -> impl Fn(&E, &mut Window, &mut App) + 'static {
205 let view = self.entity().downgrade();
206 move |e: &E, window: &mut Window, cx: &mut App| {
207 view.update(cx, |view, cx| f(view, e, window, cx)).ok();
208 }
209 }
210
211 /// Focus the given view in the given window. View type is required to implement Focusable.
212 pub fn focus_view<W: Focusable>(&mut self, view: &Entity<W>, window: &mut Window) {
213 window.focus(&view.focus_handle(self));
214 }
215
216 /// Sets a given callback to be run on the next frame.
217 pub fn on_next_frame(
218 &self,
219 window: &mut Window,
220 f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
221 ) where
222 T: 'static,
223 {
224 let view = self.entity();
225 window.on_next_frame(move |window, cx| view.update(cx, |view, cx| f(view, window, cx)));
226 }
227
228 /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
229 /// that are currently on the stack to be returned to the app.
230 pub fn defer_in(
231 &mut self,
232 window: &Window,
233 f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
234 ) {
235 let view = self.entity();
236 window.defer(self, move |window, cx| {
237 view.update(cx, |view, cx| f(view, window, cx))
238 });
239 }
240
241 /// Observe another model or view for changes to its state, as tracked by [`ModelContext::notify`].
242 pub fn observe_in<V2>(
243 &mut self,
244 observed: &Entity<V2>,
245 window: &mut Window,
246 mut on_notify: impl FnMut(&mut T, Entity<V2>, &mut Window, &mut Context<'_, T>) + 'static,
247 ) -> Subscription
248 where
249 V2: 'static,
250 T: 'static,
251 {
252 let observed_id = observed.entity_id();
253 let observed = observed.downgrade();
254 let window_handle = window.handle;
255 let observer = self.weak_entity();
256 self.new_observer(
257 observed_id,
258 Box::new(move |cx| {
259 window_handle
260 .update(cx, |_, window, cx| {
261 if let Some((observer, observed)) =
262 observer.upgrade().zip(observed.upgrade())
263 {
264 observer.update(cx, |observer, cx| {
265 on_notify(observer, observed, window, cx);
266 });
267 true
268 } else {
269 false
270 }
271 })
272 .unwrap_or(false)
273 }),
274 )
275 }
276
277 /// Subscribe to events emitted by another model or view.
278 /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
279 /// The callback will be invoked with a reference to the current view, a handle to the emitting entity (either a [`View`] or [`Model`]), the event, and a view context for the current view.
280 pub fn subscribe_in<Emitter, Evt>(
281 &mut self,
282 emitter: &Entity<Emitter>,
283 window: &Window,
284 mut on_event: impl FnMut(&mut T, &Entity<Emitter>, &Evt, &mut Window, &mut Context<'_, T>)
285 + 'static,
286 ) -> Subscription
287 where
288 Emitter: EventEmitter<Evt>,
289 Evt: 'static,
290 {
291 let emitter = emitter.downgrade();
292 let window_handle = window.handle;
293 let subscriber = self.weak_entity();
294 self.new_subscription(
295 emitter.entity_id(),
296 (
297 TypeId::of::<Evt>(),
298 Box::new(move |event, cx| {
299 window_handle
300 .update(cx, |_, window, cx| {
301 if let Some((subscriber, emitter)) =
302 subscriber.upgrade().zip(emitter.upgrade())
303 {
304 let event = event.downcast_ref().expect("invalid event type");
305 subscriber.update(cx, |subscriber, cx| {
306 on_event(subscriber, &emitter, event, window, cx);
307 });
308 true
309 } else {
310 false
311 }
312 })
313 .unwrap_or(false)
314 }),
315 ),
316 )
317 }
318
319 /// Register a callback to be invoked when the view is released.
320 ///
321 /// The callback receives a handle to the view's window. This handle may be
322 /// invalid, if the window was closed before the view was released.
323 pub fn on_release_in(
324 &mut self,
325 window: &Window,
326 on_release: impl FnOnce(&mut T, AnyWindowHandle, &mut App) + 'static,
327 ) -> Subscription {
328 let window_handle = window.handle;
329 let (subscription, activate) = self.release_listeners.insert(
330 self.entity_id(),
331 Box::new(move |this, cx| {
332 let this = this.downcast_mut().expect("invalid entity type");
333 on_release(this, window_handle, cx)
334 }),
335 );
336 activate();
337 subscription
338 }
339
340 /// Register a callback to be invoked when the given Model or View is released.
341 pub fn observe_release_in<V2>(
342 &self,
343 observed: &Entity<V2>,
344 window: &Window,
345 mut on_release: impl FnMut(&mut T, &mut V2, &mut Window, &mut Context<'_, T>) + 'static,
346 ) -> Subscription
347 where
348 T: 'static,
349 V2: 'static,
350 {
351 let observer = self.weak_entity();
352 let window_handle = window.handle;
353 let (subscription, activate) = self.release_listeners.insert(
354 observed.entity_id(),
355 Box::new(move |observed, cx| {
356 let observed = observed
357 .downcast_mut()
358 .expect("invalid observed entity type");
359 let _ = window_handle.update(cx, |_, window, cx| {
360 observer.update(cx, |this, cx| on_release(this, observed, window, cx))
361 });
362 }),
363 );
364 activate();
365 subscription
366 }
367
368 /// Register a callback to be invoked when the window is resized.
369 pub fn observe_window_bounds(
370 &self,
371 window: &mut Window,
372 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
373 ) -> Subscription {
374 let view = self.weak_entity();
375 let (subscription, activate) = window.bounds_observers.insert(
376 (),
377 Box::new(move |window, cx| {
378 view.update(cx, |view, cx| callback(view, window, cx))
379 .is_ok()
380 }),
381 );
382 activate();
383 subscription
384 }
385
386 /// Register a callback to be invoked when the window is activated or deactivated.
387 pub fn observe_window_activation(
388 &self,
389 window: &mut Window,
390 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
391 ) -> Subscription {
392 let view = self.weak_entity();
393 let (subscription, activate) = window.activation_observers.insert(
394 (),
395 Box::new(move |window, cx| {
396 view.update(cx, |view, cx| callback(view, window, cx))
397 .is_ok()
398 }),
399 );
400 activate();
401 subscription
402 }
403
404 /// Registers a callback to be invoked when the window appearance changes.
405 pub fn observe_window_appearance(
406 &self,
407 window: &mut Window,
408 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
409 ) -> Subscription {
410 let view = self.weak_entity();
411 let (subscription, activate) = window.appearance_observers.insert(
412 (),
413 Box::new(move |window, cx| {
414 view.update(cx, |view, cx| callback(view, window, cx))
415 .is_ok()
416 }),
417 );
418 activate();
419 subscription
420 }
421
422 /// Register a callback to be invoked when a keystroke is received by the application
423 /// in any window. Note that this fires after all other action and event mechanisms have resolved
424 /// and that this API will not be invoked if the event's propagation is stopped.
425 pub fn observe_keystrokes(
426 &mut self,
427 mut f: impl FnMut(&mut T, &KeystrokeEvent, &mut Window, &mut Context<T>) + 'static,
428 ) -> Subscription {
429 fn inner(
430 keystroke_observers: &SubscriberSet<(), KeystrokeObserver>,
431 handler: KeystrokeObserver,
432 ) -> Subscription {
433 let (subscription, activate) = keystroke_observers.insert((), handler);
434 activate();
435 subscription
436 }
437
438 let view = self.weak_entity();
439 inner(
440 &mut self.keystroke_observers,
441 Box::new(move |event, window, cx| {
442 if let Some(view) = view.upgrade() {
443 view.update(cx, |view, cx| f(view, event, window, cx));
444 true
445 } else {
446 false
447 }
448 }),
449 )
450 }
451
452 /// Register a callback to be invoked when the window's pending input changes.
453 pub fn observe_pending_input(
454 &self,
455 window: &mut Window,
456 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
457 ) -> Subscription {
458 let view = self.weak_entity();
459 let (subscription, activate) = window.pending_input_observers.insert(
460 (),
461 Box::new(move |window, cx| {
462 view.update(cx, |view, cx| callback(view, window, cx))
463 .is_ok()
464 }),
465 );
466 activate();
467 subscription
468 }
469
470 /// Register a listener to be called when the given focus handle receives focus.
471 /// Returns a subscription and persists until the subscription is dropped.
472 pub fn on_focus(
473 &mut self,
474 handle: &FocusHandle,
475 window: &mut Window,
476 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
477 ) -> Subscription {
478 let view = self.weak_entity();
479 let focus_id = handle.id;
480 let (subscription, activate) =
481 window.new_focus_listener(Box::new(move |event, window, cx| {
482 view.update(cx, |view, cx| {
483 if event.previous_focus_path.last() != Some(&focus_id)
484 && event.current_focus_path.last() == Some(&focus_id)
485 {
486 listener(view, window, cx)
487 }
488 })
489 .is_ok()
490 }));
491 self.defer(|_| activate());
492 subscription
493 }
494
495 /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
496 /// This does not fire if the given focus handle - or one of its descendants - was previously focused.
497 /// Returns a subscription and persists until the subscription is dropped.
498 pub fn on_focus_in(
499 &mut self,
500 handle: &FocusHandle,
501 window: &mut Window,
502 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
503 ) -> Subscription {
504 let view = self.weak_entity();
505 let focus_id = handle.id;
506 let (subscription, activate) =
507 window.new_focus_listener(Box::new(move |event, window, cx| {
508 view.update(cx, |view, cx| {
509 if event.is_focus_in(focus_id) {
510 listener(view, window, cx)
511 }
512 })
513 .is_ok()
514 }));
515 self.defer(|_| activate());
516 subscription
517 }
518
519 /// Register a listener to be called when the given focus handle loses focus.
520 /// Returns a subscription and persists until the subscription is dropped.
521 pub fn on_blur(
522 &mut self,
523 handle: &FocusHandle,
524 window: &mut Window,
525 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
526 ) -> Subscription {
527 let view = self.weak_entity();
528 let focus_id = handle.id;
529 let (subscription, activate) =
530 window.new_focus_listener(Box::new(move |event, window, cx| {
531 view.update(cx, |view, cx| {
532 if event.previous_focus_path.last() == Some(&focus_id)
533 && event.current_focus_path.last() != Some(&focus_id)
534 {
535 listener(view, window, cx)
536 }
537 })
538 .is_ok()
539 }));
540 self.defer(|_| activate());
541 subscription
542 }
543
544 /// Register a listener to be called when nothing in the window has focus.
545 /// This typically happens when the node that was focused is removed from the tree,
546 /// and this callback lets you chose a default place to restore the users focus.
547 /// Returns a subscription and persists until the subscription is dropped.
548 pub fn on_focus_lost(
549 &mut self,
550 window: &mut Window,
551 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
552 ) -> Subscription {
553 let view = self.weak_entity();
554 let (subscription, activate) = window.focus_lost_listeners.insert(
555 (),
556 Box::new(move |window, cx| {
557 view.update(cx, |view, cx| listener(view, window, cx))
558 .is_ok()
559 }),
560 );
561 self.defer(|_| activate());
562 subscription
563 }
564
565 /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
566 /// Returns a subscription and persists until the subscription is dropped.
567 pub fn on_focus_out(
568 &mut self,
569 handle: &FocusHandle,
570 window: &mut Window,
571 mut listener: impl FnMut(&mut T, FocusOutEvent, &mut Window, &mut Context<T>) + 'static,
572 ) -> Subscription {
573 let view = self.weak_entity();
574 let focus_id = handle.id;
575 let (subscription, activate) =
576 window.new_focus_listener(Box::new(move |event, window, cx| {
577 view.update(cx, |view, cx| {
578 if let Some(blurred_id) = event.previous_focus_path.last().copied() {
579 if event.is_focus_out(focus_id) {
580 let event = FocusOutEvent {
581 blurred: WeakFocusHandle {
582 id: blurred_id,
583 handles: Arc::downgrade(&cx.focus_handles),
584 },
585 };
586 listener(view, event, window, cx)
587 }
588 }
589 })
590 .is_ok()
591 }));
592 self.defer(|_| activate());
593 subscription
594 }
595
596 /// Schedule a future to be run asynchronously.
597 /// The given callback is invoked with a [`WeakModel<V>`] to avoid leaking the view for a long-running process.
598 /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the view across await points.
599 /// The returned future will be polled on the main thread.
600 pub fn spawn_in<Fut, R>(
601 &self,
602 window: &Window,
603 f: impl FnOnce(WeakEntity<T>, AsyncWindowContext) -> Fut,
604 ) -> Task<R>
605 where
606 R: 'static,
607 Fut: Future<Output = R> + 'static,
608 {
609 let view = self.weak_entity();
610 window.spawn(self, |mut cx| f(view, cx))
611 }
612
613 /// Register a callback to be invoked when the given global state changes.
614 pub fn observe_global_in<G: Global>(
615 &mut self,
616 window: &Window,
617 mut f: impl FnMut(&mut T, &mut Window, &mut Context<'_, T>) + 'static,
618 ) -> Subscription {
619 let window_handle = window.handle;
620 let view = self.weak_entity();
621 let (subscription, activate) = self.global_observers.insert(
622 TypeId::of::<G>(),
623 Box::new(move |cx| {
624 window_handle
625 .update(cx, |_, window, cx| {
626 view.update(cx, |view, cx| f(view, window, cx)).is_ok()
627 })
628 .unwrap_or(false)
629 }),
630 );
631 self.defer(move |_| activate());
632 subscription
633 }
634
635 /// Register a callback to be invoked when the given Action type is dispatched to the window.
636 pub fn on_action(
637 &mut self,
638 action_type: TypeId,
639 window: &mut Window,
640 listener: impl Fn(&mut T, &dyn Any, DispatchPhase, &mut Window, &mut Context<T>) + 'static,
641 ) {
642 let handle = self.weak_entity();
643 window.on_action(action_type, move |action, phase, window, cx| {
644 handle
645 .update(cx, |view, cx| {
646 listener(view, action, phase, window, cx);
647 })
648 .ok();
649 });
650 }
651
652 /// Move focus to the current view, assuming it implements [`Focusable`].
653 pub fn focus_self(&mut self, window: &mut Window)
654 where
655 T: Focusable,
656 {
657 let view = self.entity();
658 window.defer(self, move |window, cx| {
659 view.read(cx).focus_handle(cx).focus(window)
660 })
661 }
662}
663
664impl<'a, T> Context<'a, T> {
665 /// Emit an event of the specified type, which can be handled by other entities that have subscribed via `subscribe` methods on their respective contexts.
666 pub fn emit<Evt>(&mut self, event: Evt)
667 where
668 T: EventEmitter<Evt>,
669 Evt: 'static,
670 {
671 self.app.pending_effects.push_back(Effect::Emit {
672 emitter: self.model_state.entity_id,
673 event_type: TypeId::of::<Evt>(),
674 event: Box::new(event),
675 });
676 }
677}
678
679impl<'a, T> AppContext for Context<'a, T> {
680 type Result<U> = U;
681
682 fn new<U: 'static>(&mut self, build_model: impl FnOnce(&mut Context<'_, U>) -> U) -> Entity<U> {
683 self.app.new(build_model)
684 }
685
686 fn reserve_entity<U: 'static>(&mut self) -> Reservation<U> {
687 self.app.reserve_entity()
688 }
689
690 fn insert_entity<U: 'static>(
691 &mut self,
692 reservation: Reservation<U>,
693 build_model: impl FnOnce(&mut Context<'_, U>) -> U,
694 ) -> Self::Result<Entity<U>> {
695 self.app.insert_entity(reservation, build_model)
696 }
697
698 fn update_entity<U: 'static, R>(
699 &mut self,
700 handle: &Entity<U>,
701 update: impl FnOnce(&mut U, &mut Context<'_, U>) -> R,
702 ) -> R {
703 self.app.update_entity(handle, update)
704 }
705
706 fn read_entity<U, R>(
707 &self,
708 handle: &Entity<U>,
709 read: impl FnOnce(&U, &App) -> R,
710 ) -> Self::Result<R>
711 where
712 U: 'static,
713 {
714 self.app.read_entity(handle, read)
715 }
716
717 fn update_window<R, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<R>
718 where
719 F: FnOnce(AnyView, &mut Window, &mut App) -> R,
720 {
721 self.app.update_window(window, update)
722 }
723
724 fn read_window<U, R>(
725 &self,
726 window: &WindowHandle<U>,
727 read: impl FnOnce(Entity<U>, &App) -> R,
728 ) -> Result<R>
729 where
730 U: 'static,
731 {
732 self.app.read_window(window, read)
733 }
734}
735
736impl<T> Borrow<App> for Context<'_, T> {
737 fn borrow(&self) -> &App {
738 self.app
739 }
740}
741
742impl<T> BorrowMut<App> for Context<'_, T> {
743 fn borrow_mut(&mut self) -> &mut App {
744 self.app
745 }
746}