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