context.rs

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