1use crate::{
2 AnyView, AnyWindowHandle, AppContext, AsyncApp, DispatchPhase, Effect, EntityId, EventEmitter,
3 FocusHandle, FocusOutEvent, Focusable, Global, KeystrokeObserver, Priority, Reservation,
4 SubscriberSet, Subscription, Task, WeakEntity, WeakFocusHandle, Window, WindowHandle,
5};
6use anyhow::Result;
7use futures::FutureExt;
8use gpui_util::Deferred;
9use std::{
10 any::{Any, TypeId},
11 borrow::{Borrow, BorrowMut},
12 future::Future,
13 ops,
14 sync::Arc,
15};
16
17use super::{App, AsyncWindowContext, Entity, KeystrokeEvent};
18
19pub struct Context<'a, T> {
21 app: &'a mut App,
22 entity_state: WeakEntity<T>,
23}
24
25impl<'a, T> ops::Deref for Context<'a, T> {
26 type Target = App;
27
28 fn deref(&self) -> &Self::Target {
29 self.app
30 }
31}
32
33impl<'a, T> ops::DerefMut for Context<'a, T> {
34 fn deref_mut(&mut self) -> &mut Self::Target {
35 self.app
36 }
37}
38
39impl<'a, T: 'static> Context<'a, T> {
40 pub(crate) fn new_context(app: &'a mut App, entity_state: WeakEntity<T>) -> Self {
41 Self { app, entity_state }
42 }
43
44 pub fn entity_id(&self) -> EntityId {
46 self.entity_state.entity_id
47 }
48
49 pub fn entity(&self) -> Entity<T> {
51 self.weak_entity()
52 .upgrade()
53 .expect("The entity must be alive if we have a entity context")
54 }
55
56 pub fn weak_entity(&self) -> WeakEntity<T> {
58 self.entity_state.clone()
59 }
60
61 pub fn observe<W>(
64 &mut self,
65 entity: &Entity<W>,
66 mut on_notify: impl FnMut(&mut T, Entity<W>, &mut Context<T>) + 'static,
67 ) -> Subscription
68 where
69 T: 'static,
70 W: 'static,
71 {
72 let this = self.weak_entity();
73 self.app.observe_internal(entity, move |e, cx| {
74 if let Some(this) = this.upgrade() {
75 this.update(cx, |this, cx| on_notify(this, e, cx));
76 true
77 } else {
78 false
79 }
80 })
81 }
82
83 pub fn observe_self(
85 &mut self,
86 mut on_event: impl FnMut(&mut T, &mut Context<T>) + 'static,
87 ) -> Subscription
88 where
89 T: 'static,
90 {
91 let this = self.entity();
92 self.app.observe(&this, move |this, cx| {
93 this.update(cx, |this, cx| on_event(this, cx))
94 })
95 }
96
97 pub fn subscribe<T2, Evt>(
99 &mut self,
100 entity: &Entity<T2>,
101 mut on_event: impl FnMut(&mut T, Entity<T2>, &Evt, &mut Context<T>) + 'static,
102 ) -> Subscription
103 where
104 T: 'static,
105 T2: 'static + EventEmitter<Evt>,
106 Evt: 'static,
107 {
108 let this = self.weak_entity();
109 self.app.subscribe_internal(entity, move |e, event, cx| {
110 if let Some(this) = this.upgrade() {
111 this.update(cx, |this, cx| on_event(this, e, event, cx));
112 true
113 } else {
114 false
115 }
116 })
117 }
118
119 pub fn subscribe_self<Evt>(
121 &mut self,
122 mut on_event: impl FnMut(&mut T, &Evt, &mut Context<T>) + 'static,
123 ) -> Subscription
124 where
125 T: 'static + EventEmitter<Evt>,
126 Evt: 'static,
127 {
128 let this = self.entity();
129 self.app.subscribe(&this, move |this, evt, cx| {
130 this.update(cx, |this, cx| on_event(this, evt, cx))
131 })
132 }
133
134 pub fn on_release(&self, on_release: impl FnOnce(&mut T, &mut App) + 'static) -> Subscription
136 where
137 T: 'static,
138 {
139 let (subscription, activate) = self.app.release_listeners.insert(
140 self.entity_state.entity_id,
141 Box::new(move |this, cx| {
142 let this = this.downcast_mut().expect("invalid entity type");
143 on_release(this, cx);
144 }),
145 );
146 activate();
147 subscription
148 }
149
150 pub fn observe_release<T2>(
152 &self,
153 entity: &Entity<T2>,
154 on_release: impl FnOnce(&mut T, &mut T2, &mut Context<T>) + 'static,
155 ) -> Subscription
156 where
157 T: Any,
158 T2: 'static,
159 {
160 let entity_id = entity.entity_id();
161 let this = self.weak_entity();
162 let (subscription, activate) = self.app.release_listeners.insert(
163 entity_id,
164 Box::new(move |entity, cx| {
165 let entity = entity.downcast_mut().expect("invalid entity type");
166 if let Some(this) = this.upgrade() {
167 this.update(cx, |this, cx| on_release(this, entity, cx));
168 }
169 }),
170 );
171 activate();
172 subscription
173 }
174
175 pub fn observe_global<G: 'static>(
177 &mut self,
178 mut f: impl FnMut(&mut T, &mut Context<T>) + 'static,
179 ) -> Subscription
180 where
181 T: 'static,
182 {
183 let handle = self.weak_entity();
184 let (subscription, activate) = self.global_observers.insert(
185 TypeId::of::<G>(),
186 Box::new(move |cx| handle.update(cx, |view, cx| f(view, cx)).is_ok()),
187 );
188 self.defer(move |_| activate());
189 subscription
190 }
191
192 pub fn on_app_restart(
194 &self,
195 mut on_restart: impl FnMut(&mut T, &mut App) + 'static,
196 ) -> Subscription
197 where
198 T: 'static,
199 {
200 let handle = self.weak_entity();
201 self.app.on_app_restart(move |cx| {
202 handle.update(cx, |entity, cx| on_restart(entity, cx)).ok();
203 })
204 }
205
206 pub fn on_app_quit<Fut>(
209 &self,
210 mut on_quit: impl FnMut(&mut T, &mut Context<T>) -> Fut + 'static,
211 ) -> Subscription
212 where
213 Fut: 'static + Future<Output = ()>,
214 T: 'static,
215 {
216 let handle = self.weak_entity();
217 self.app.on_app_quit(move |cx| {
218 let future = handle.update(cx, |entity, cx| on_quit(entity, cx)).ok();
219 async move {
220 if let Some(future) = future {
221 future.await;
222 }
223 }
224 .boxed_local()
225 })
226 }
227
228 pub fn notify(&mut self) {
230 self.app.notify(self.entity_state.entity_id);
231 }
232
233 #[track_caller]
237 pub fn spawn<AsyncFn, R>(&self, f: AsyncFn) -> Task<R>
238 where
239 T: 'static,
240 AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncApp) -> R + 'static,
241 R: 'static,
242 {
243 let this = self.weak_entity();
244 self.app.spawn(async move |cx| f(this, cx).await)
245 }
246
247 pub fn listener<E: ?Sized>(
253 &self,
254 f: impl Fn(&mut T, &E, &mut Window, &mut Context<T>) + 'static,
255 ) -> impl Fn(&E, &mut Window, &mut App) + 'static {
256 let view = self.entity().downgrade();
257 move |e: &E, window: &mut Window, cx: &mut App| {
258 view.update(cx, |view, cx| f(view, e, window, cx)).ok();
259 }
260 }
261
262 pub fn processor<E, R>(
265 &self,
266 f: impl Fn(&mut T, E, &mut Window, &mut Context<T>) -> R + 'static,
267 ) -> impl Fn(E, &mut Window, &mut App) -> R + 'static {
268 let view = self.entity();
269 move |e: E, window: &mut Window, cx: &mut App| {
270 view.update(cx, |view, cx| f(view, e, window, cx))
271 }
272 }
273
274 pub fn on_drop(
276 &self,
277 f: impl FnOnce(&mut T, &mut Context<T>) + 'static,
278 ) -> Deferred<impl FnOnce()> {
279 let this = self.weak_entity();
280 let mut cx = self.to_async();
281 gpui_util::defer(move || {
282 this.update(&mut cx, f).ok();
283 })
284 }
285
286 pub fn focus_view<W: Focusable>(&mut self, view: &Entity<W>, window: &mut Window) {
288 window.focus(&view.focus_handle(self), self);
289 }
290
291 pub fn on_next_frame(
293 &self,
294 window: &mut Window,
295 f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
296 ) where
297 T: 'static,
298 {
299 let view = self.entity();
300 window.on_next_frame(move |window, cx| view.update(cx, |view, cx| f(view, window, cx)));
301 }
302
303 pub fn defer_in(
306 &mut self,
307 window: &Window,
308 f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
309 ) {
310 let view = self.weak_entity();
311 let entity_id = self.entity_id();
312 self.ensure_window(entity_id, window.handle.id);
313 self.app.defer(move |cx| {
314 cx.with_window(entity_id, |window, cx| {
315 view.update(cx, |view, cx| f(view, window, cx)).ok();
316 });
317 });
318 }
319
320 pub fn observe_in<V2>(
322 &mut self,
323 observed: &Entity<V2>,
324 window: &mut Window,
325 mut on_notify: impl FnMut(&mut T, Entity<V2>, &mut Window, &mut Context<T>) + 'static,
326 ) -> Subscription
327 where
328 V2: 'static,
329 T: 'static,
330 {
331 let observed_id = observed.entity_id();
332 let observed = observed.downgrade();
333 let observer = self.weak_entity();
334 let observer_id = self.entity_id();
335 self.ensure_window(observer_id, window.handle.id);
336 self.new_observer(
337 observed_id,
338 Box::new(move |cx| {
339 let Some((observer, observed)) = observer.upgrade().zip(observed.upgrade()) else {
340 return false;
341 };
342 cx.with_window(observer_id, |window, cx| {
343 observer.update(cx, |observer, cx| {
344 on_notify(observer, observed, window, cx);
345 });
346 });
347 true
348 }),
349 )
350 }
351
352 pub fn subscribe_in<Emitter, Evt>(
356 &mut self,
357 emitter: &Entity<Emitter>,
358 window: &Window,
359 mut on_event: impl FnMut(&mut T, &Entity<Emitter>, &Evt, &mut Window, &mut Context<T>) + 'static,
360 ) -> Subscription
361 where
362 Emitter: EventEmitter<Evt>,
363 Evt: 'static,
364 {
365 let emitter = emitter.downgrade();
366 let subscriber = self.weak_entity();
367 let subscriber_id = self.entity_id();
368 self.ensure_window(subscriber_id, window.handle.id);
369 self.new_subscription(
370 emitter.entity_id(),
371 (
372 TypeId::of::<Evt>(),
373 Box::new(move |event, cx| {
374 let Some((subscriber, emitter)) = subscriber.upgrade().zip(emitter.upgrade())
375 else {
376 return false;
377 };
378 let event = event.downcast_ref().expect("invalid event type");
379 cx.with_window(subscriber_id, |window, cx| {
380 subscriber.update(cx, |subscriber, cx| {
381 on_event(subscriber, &emitter, event, window, cx);
382 });
383 });
384 true
385 }),
386 ),
387 )
388 }
389
390 pub fn on_release_in(
395 &mut self,
396 window: &Window,
397 on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static,
398 ) -> Subscription {
399 let entity = self.entity();
400 self.app.observe_release_in(&entity, window, on_release)
401 }
402
403 pub fn observe_release_in<T2>(
405 &self,
406 observed: &Entity<T2>,
407 window: &Window,
408 mut on_release: impl FnMut(&mut T, &mut T2, &mut Window, &mut Context<T>) + 'static,
409 ) -> Subscription
410 where
411 T: 'static,
412 T2: 'static,
413 {
414 let observer = self.weak_entity();
415 self.app
416 .observe_release_in(observed, window, move |observed, window, cx| {
417 observer
418 .update(cx, |observer, cx| {
419 on_release(observer, observed, window, cx)
420 })
421 .ok();
422 })
423 }
424
425 pub fn observe_window_bounds(
427 &self,
428 window: &mut Window,
429 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
430 ) -> Subscription {
431 let view = self.weak_entity();
432 let (subscription, activate) = window.bounds_observers.insert(
433 (),
434 Box::new(move |window, cx| {
435 view.update(cx, |view, cx| callback(view, window, cx))
436 .is_ok()
437 }),
438 );
439 activate();
440 subscription
441 }
442
443 pub fn observe_window_activation(
445 &self,
446 window: &mut Window,
447 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
448 ) -> Subscription {
449 let view = self.weak_entity();
450 let (subscription, activate) = window.activation_observers.insert(
451 (),
452 Box::new(move |window, cx| {
453 view.update(cx, |view, cx| callback(view, window, cx))
454 .is_ok()
455 }),
456 );
457 activate();
458 subscription
459 }
460
461 pub fn observe_window_appearance(
463 &self,
464 window: &mut Window,
465 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
466 ) -> Subscription {
467 let view = self.weak_entity();
468 let (subscription, activate) = window.appearance_observers.insert(
469 (),
470 Box::new(move |window, cx| {
471 view.update(cx, |view, cx| callback(view, window, cx))
472 .is_ok()
473 }),
474 );
475 activate();
476 subscription
477 }
478
479 pub fn observe_button_layout_changed(
481 &self,
482 window: &mut Window,
483 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
484 ) -> Subscription {
485 let view = self.weak_entity();
486 let (subscription, activate) = window.button_layout_observers.insert(
487 (),
488 Box::new(move |window, cx| {
489 view.update(cx, |view, cx| callback(view, window, cx))
490 .is_ok()
491 }),
492 );
493 activate();
494 subscription
495 }
496
497 pub fn observe_keystrokes(
501 &mut self,
502 mut f: impl FnMut(&mut T, &KeystrokeEvent, &mut Window, &mut Context<T>) + 'static,
503 ) -> Subscription {
504 fn inner(
505 keystroke_observers: &SubscriberSet<(), KeystrokeObserver>,
506 handler: KeystrokeObserver,
507 ) -> Subscription {
508 let (subscription, activate) = keystroke_observers.insert((), handler);
509 activate();
510 subscription
511 }
512
513 let view = self.weak_entity();
514 inner(
515 &self.keystroke_observers,
516 Box::new(move |event, window, cx| {
517 if let Some(view) = view.upgrade() {
518 view.update(cx, |view, cx| f(view, event, window, cx));
519 true
520 } else {
521 false
522 }
523 }),
524 )
525 }
526
527 pub fn observe_pending_input(
529 &self,
530 window: &mut Window,
531 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
532 ) -> Subscription {
533 let view = self.weak_entity();
534 let (subscription, activate) = window.pending_input_observers.insert(
535 (),
536 Box::new(move |window, cx| {
537 view.update(cx, |view, cx| callback(view, window, cx))
538 .is_ok()
539 }),
540 );
541 activate();
542 subscription
543 }
544
545 pub fn on_focus(
548 &mut self,
549 handle: &FocusHandle,
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 focus_id = handle.id;
555 let (subscription, activate) =
556 window.new_focus_listener(Box::new(move |event, window, cx| {
557 view.update(cx, |view, cx| {
558 if event.previous_focus_path.last() != Some(&focus_id)
559 && event.current_focus_path.last() == Some(&focus_id)
560 {
561 listener(view, window, cx)
562 }
563 })
564 .is_ok()
565 }));
566 self.defer(|_| activate());
567 subscription
568 }
569
570 pub fn on_focus_in(
574 &mut self,
575 handle: &FocusHandle,
576 window: &mut Window,
577 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
578 ) -> Subscription {
579 let view = self.weak_entity();
580 let focus_id = handle.id;
581 let (subscription, activate) =
582 window.new_focus_listener(Box::new(move |event, window, cx| {
583 view.update(cx, |view, cx| {
584 if event.is_focus_in(focus_id) {
585 listener(view, window, cx)
586 }
587 })
588 .is_ok()
589 }));
590 self.defer(|_| activate());
591 subscription
592 }
593
594 pub fn on_blur(
597 &mut self,
598 handle: &FocusHandle,
599 window: &mut Window,
600 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
601 ) -> Subscription {
602 let view = self.weak_entity();
603 let focus_id = handle.id;
604 let (subscription, activate) =
605 window.new_focus_listener(Box::new(move |event, window, cx| {
606 view.update(cx, |view, cx| {
607 if event.previous_focus_path.last() == Some(&focus_id)
608 && event.current_focus_path.last() != Some(&focus_id)
609 {
610 listener(view, window, cx)
611 }
612 })
613 .is_ok()
614 }));
615 self.defer(|_| activate());
616 subscription
617 }
618
619 pub fn on_focus_lost(
624 &mut self,
625 window: &mut Window,
626 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
627 ) -> Subscription {
628 let view = self.weak_entity();
629 let (subscription, activate) = window.focus_lost_listeners.insert(
630 (),
631 Box::new(move |window, cx| {
632 view.update(cx, |view, cx| listener(view, window, cx))
633 .is_ok()
634 }),
635 );
636 self.defer(|_| activate());
637 subscription
638 }
639
640 pub fn on_focus_out(
643 &mut self,
644 handle: &FocusHandle,
645 window: &mut Window,
646 mut listener: impl FnMut(&mut T, FocusOutEvent, &mut Window, &mut Context<T>) + 'static,
647 ) -> Subscription {
648 let view = self.weak_entity();
649 let focus_id = handle.id;
650 let (subscription, activate) =
651 window.new_focus_listener(Box::new(move |event, window, cx| {
652 view.update(cx, |view, cx| {
653 if let Some(blurred_id) = event.previous_focus_path.last().copied()
654 && event.is_focus_out(focus_id)
655 {
656 let event = FocusOutEvent {
657 blurred: WeakFocusHandle {
658 id: blurred_id,
659 handles: Arc::downgrade(&cx.focus_handles),
660 },
661 };
662 listener(view, event, window, cx)
663 }
664 })
665 .is_ok()
666 }));
667 self.defer(|_| activate());
668 subscription
669 }
670
671 #[track_caller]
676 pub fn spawn_in<AsyncFn, R>(&self, window: &Window, f: AsyncFn) -> Task<R>
677 where
678 R: 'static,
679 AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
680 {
681 let view = self.weak_entity();
682 window.spawn(self, async move |cx| f(view, cx).await)
683 }
684
685 #[track_caller]
690 pub fn spawn_in_with_priority<AsyncFn, R>(
691 &self,
692 priority: Priority,
693 window: &Window,
694 f: AsyncFn,
695 ) -> Task<R>
696 where
697 R: 'static,
698 AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
699 {
700 let view = self.weak_entity();
701 window.spawn_with_priority(priority, self, async move |cx| f(view, cx).await)
702 }
703
704 pub fn observe_global_in<G: Global>(
706 &mut self,
707 window: &Window,
708 mut f: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
709 ) -> Subscription {
710 let window_handle = window.handle;
711 let view = self.weak_entity();
712 let (subscription, activate) = self.global_observers.insert(
713 TypeId::of::<G>(),
714 Box::new(move |cx| {
715 if view.upgrade().is_none() {
717 return false;
718 }
719 let Ok(entity_alive) = window_handle.update(cx, |_, window, cx| {
723 view.update(cx, |view, cx| f(view, window, cx)).is_ok()
724 }) else {
725 return true;
726 };
727 entity_alive
728 }),
729 );
730 self.defer(move |_| activate());
731 subscription
732 }
733
734 pub fn on_action(
736 &mut self,
737 action_type: TypeId,
738 window: &mut Window,
739 listener: impl Fn(&mut T, &dyn Any, DispatchPhase, &mut Window, &mut Context<T>) + 'static,
740 ) {
741 let handle = self.weak_entity();
742 window.on_action(action_type, move |action, phase, window, cx| {
743 handle
744 .update(cx, |view, cx| {
745 listener(view, action, phase, window, cx);
746 })
747 .ok();
748 });
749 }
750
751 pub fn focus_self(&mut self, window: &mut Window)
753 where
754 T: Focusable,
755 {
756 let view = self.entity();
757 window.defer(self, move |window, cx| {
758 view.read(cx).focus_handle(cx).focus(window, cx)
759 })
760 }
761}
762
763impl<T> Context<'_, T> {
764 pub fn emit<Evt>(&mut self, event: Evt)
766 where
767 T: EventEmitter<Evt>,
768 Evt: 'static,
769 {
770 let event = self
771 .event_arena
772 .alloc(|| event)
773 .map(|it| it as &mut dyn Any);
774 self.app.pending_effects.push_back(Effect::Emit {
775 emitter: self.entity_state.entity_id,
776 event_type: TypeId::of::<Evt>(),
777 event,
778 });
779 }
780}
781
782impl<T> AppContext for Context<'_, T> {
783 #[inline]
784 fn new<U: 'static>(&mut self, build_entity: impl FnOnce(&mut Context<U>) -> U) -> Entity<U> {
785 self.app.new(build_entity)
786 }
787
788 #[inline]
789 fn reserve_entity<U: 'static>(&mut self) -> Reservation<U> {
790 self.app.reserve_entity()
791 }
792
793 #[inline]
794 fn insert_entity<U: 'static>(
795 &mut self,
796 reservation: Reservation<U>,
797 build_entity: impl FnOnce(&mut Context<U>) -> U,
798 ) -> Entity<U> {
799 self.app.insert_entity(reservation, build_entity)
800 }
801
802 #[inline]
803 fn update_entity<U: 'static, R>(
804 &mut self,
805 handle: &Entity<U>,
806 update: impl FnOnce(&mut U, &mut Context<U>) -> R,
807 ) -> R {
808 self.app.update_entity(handle, update)
809 }
810
811 #[inline]
812 fn as_mut<'a, E>(&'a mut self, handle: &Entity<E>) -> super::GpuiBorrow<'a, E>
813 where
814 E: 'static,
815 {
816 self.app.as_mut(handle)
817 }
818
819 #[inline]
820 fn read_entity<U, R>(&self, handle: &Entity<U>, read: impl FnOnce(&U, &App) -> R) -> R
821 where
822 U: 'static,
823 {
824 self.app.read_entity(handle, read)
825 }
826
827 #[inline]
828 fn update_window<R, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<R>
829 where
830 F: FnOnce(AnyView, &mut Window, &mut App) -> R,
831 {
832 self.app.update_window(window, update)
833 }
834
835 #[inline]
836 fn with_window<R>(
837 &mut self,
838 entity_id: EntityId,
839 f: impl FnOnce(&mut Window, &mut App) -> R,
840 ) -> Option<R> {
841 self.app.with_window(entity_id, f)
842 }
843
844 #[inline]
845 fn read_window<U, R>(
846 &self,
847 window: &WindowHandle<U>,
848 read: impl FnOnce(Entity<U>, &App) -> R,
849 ) -> Result<R>
850 where
851 U: 'static,
852 {
853 self.app.read_window(window, read)
854 }
855
856 #[inline]
857 fn background_spawn<R>(&self, future: impl Future<Output = R> + Send + 'static) -> Task<R>
858 where
859 R: Send + 'static,
860 {
861 self.app.background_executor.spawn(future)
862 }
863
864 #[inline]
865 fn read_global<G, R>(&self, callback: impl FnOnce(&G, &App) -> R) -> R
866 where
867 G: Global,
868 {
869 self.app.read_global(callback)
870 }
871}
872
873impl<T> Borrow<App> for Context<'_, T> {
874 fn borrow(&self) -> &App {
875 self.app
876 }
877}
878
879impl<T> BorrowMut<App> for Context<'_, T> {
880 fn borrow_mut(&mut self) -> &mut App {
881 self.app
882 }
883}