model_context.rs

  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}