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};
6use anyhow::Result;
7use futures::FutureExt;
8use gpui_util::Deferred;
9use std::{
10    any::{Any, TypeId},
11    borrow::{Borrow, BorrowMut},
12    future::Future,
13    ops,
14    sync::Arc,
15};
16
17use super::{App, AsyncWindowContext, Entity, KeystrokeEvent};
18
19/// The app context, with specialized behavior for the given entity.
20pub struct Context<'a, T> {
21    app: &'a mut App,
22    entity_state: WeakEntity<T>,
23}
24
25impl<'a, T> ops::Deref for Context<'a, T> {
26    type Target = App;
27
28    fn deref(&self) -> &Self::Target {
29        self.app
30    }
31}
32
33impl<'a, T> ops::DerefMut for Context<'a, T> {
34    fn deref_mut(&mut self) -> &mut Self::Target {
35        self.app
36    }
37}
38
39impl<'a, T: 'static> Context<'a, T> {
40    pub(crate) fn new_context(app: &'a mut App, entity_state: WeakEntity<T>) -> Self {
41        Self { app, entity_state }
42    }
43
44    /// The entity id of the entity backing this context.
45    pub fn entity_id(&self) -> EntityId {
46        self.entity_state.entity_id
47    }
48
49    /// Returns a handle to the entity belonging to this context.
50    pub fn entity(&self) -> Entity<T> {
51        self.weak_entity()
52            .upgrade()
53            .expect("The entity must be alive if we have a entity context")
54    }
55
56    /// Returns a weak handle to the entity belonging to this context.
57    pub fn weak_entity(&self) -> WeakEntity<T> {
58        self.entity_state.clone()
59    }
60
61    /// Arranges for the given function to be called whenever [`Context::notify`] is
62    /// called with the given entity.
63    pub fn observe<W>(
64        &mut self,
65        entity: &Entity<W>,
66        mut on_notify: impl FnMut(&mut T, Entity<W>, &mut Context<T>) + 'static,
67    ) -> Subscription
68    where
69        T: 'static,
70        W: 'static,
71    {
72        let this = self.weak_entity();
73        self.app.observe_internal(entity, move |e, cx| {
74            if let Some(this) = this.upgrade() {
75                this.update(cx, |this, cx| on_notify(this, e, cx));
76                true
77            } else {
78                false
79            }
80        })
81    }
82
83    /// Observe changes to ourselves
84    pub fn observe_self(
85        &mut self,
86        mut on_event: impl FnMut(&mut T, &mut Context<T>) + 'static,
87    ) -> Subscription
88    where
89        T: 'static,
90    {
91        let this = self.entity();
92        self.app.observe(&this, move |this, cx| {
93            this.update(cx, |this, cx| on_event(this, cx))
94        })
95    }
96
97    /// Subscribe to an event type from another entity
98    pub fn subscribe<T2, Evt>(
99        &mut self,
100        entity: &Entity<T2>,
101        mut on_event: impl FnMut(&mut T, Entity<T2>, &Evt, &mut Context<T>) + 'static,
102    ) -> Subscription
103    where
104        T: 'static,
105        T2: 'static + EventEmitter<Evt>,
106        Evt: 'static,
107    {
108        let this = self.weak_entity();
109        self.app.subscribe_internal(entity, move |e, event, cx| {
110            if let Some(this) = this.upgrade() {
111                this.update(cx, |this, cx| on_event(this, e, event, cx));
112                true
113            } else {
114                false
115            }
116        })
117    }
118
119    /// Subscribe to an event type from ourself
120    pub fn subscribe_self<Evt>(
121        &mut self,
122        mut on_event: impl FnMut(&mut T, &Evt, &mut Context<T>) + 'static,
123    ) -> Subscription
124    where
125        T: 'static + EventEmitter<Evt>,
126        Evt: 'static,
127    {
128        let this = self.entity();
129        self.app.subscribe(&this, move |this, evt, cx| {
130            this.update(cx, |this, cx| on_event(this, evt, cx))
131        })
132    }
133
134    /// Register a callback to be invoked when GPUI releases this entity.
135    pub fn on_release(&self, on_release: impl FnOnce(&mut T, &mut App) + 'static) -> Subscription
136    where
137        T: 'static,
138    {
139        let (subscription, activate) = self.app.release_listeners.insert(
140            self.entity_state.entity_id,
141            Box::new(move |this, cx| {
142                let this = this.downcast_mut().expect("invalid entity type");
143                on_release(this, cx);
144            }),
145        );
146        activate();
147        subscription
148    }
149
150    /// Register a callback to be run on the release of another entity
151    pub fn observe_release<T2>(
152        &self,
153        entity: &Entity<T2>,
154        on_release: impl FnOnce(&mut T, &mut T2, &mut Context<T>) + 'static,
155    ) -> Subscription
156    where
157        T: Any,
158        T2: 'static,
159    {
160        let entity_id = entity.entity_id();
161        let this = self.weak_entity();
162        let (subscription, activate) = self.app.release_listeners.insert(
163            entity_id,
164            Box::new(move |entity, cx| {
165                let entity = entity.downcast_mut().expect("invalid entity type");
166                if let Some(this) = this.upgrade() {
167                    this.update(cx, |this, cx| on_release(this, entity, cx));
168                }
169            }),
170        );
171        activate();
172        subscription
173    }
174
175    /// Register a callback to for updates to the given global
176    pub fn observe_global<G: 'static>(
177        &mut self,
178        mut f: impl FnMut(&mut T, &mut Context<T>) + 'static,
179    ) -> Subscription
180    where
181        T: 'static,
182    {
183        let handle = self.weak_entity();
184        let (subscription, activate) = self.global_observers.insert(
185            TypeId::of::<G>(),
186            Box::new(move |cx| handle.update(cx, |view, cx| f(view, cx)).is_ok()),
187        );
188        self.defer(move |_| activate());
189        subscription
190    }
191
192    /// Register a callback to be invoked when the application is about to restart.
193    pub fn on_app_restart(
194        &self,
195        mut on_restart: impl FnMut(&mut T, &mut App) + 'static,
196    ) -> Subscription
197    where
198        T: 'static,
199    {
200        let handle = self.weak_entity();
201        self.app.on_app_restart(move |cx| {
202            handle.update(cx, |entity, cx| on_restart(entity, cx)).ok();
203        })
204    }
205
206    /// Arrange for the given function to be invoked whenever the application is quit.
207    /// The future returned from this callback will be polled for up to [crate::SHUTDOWN_TIMEOUT] until the app fully quits.
208    pub fn on_app_quit<Fut>(
209        &self,
210        mut on_quit: impl FnMut(&mut T, &mut Context<T>) -> Fut + 'static,
211    ) -> Subscription
212    where
213        Fut: 'static + Future<Output = ()>,
214        T: 'static,
215    {
216        let handle = self.weak_entity();
217        self.app.on_app_quit(move |cx| {
218            let future = handle.update(cx, |entity, cx| on_quit(entity, cx)).ok();
219            async move {
220                if let Some(future) = future {
221                    future.await;
222                }
223            }
224            .boxed_local()
225        })
226    }
227
228    /// Tell GPUI that this entity has changed and observers of it should be notified.
229    pub fn notify(&mut self) {
230        self.app.notify(self.entity_state.entity_id);
231    }
232
233    /// Spawn the future returned by the given function.
234    /// The function is provided a weak handle to the entity owned by this context and a context that can be held across await points.
235    /// The returned task must be held or detached.
236    #[track_caller]
237    pub fn spawn<AsyncFn, R>(&self, f: AsyncFn) -> Task<R>
238    where
239        T: 'static,
240        AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncApp) -> R + 'static,
241        R: 'static,
242    {
243        let this = self.weak_entity();
244        self.app.spawn(async move |cx| f(this, cx).await)
245    }
246
247    /// Convenience method for accessing view state in an event callback.
248    ///
249    /// Many GPUI callbacks take the form of `Fn(&E, &mut Window, &mut App)`,
250    /// but it's often useful to be able to access view state in these
251    /// callbacks. This method provides a convenient way to do so.
252    pub fn listener<E: ?Sized>(
253        &self,
254        f: impl Fn(&mut T, &E, &mut Window, &mut Context<T>) + 'static,
255    ) -> impl Fn(&E, &mut Window, &mut App) + 'static {
256        let view = self.entity().downgrade();
257        move |e: &E, window: &mut Window, cx: &mut App| {
258            view.update(cx, |view, cx| f(view, e, window, cx)).ok();
259        }
260    }
261
262    /// Convenience method for producing view state in a closure.
263    /// See `listener` for more details.
264    pub fn processor<E, R>(
265        &self,
266        f: impl Fn(&mut T, E, &mut Window, &mut Context<T>) -> R + 'static,
267    ) -> impl Fn(E, &mut Window, &mut App) -> R + 'static {
268        let view = self.entity();
269        move |e: E, window: &mut Window, cx: &mut App| {
270            view.update(cx, |view, cx| f(view, e, window, cx))
271        }
272    }
273
274    /// Run something using this entity and cx, when the returned struct is dropped
275    pub fn on_drop(
276        &self,
277        f: impl FnOnce(&mut T, &mut Context<T>) + 'static,
278    ) -> Deferred<impl FnOnce()> {
279        let this = self.weak_entity();
280        let mut cx = self.to_async();
281        gpui_util::defer(move || {
282            this.update(&mut cx, f).ok();
283        })
284    }
285
286    /// Focus the given view in the given window. View type is required to implement Focusable.
287    pub fn focus_view<W: Focusable>(&mut self, view: &Entity<W>, window: &mut Window) {
288        window.focus(&view.focus_handle(self), self);
289    }
290
291    /// Sets a given callback to be run on the next frame.
292    pub fn on_next_frame(
293        &self,
294        window: &mut Window,
295        f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
296    ) where
297        T: 'static,
298    {
299        let view = self.entity();
300        window.on_next_frame(move |window, cx| view.update(cx, |view, cx| f(view, window, cx)));
301    }
302
303    /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
304    /// that are currently on the stack to be returned to the app.
305    pub fn defer_in(
306        &mut self,
307        window: &Window,
308        f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
309    ) {
310        let view = self.weak_entity();
311        let entity_id = self.entity_id();
312        self.ensure_window(entity_id, window.handle.id);
313        self.app.defer(move |cx| {
314            cx.with_window(entity_id, |window, cx| {
315                view.update(cx, |view, cx| f(view, window, cx)).ok();
316            });
317        });
318    }
319
320    /// Observe another entity for changes to its state, as tracked by [`Context::notify`].
321    pub fn observe_in<V2>(
322        &mut self,
323        observed: &Entity<V2>,
324        window: &mut Window,
325        mut on_notify: impl FnMut(&mut T, Entity<V2>, &mut Window, &mut Context<T>) + 'static,
326    ) -> Subscription
327    where
328        V2: 'static,
329        T: 'static,
330    {
331        let observed_id = observed.entity_id();
332        let observed = observed.downgrade();
333        let observer = self.weak_entity();
334        let observer_id = self.entity_id();
335        self.ensure_window(observer_id, window.handle.id);
336        self.new_observer(
337            observed_id,
338            Box::new(move |cx| {
339                let Some((observer, observed)) = observer.upgrade().zip(observed.upgrade()) else {
340                    return false;
341                };
342                cx.with_window(observer_id, |window, cx| {
343                    observer.update(cx, |observer, cx| {
344                        on_notify(observer, observed, window, cx);
345                    });
346                });
347                true
348            }),
349        )
350    }
351
352    /// Subscribe to events emitted by another entity.
353    /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
354    /// 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.
355    pub fn subscribe_in<Emitter, Evt>(
356        &mut self,
357        emitter: &Entity<Emitter>,
358        window: &Window,
359        mut on_event: impl FnMut(&mut T, &Entity<Emitter>, &Evt, &mut Window, &mut Context<T>) + 'static,
360    ) -> Subscription
361    where
362        Emitter: EventEmitter<Evt>,
363        Evt: 'static,
364    {
365        let emitter = emitter.downgrade();
366        let subscriber = self.weak_entity();
367        let subscriber_id = self.entity_id();
368        self.ensure_window(subscriber_id, window.handle.id);
369        self.new_subscription(
370            emitter.entity_id(),
371            (
372                TypeId::of::<Evt>(),
373                Box::new(move |event, cx| {
374                    let Some((subscriber, emitter)) = subscriber.upgrade().zip(emitter.upgrade())
375                    else {
376                        return false;
377                    };
378                    let event = event.downcast_ref().expect("invalid event type");
379                    cx.with_window(subscriber_id, |window, cx| {
380                        subscriber.update(cx, |subscriber, cx| {
381                            on_event(subscriber, &emitter, event, window, cx);
382                        });
383                    });
384                    true
385                }),
386            ),
387        )
388    }
389
390    /// Register a callback to be invoked when the view is released.
391    ///
392    /// The callback receives a handle to the view's window. This handle may be
393    /// invalid, if the window was closed before the view was released.
394    pub fn on_release_in(
395        &mut self,
396        window: &Window,
397        on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static,
398    ) -> Subscription {
399        let entity = self.entity();
400        self.app.observe_release_in(&entity, window, on_release)
401    }
402
403    /// Register a callback to be invoked when the given Entity is released.
404    pub fn observe_release_in<T2>(
405        &self,
406        observed: &Entity<T2>,
407        window: &Window,
408        mut on_release: impl FnMut(&mut T, &mut T2, &mut Window, &mut Context<T>) + 'static,
409    ) -> Subscription
410    where
411        T: 'static,
412        T2: 'static,
413    {
414        let observer = self.weak_entity();
415        self.app
416            .observe_release_in(observed, window, move |observed, window, cx| {
417                observer
418                    .update(cx, |observer, cx| {
419                        on_release(observer, observed, window, cx)
420                    })
421                    .ok();
422            })
423    }
424
425    /// Register a callback to be invoked when the window is resized.
426    pub fn observe_window_bounds(
427        &self,
428        window: &mut Window,
429        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
430    ) -> Subscription {
431        let view = self.weak_entity();
432        let (subscription, activate) = window.bounds_observers.insert(
433            (),
434            Box::new(move |window, cx| {
435                view.update(cx, |view, cx| callback(view, window, cx))
436                    .is_ok()
437            }),
438        );
439        activate();
440        subscription
441    }
442
443    /// Register a callback to be invoked when the window is activated or deactivated.
444    pub fn observe_window_activation(
445        &self,
446        window: &mut Window,
447        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
448    ) -> Subscription {
449        let view = self.weak_entity();
450        let (subscription, activate) = window.activation_observers.insert(
451            (),
452            Box::new(move |window, cx| {
453                view.update(cx, |view, cx| callback(view, window, cx))
454                    .is_ok()
455            }),
456        );
457        activate();
458        subscription
459    }
460
461    /// Registers a callback to be invoked when the window appearance changes.
462    pub fn observe_window_appearance(
463        &self,
464        window: &mut Window,
465        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
466    ) -> Subscription {
467        let view = self.weak_entity();
468        let (subscription, activate) = window.appearance_observers.insert(
469            (),
470            Box::new(move |window, cx| {
471                view.update(cx, |view, cx| callback(view, window, cx))
472                    .is_ok()
473            }),
474        );
475        activate();
476        subscription
477    }
478
479    /// Registers a callback to be invoked when the window button layout changes.
480    pub fn observe_button_layout_changed(
481        &self,
482        window: &mut Window,
483        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
484    ) -> Subscription {
485        let view = self.weak_entity();
486        let (subscription, activate) = window.button_layout_observers.insert(
487            (),
488            Box::new(move |window, cx| {
489                view.update(cx, |view, cx| callback(view, window, cx))
490                    .is_ok()
491            }),
492        );
493        activate();
494        subscription
495    }
496
497    /// Register a callback to be invoked when a keystroke is received by the application
498    /// in any window. Note that this fires after all other action and event mechanisms have resolved
499    /// and that this API will not be invoked if the event's propagation is stopped.
500    pub fn observe_keystrokes(
501        &mut self,
502        mut f: impl FnMut(&mut T, &KeystrokeEvent, &mut Window, &mut Context<T>) + 'static,
503    ) -> Subscription {
504        fn inner(
505            keystroke_observers: &SubscriberSet<(), KeystrokeObserver>,
506            handler: KeystrokeObserver,
507        ) -> Subscription {
508            let (subscription, activate) = keystroke_observers.insert((), handler);
509            activate();
510            subscription
511        }
512
513        let view = self.weak_entity();
514        inner(
515            &self.keystroke_observers,
516            Box::new(move |event, window, cx| {
517                if let Some(view) = view.upgrade() {
518                    view.update(cx, |view, cx| f(view, event, window, cx));
519                    true
520                } else {
521                    false
522                }
523            }),
524        )
525    }
526
527    /// Register a callback to be invoked when the window's pending input changes.
528    pub fn observe_pending_input(
529        &self,
530        window: &mut Window,
531        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
532    ) -> Subscription {
533        let view = self.weak_entity();
534        let (subscription, activate) = window.pending_input_observers.insert(
535            (),
536            Box::new(move |window, cx| {
537                view.update(cx, |view, cx| callback(view, window, cx))
538                    .is_ok()
539            }),
540        );
541        activate();
542        subscription
543    }
544
545    /// Register a listener to be called when the given focus handle receives focus.
546    /// Returns a subscription and persists until the subscription is dropped.
547    pub fn on_focus(
548        &mut self,
549        handle: &FocusHandle,
550        window: &mut Window,
551        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
552    ) -> Subscription {
553        let view = self.weak_entity();
554        let focus_id = handle.id;
555        let (subscription, activate) =
556            window.new_focus_listener(Box::new(move |event, window, cx| {
557                view.update(cx, |view, cx| {
558                    if event.previous_focus_path.last() != Some(&focus_id)
559                        && event.current_focus_path.last() == Some(&focus_id)
560                    {
561                        listener(view, window, cx)
562                    }
563                })
564                .is_ok()
565            }));
566        self.defer(|_| activate());
567        subscription
568    }
569
570    /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
571    /// This does not fire if the given focus handle - or one of its descendants - was previously focused.
572    /// Returns a subscription and persists until the subscription is dropped.
573    pub fn on_focus_in(
574        &mut self,
575        handle: &FocusHandle,
576        window: &mut Window,
577        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
578    ) -> Subscription {
579        let view = self.weak_entity();
580        let focus_id = handle.id;
581        let (subscription, activate) =
582            window.new_focus_listener(Box::new(move |event, window, cx| {
583                view.update(cx, |view, cx| {
584                    if event.is_focus_in(focus_id) {
585                        listener(view, window, cx)
586                    }
587                })
588                .is_ok()
589            }));
590        self.defer(|_| activate());
591        subscription
592    }
593
594    /// Register a listener to be called when the given focus handle loses focus.
595    /// Returns a subscription and persists until the subscription is dropped.
596    pub fn on_blur(
597        &mut self,
598        handle: &FocusHandle,
599        window: &mut Window,
600        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
601    ) -> Subscription {
602        let view = self.weak_entity();
603        let focus_id = handle.id;
604        let (subscription, activate) =
605            window.new_focus_listener(Box::new(move |event, window, cx| {
606                view.update(cx, |view, cx| {
607                    if event.previous_focus_path.last() == Some(&focus_id)
608                        && event.current_focus_path.last() != Some(&focus_id)
609                    {
610                        listener(view, window, cx)
611                    }
612                })
613                .is_ok()
614            }));
615        self.defer(|_| activate());
616        subscription
617    }
618
619    /// Register a listener to be called when nothing in the window has focus.
620    /// This typically happens when the node that was focused is removed from the tree,
621    /// and this callback lets you chose a default place to restore the users focus.
622    /// Returns a subscription and persists until the subscription is dropped.
623    pub fn on_focus_lost(
624        &mut self,
625        window: &mut Window,
626        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
627    ) -> Subscription {
628        let view = self.weak_entity();
629        let (subscription, activate) = window.focus_lost_listeners.insert(
630            (),
631            Box::new(move |window, cx| {
632                view.update(cx, |view, cx| listener(view, window, cx))
633                    .is_ok()
634            }),
635        );
636        self.defer(|_| activate());
637        subscription
638    }
639
640    /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
641    /// Returns a subscription and persists until the subscription is dropped.
642    pub fn on_focus_out(
643        &mut self,
644        handle: &FocusHandle,
645        window: &mut Window,
646        mut listener: impl FnMut(&mut T, FocusOutEvent, &mut Window, &mut Context<T>) + 'static,
647    ) -> Subscription {
648        let view = self.weak_entity();
649        let focus_id = handle.id;
650        let (subscription, activate) =
651            window.new_focus_listener(Box::new(move |event, window, cx| {
652                view.update(cx, |view, cx| {
653                    if let Some(blurred_id) = event.previous_focus_path.last().copied()
654                        && event.is_focus_out(focus_id)
655                    {
656                        let event = FocusOutEvent {
657                            blurred: WeakFocusHandle {
658                                id: blurred_id,
659                                handles: Arc::downgrade(&cx.focus_handles),
660                            },
661                        };
662                        listener(view, event, window, cx)
663                    }
664                })
665                .is_ok()
666            }));
667        self.defer(|_| activate());
668        subscription
669    }
670
671    /// Schedule a future to be run asynchronously.
672    /// The given callback is invoked with a [`WeakEntity<V>`] to avoid leaking the entity for a long-running process.
673    /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the entity across await points.
674    /// The returned future will be polled on the main thread.
675    #[track_caller]
676    pub fn spawn_in<AsyncFn, R>(&self, window: &Window, f: AsyncFn) -> Task<R>
677    where
678        R: 'static,
679        AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
680    {
681        let view = self.weak_entity();
682        window.spawn(self, async move |cx| f(view, cx).await)
683    }
684
685    /// Schedule a future to be run asynchronously with the given priority.
686    /// The given callback is invoked with a [`WeakEntity<V>`] to avoid leaking the entity for a long-running process.
687    /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the entity across await points.
688    /// The returned future will be polled on the main thread.
689    #[track_caller]
690    pub fn spawn_in_with_priority<AsyncFn, R>(
691        &self,
692        priority: Priority,
693        window: &Window,
694        f: AsyncFn,
695    ) -> Task<R>
696    where
697        R: 'static,
698        AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
699    {
700        let view = self.weak_entity();
701        window.spawn_with_priority(priority, self, async move |cx| f(view, cx).await)
702    }
703
704    /// Register a callback to be invoked when the given global state changes.
705    pub fn observe_global_in<G: Global>(
706        &mut self,
707        window: &Window,
708        mut f: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
709    ) -> Subscription {
710        let window_handle = window.handle;
711        let view = self.weak_entity();
712        let (subscription, activate) = self.global_observers.insert(
713            TypeId::of::<G>(),
714            Box::new(move |cx| {
715                // If the entity has been dropped, remove this observer.
716                if view.upgrade().is_none() {
717                    return false;
718                }
719                // If the window is unavailable (e.g. temporarily taken during a
720                // nested update, or already closed), skip this notification but
721                // keep the observer alive so it can fire on future changes.
722                let Ok(entity_alive) = window_handle.update(cx, |_, window, cx| {
723                    view.update(cx, |view, cx| f(view, window, cx)).is_ok()
724                }) else {
725                    return true;
726                };
727                entity_alive
728            }),
729        );
730        self.defer(move |_| activate());
731        subscription
732    }
733
734    /// Register a callback to be invoked when the given Action type is dispatched to the window.
735    pub fn on_action(
736        &mut self,
737        action_type: TypeId,
738        window: &mut Window,
739        listener: impl Fn(&mut T, &dyn Any, DispatchPhase, &mut Window, &mut Context<T>) + 'static,
740    ) {
741        let handle = self.weak_entity();
742        window.on_action(action_type, move |action, phase, window, cx| {
743            handle
744                .update(cx, |view, cx| {
745                    listener(view, action, phase, window, cx);
746                })
747                .ok();
748        });
749    }
750
751    /// Move focus to the current view, assuming it implements [`Focusable`].
752    pub fn focus_self(&mut self, window: &mut Window)
753    where
754        T: Focusable,
755    {
756        let view = self.entity();
757        window.defer(self, move |window, cx| {
758            view.read(cx).focus_handle(cx).focus(window, cx)
759        })
760    }
761}
762
763impl<T> Context<'_, T> {
764    /// Emit an event of the specified type, which can be handled by other entities that have subscribed via `subscribe` methods on their respective contexts.
765    pub fn emit<Evt>(&mut self, event: Evt)
766    where
767        T: EventEmitter<Evt>,
768        Evt: 'static,
769    {
770        let event = self
771            .event_arena
772            .alloc(|| event)
773            .map(|it| it as &mut dyn Any);
774        self.app.pending_effects.push_back(Effect::Emit {
775            emitter: self.entity_state.entity_id,
776            event_type: TypeId::of::<Evt>(),
777            event,
778        });
779    }
780}
781
782impl<T> AppContext for Context<'_, T> {
783    #[inline]
784    fn new<U: 'static>(&mut self, build_entity: impl FnOnce(&mut Context<U>) -> U) -> Entity<U> {
785        self.app.new(build_entity)
786    }
787
788    #[inline]
789    fn reserve_entity<U: 'static>(&mut self) -> Reservation<U> {
790        self.app.reserve_entity()
791    }
792
793    #[inline]
794    fn insert_entity<U: 'static>(
795        &mut self,
796        reservation: Reservation<U>,
797        build_entity: impl FnOnce(&mut Context<U>) -> U,
798    ) -> Entity<U> {
799        self.app.insert_entity(reservation, build_entity)
800    }
801
802    #[inline]
803    fn update_entity<U: 'static, R>(
804        &mut self,
805        handle: &Entity<U>,
806        update: impl FnOnce(&mut U, &mut Context<U>) -> R,
807    ) -> R {
808        self.app.update_entity(handle, update)
809    }
810
811    #[inline]
812    fn as_mut<'a, E>(&'a mut self, handle: &Entity<E>) -> super::GpuiBorrow<'a, E>
813    where
814        E: 'static,
815    {
816        self.app.as_mut(handle)
817    }
818
819    #[inline]
820    fn read_entity<U, R>(&self, handle: &Entity<U>, read: impl FnOnce(&U, &App) -> R) -> R
821    where
822        U: 'static,
823    {
824        self.app.read_entity(handle, read)
825    }
826
827    #[inline]
828    fn update_window<R, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<R>
829    where
830        F: FnOnce(AnyView, &mut Window, &mut App) -> R,
831    {
832        self.app.update_window(window, update)
833    }
834
835    #[inline]
836    fn with_window<R>(
837        &mut self,
838        entity_id: EntityId,
839        f: impl FnOnce(&mut Window, &mut App) -> R,
840    ) -> Option<R> {
841        self.app.with_window(entity_id, f)
842    }
843
844    #[inline]
845    fn read_window<U, R>(
846        &self,
847        window: &WindowHandle<U>,
848        read: impl FnOnce(Entity<U>, &App) -> R,
849    ) -> Result<R>
850    where
851        U: 'static,
852    {
853        self.app.read_window(window, read)
854    }
855
856    #[inline]
857    fn background_spawn<R>(&self, future: impl Future<Output = R> + Send + 'static) -> Task<R>
858    where
859        R: Send + 'static,
860    {
861        self.app.background_executor.spawn(future)
862    }
863
864    #[inline]
865    fn read_global<G, R>(&self, callback: impl FnOnce(&G, &App) -> R) -> R
866    where
867        G: Global,
868    {
869        self.app.read_global(callback)
870    }
871}
872
873impl<T> Borrow<App> for Context<'_, T> {
874    fn borrow(&self) -> &App {
875        self.app
876    }
877}
878
879impl<T> BorrowMut<App> for Context<'_, T> {
880    fn borrow_mut(&mut self) -> &mut App {
881        self.app
882    }
883}