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