Skip to main content

gpui/app/
context.rs

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
20/// The app context, with specialized behavior for the given entity.
21pub 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    /// The entity id of the entity backing this context.
46    pub fn entity_id(&self) -> EntityId {
47        self.entity_state.entity_id
48    }
49
50    /// Returns a handle to the entity belonging to this context.
51    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    /// Returns a weak handle to the entity belonging to this context.
58    pub fn weak_entity(&self) -> WeakEntity<T> {
59        self.entity_state.clone()
60    }
61
62    /// Arranges for the given function to be called whenever [`Context::notify`] is
63    /// called with the given entity.
64    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    /// Observe changes to ourselves
85    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    /// Subscribe to an event type from another entity
99    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    /// Subscribe to an event type from ourself
121    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    /// Register a callback to be invoked when GPUI releases this entity.
136    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    /// Register a callback to be run on the release of another entity
152    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    /// Register a callback to for updates to the given global
177    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    /// Register a callback to be invoked when the application is about to restart.
194    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    /// Arrange for the given function to be invoked whenever the application is quit.
208    /// The future returned from this callback will be polled for up to [crate::SHUTDOWN_TIMEOUT] until the app fully quits.
209    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    /// Tell GPUI that this entity has changed and observers of it should be notified.
230    pub fn notify(&mut self) {
231        self.app.notify(self.entity_state.entity_id);
232    }
233
234    /// Spawn the future returned by the given function.
235    /// The function is provided a weak handle to the entity owned by this context and a context that can be held across await points.
236    /// The returned task must be held or detached.
237    #[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    /// Convenience method for accessing view state in an event callback.
249    ///
250    /// Many GPUI callbacks take the form of `Fn(&E, &mut Window, &mut App)`,
251    /// but it's often useful to be able to access view state in these
252    /// callbacks. This method provides a convenient way to do so.
253    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    /// Convenience method for producing view state in a closure.
264    /// See `listener` for more details.
265    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    /// Run something using this entity and cx, when the returned struct is dropped
276    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    /// Focus the given view in the given window. View type is required to implement Focusable.
288    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    /// Sets a given callback to be run on the next frame.
293    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    /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
305    /// that are currently on the stack to be returned to the app.
306    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    /// Observe another entity for changes to its state, as tracked by [`Context::notify`].
322    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    /// Subscribe to events emitted by another entity.
354    /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
355    /// 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.
356    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    /// Register a callback to be invoked when the view is released.
392    ///
393    /// The callback receives a handle to the view's window. This handle may be
394    /// invalid, if the window was closed before the view was released.
395    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    /// Register a callback to be invoked when the given Entity is released.
405    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    /// Register a callback to be invoked when the window is resized.
427    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    /// Register a callback to be invoked when the window is activated or deactivated.
445    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    /// Registers a callback to be invoked when the window's visibility changes
463    /// (see [`WindowVisibility`]).
464    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    /// Registers a callback to be invoked when the window appearance changes.
482    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    /// Registers a callback to be invoked when the window button layout changes.
500    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    /// Register a callback to be invoked when a keystroke is received by the application
518    /// in any window. Note that this fires after all other action and event mechanisms have resolved
519    /// and that this API will not be invoked if the event's propagation is stopped.
520    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    /// Register a callback to be invoked when the window's pending input changes.
548    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    /// Register a listener to be called when the given focus handle receives focus.
566    /// Returns a subscription and persists until the subscription is dropped.
567    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    /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
591    /// This does not fire if the given focus handle - or one of its descendants - was previously focused.
592    /// Returns a subscription and persists until the subscription is dropped.
593    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    /// Register a listener to be called when the given focus handle loses focus.
615    /// Returns a subscription and persists until the subscription is dropped.
616    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    /// Register a listener to be called when nothing in the window has focus.
640    /// This typically happens when the node that was focused is removed from the tree,
641    /// and this callback lets you chose a default place to restore the users focus.
642    /// Returns a subscription and persists until the subscription is dropped.
643    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    /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
661    /// Returns a subscription and persists until the subscription is dropped.
662    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    /// Schedule a future to be run asynchronously.
692    /// The given callback is invoked with a [`WeakEntity<V>`] to avoid leaking the entity for a long-running process.
693    /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the entity across await points.
694    /// The returned future will be polled on the main thread.
695    #[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    /// Schedule a future to be run asynchronously with the given priority.
706    /// The given callback is invoked with a [`WeakEntity<V>`] to avoid leaking the entity for a long-running process.
707    /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the entity across await points.
708    /// The returned future will be polled on the main thread.
709    #[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    /// Register a callback to be invoked when the given global state changes.
725    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 the entity has been dropped, remove this observer.
736                if view.upgrade().is_none() {
737                    return false;
738                }
739                // If the window is unavailable (e.g. temporarily taken during a
740                // nested update, or already closed), skip this notification but
741                // keep the observer alive so it can fire on future changes.
742                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    /// Register a callback to be invoked when the given Action type is dispatched to the window.
755    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    /// Move focus to the current view, assuming it implements [`Focusable`].
772    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    /// Emit an event of the specified type, which can be handled by other entities that have subscribed via `subscribe` methods on their respective contexts.
785    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}