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.entity();
311        window.defer(self, move |window, cx| {
312            view.update(cx, |view, cx| f(view, window, cx))
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 window_handle = window.handle;
330        let observer = self.weak_entity();
331        self.new_observer(
332            observed_id,
333            Box::new(move |cx| {
334                window_handle
335                    .update(cx, |_, window, cx| {
336                        if let Some((observer, observed)) =
337                            observer.upgrade().zip(observed.upgrade())
338                        {
339                            observer.update(cx, |observer, cx| {
340                                on_notify(observer, observed, window, cx);
341                            });
342                            true
343                        } else {
344                            false
345                        }
346                    })
347                    .unwrap_or(false)
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 window_handle = window.handle;
367        let subscriber = self.weak_entity();
368        self.new_subscription(
369            emitter.entity_id(),
370            (
371                TypeId::of::<Evt>(),
372                Box::new(move |event, cx| {
373                    window_handle
374                        .update(cx, |_, window, cx| {
375                            if let Some((subscriber, emitter)) =
376                                subscriber.upgrade().zip(emitter.upgrade())
377                            {
378                                let event = event.downcast_ref().expect("invalid event type");
379                                subscriber.update(cx, |subscriber, cx| {
380                                    on_event(subscriber, &emitter, event, window, cx);
381                                });
382                                true
383                            } else {
384                                false
385                            }
386                        })
387                        .unwrap_or(false)
388                }),
389            ),
390        )
391    }
392
393    /// Register a callback to be invoked when the view is released.
394    ///
395    /// The callback receives a handle to the view's window. This handle may be
396    /// invalid, if the window was closed before the view was released.
397    pub fn on_release_in(
398        &mut self,
399        window: &Window,
400        on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static,
401    ) -> Subscription {
402        let entity = self.entity();
403        self.app.observe_release_in(&entity, window, on_release)
404    }
405
406    /// Register a callback to be invoked when the given Entity is released.
407    pub fn observe_release_in<T2>(
408        &self,
409        observed: &Entity<T2>,
410        window: &Window,
411        mut on_release: impl FnMut(&mut T, &mut T2, &mut Window, &mut Context<T>) + 'static,
412    ) -> Subscription
413    where
414        T: 'static,
415        T2: 'static,
416    {
417        let observer = self.weak_entity();
418        self.app
419            .observe_release_in(observed, window, move |observed, window, cx| {
420                observer
421                    .update(cx, |observer, cx| {
422                        on_release(observer, observed, window, cx)
423                    })
424                    .ok();
425            })
426    }
427
428    /// Register a callback to be invoked when the window is resized.
429    pub fn observe_window_bounds(
430        &self,
431        window: &mut Window,
432        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
433    ) -> Subscription {
434        let view = self.weak_entity();
435        let (subscription, activate) = window.bounds_observers.insert(
436            (),
437            Box::new(move |window, cx| {
438                view.update(cx, |view, cx| callback(view, window, cx))
439                    .is_ok()
440            }),
441        );
442        activate();
443        subscription
444    }
445
446    /// Register a callback to be invoked when the window is activated or deactivated.
447    pub fn observe_window_activation(
448        &self,
449        window: &mut Window,
450        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
451    ) -> Subscription {
452        let view = self.weak_entity();
453        let (subscription, activate) = window.activation_observers.insert(
454            (),
455            Box::new(move |window, cx| {
456                view.update(cx, |view, cx| callback(view, window, cx))
457                    .is_ok()
458            }),
459        );
460        activate();
461        subscription
462    }
463
464    /// Registers a callback to be invoked when the window appearance changes.
465    pub fn observe_window_appearance(
466        &self,
467        window: &mut Window,
468        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
469    ) -> Subscription {
470        let view = self.weak_entity();
471        let (subscription, activate) = window.appearance_observers.insert(
472            (),
473            Box::new(move |window, cx| {
474                view.update(cx, |view, cx| callback(view, window, cx))
475                    .is_ok()
476            }),
477        );
478        activate();
479        subscription
480    }
481
482    /// Registers a callback to be invoked when the window button layout changes.
483    pub fn observe_button_layout_changed(
484        &self,
485        window: &mut Window,
486        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
487    ) -> Subscription {
488        let view = self.weak_entity();
489        let (subscription, activate) = window.button_layout_observers.insert(
490            (),
491            Box::new(move |window, cx| {
492                view.update(cx, |view, cx| callback(view, window, cx))
493                    .is_ok()
494            }),
495        );
496        activate();
497        subscription
498    }
499
500    /// Register a callback to be invoked when a keystroke is received by the application
501    /// in any window. Note that this fires after all other action and event mechanisms have resolved
502    /// and that this API will not be invoked if the event's propagation is stopped.
503    pub fn observe_keystrokes(
504        &mut self,
505        mut f: impl FnMut(&mut T, &KeystrokeEvent, &mut Window, &mut Context<T>) + 'static,
506    ) -> Subscription {
507        fn inner(
508            keystroke_observers: &SubscriberSet<(), KeystrokeObserver>,
509            handler: KeystrokeObserver,
510        ) -> Subscription {
511            let (subscription, activate) = keystroke_observers.insert((), handler);
512            activate();
513            subscription
514        }
515
516        let view = self.weak_entity();
517        inner(
518            &self.keystroke_observers,
519            Box::new(move |event, window, cx| {
520                if let Some(view) = view.upgrade() {
521                    view.update(cx, |view, cx| f(view, event, window, cx));
522                    true
523                } else {
524                    false
525                }
526            }),
527        )
528    }
529
530    /// Register a callback to be invoked when the window's pending input changes.
531    pub fn observe_pending_input(
532        &self,
533        window: &mut Window,
534        mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
535    ) -> Subscription {
536        let view = self.weak_entity();
537        let (subscription, activate) = window.pending_input_observers.insert(
538            (),
539            Box::new(move |window, cx| {
540                view.update(cx, |view, cx| callback(view, window, cx))
541                    .is_ok()
542            }),
543        );
544        activate();
545        subscription
546    }
547
548    /// Register a listener to be called when the given focus handle receives focus.
549    /// Returns a subscription and persists until the subscription is dropped.
550    pub fn on_focus(
551        &mut self,
552        handle: &FocusHandle,
553        window: &mut Window,
554        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
555    ) -> Subscription {
556        let view = self.weak_entity();
557        let focus_id = handle.id;
558        let (subscription, activate) =
559            window.new_focus_listener(Box::new(move |event, window, cx| {
560                view.update(cx, |view, cx| {
561                    if event.previous_focus_path.last() != Some(&focus_id)
562                        && event.current_focus_path.last() == Some(&focus_id)
563                    {
564                        listener(view, window, cx)
565                    }
566                })
567                .is_ok()
568            }));
569        self.defer(|_| activate());
570        subscription
571    }
572
573    /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
574    /// This does not fire if the given focus handle - or one of its descendants - was previously focused.
575    /// Returns a subscription and persists until the subscription is dropped.
576    pub fn on_focus_in(
577        &mut self,
578        handle: &FocusHandle,
579        window: &mut Window,
580        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
581    ) -> Subscription {
582        let view = self.weak_entity();
583        let focus_id = handle.id;
584        let (subscription, activate) =
585            window.new_focus_listener(Box::new(move |event, window, cx| {
586                view.update(cx, |view, cx| {
587                    if event.is_focus_in(focus_id) {
588                        listener(view, window, cx)
589                    }
590                })
591                .is_ok()
592            }));
593        self.defer(|_| activate());
594        subscription
595    }
596
597    /// Register a listener to be called when the given focus handle loses focus.
598    /// Returns a subscription and persists until the subscription is dropped.
599    pub fn on_blur(
600        &mut self,
601        handle: &FocusHandle,
602        window: &mut Window,
603        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
604    ) -> Subscription {
605        let view = self.weak_entity();
606        let focus_id = handle.id;
607        let (subscription, activate) =
608            window.new_focus_listener(Box::new(move |event, window, cx| {
609                view.update(cx, |view, cx| {
610                    if event.previous_focus_path.last() == Some(&focus_id)
611                        && event.current_focus_path.last() != Some(&focus_id)
612                    {
613                        listener(view, window, cx)
614                    }
615                })
616                .is_ok()
617            }));
618        self.defer(|_| activate());
619        subscription
620    }
621
622    /// Register a listener to be called when nothing in the window has focus.
623    /// This typically happens when the node that was focused is removed from the tree,
624    /// and this callback lets you chose a default place to restore the users focus.
625    /// Returns a subscription and persists until the subscription is dropped.
626    pub fn on_focus_lost(
627        &mut self,
628        window: &mut Window,
629        mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
630    ) -> Subscription {
631        let view = self.weak_entity();
632        let (subscription, activate) = window.focus_lost_listeners.insert(
633            (),
634            Box::new(move |window, cx| {
635                view.update(cx, |view, cx| listener(view, window, cx))
636                    .is_ok()
637            }),
638        );
639        self.defer(|_| activate());
640        subscription
641    }
642
643    /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
644    /// Returns a subscription and persists until the subscription is dropped.
645    pub fn on_focus_out(
646        &mut self,
647        handle: &FocusHandle,
648        window: &mut Window,
649        mut listener: impl FnMut(&mut T, FocusOutEvent, &mut Window, &mut Context<T>) + 'static,
650    ) -> Subscription {
651        let view = self.weak_entity();
652        let focus_id = handle.id;
653        let (subscription, activate) =
654            window.new_focus_listener(Box::new(move |event, window, cx| {
655                view.update(cx, |view, cx| {
656                    if let Some(blurred_id) = event.previous_focus_path.last().copied()
657                        && event.is_focus_out(focus_id)
658                    {
659                        let event = FocusOutEvent {
660                            blurred: WeakFocusHandle {
661                                id: blurred_id,
662                                handles: Arc::downgrade(&cx.focus_handles),
663                            },
664                        };
665                        listener(view, event, window, cx)
666                    }
667                })
668                .is_ok()
669            }));
670        self.defer(|_| activate());
671        subscription
672    }
673
674    /// Schedule a future to be run asynchronously.
675    /// The given callback is invoked with a [`WeakEntity<V>`] to avoid leaking the entity for a long-running process.
676    /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the entity across await points.
677    /// The returned future will be polled on the main thread.
678    #[track_caller]
679    pub fn spawn_in<AsyncFn, R>(&self, window: &Window, f: AsyncFn) -> Task<R>
680    where
681        R: 'static,
682        AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
683    {
684        let view = self.weak_entity();
685        window.spawn(self, async move |cx| f(view, cx).await)
686    }
687
688    /// Schedule a future to be run asynchronously with the given priority.
689    /// The given callback is invoked with a [`WeakEntity<V>`] to avoid leaking the entity for a long-running process.
690    /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the entity across await points.
691    /// The returned future will be polled on the main thread.
692    #[track_caller]
693    pub fn spawn_in_with_priority<AsyncFn, R>(
694        &self,
695        priority: Priority,
696        window: &Window,
697        f: AsyncFn,
698    ) -> Task<R>
699    where
700        R: 'static,
701        AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
702    {
703        let view = self.weak_entity();
704        window.spawn_with_priority(priority, self, async move |cx| f(view, cx).await)
705    }
706
707    /// Register a callback to be invoked when the given global state changes.
708    pub fn observe_global_in<G: Global>(
709        &mut self,
710        window: &Window,
711        mut f: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
712    ) -> Subscription {
713        let window_handle = window.handle;
714        let view = self.weak_entity();
715        let (subscription, activate) = self.global_observers.insert(
716            TypeId::of::<G>(),
717            Box::new(move |cx| {
718                // If the entity has been dropped, remove this observer.
719                if view.upgrade().is_none() {
720                    return false;
721                }
722                // If the window is unavailable (e.g. temporarily taken during a
723                // nested update, or already closed), skip this notification but
724                // keep the observer alive so it can fire on future changes.
725                let Ok(entity_alive) = window_handle.update(cx, |_, window, cx| {
726                    view.update(cx, |view, cx| f(view, window, cx)).is_ok()
727                }) else {
728                    return true;
729                };
730                entity_alive
731            }),
732        );
733        self.defer(move |_| activate());
734        subscription
735    }
736
737    /// Register a callback to be invoked when the given Action type is dispatched to the window.
738    pub fn on_action(
739        &mut self,
740        action_type: TypeId,
741        window: &mut Window,
742        listener: impl Fn(&mut T, &dyn Any, DispatchPhase, &mut Window, &mut Context<T>) + 'static,
743    ) {
744        let handle = self.weak_entity();
745        window.on_action(action_type, move |action, phase, window, cx| {
746            handle
747                .update(cx, |view, cx| {
748                    listener(view, action, phase, window, cx);
749                })
750                .ok();
751        });
752    }
753
754    /// Move focus to the current view, assuming it implements [`Focusable`].
755    pub fn focus_self(&mut self, window: &mut Window)
756    where
757        T: Focusable,
758    {
759        let view = self.entity();
760        window.defer(self, move |window, cx| {
761            view.read(cx).focus_handle(cx).focus(window, cx)
762        })
763    }
764}
765
766impl<T> Context<'_, T> {
767    /// Emit an event of the specified type, which can be handled by other entities that have subscribed via `subscribe` methods on their respective contexts.
768    pub fn emit<Evt>(&mut self, event: Evt)
769    where
770        T: EventEmitter<Evt>,
771        Evt: 'static,
772    {
773        let event = self
774            .event_arena
775            .alloc(|| event)
776            .map(|it| it as &mut dyn Any);
777        self.app.pending_effects.push_back(Effect::Emit {
778            emitter: self.entity_state.entity_id,
779            event_type: TypeId::of::<Evt>(),
780            event,
781        });
782    }
783}
784
785impl<T> AppContext for Context<'_, T> {
786    #[inline]
787    fn new<U: 'static>(&mut self, build_entity: impl FnOnce(&mut Context<U>) -> U) -> Entity<U> {
788        self.app.new(build_entity)
789    }
790
791    #[inline]
792    fn reserve_entity<U: 'static>(&mut self) -> Reservation<U> {
793        self.app.reserve_entity()
794    }
795
796    #[inline]
797    fn insert_entity<U: 'static>(
798        &mut self,
799        reservation: Reservation<U>,
800        build_entity: impl FnOnce(&mut Context<U>) -> U,
801    ) -> Entity<U> {
802        self.app.insert_entity(reservation, build_entity)
803    }
804
805    #[inline]
806    fn update_entity<U: 'static, R>(
807        &mut self,
808        handle: &Entity<U>,
809        update: impl FnOnce(&mut U, &mut Context<U>) -> R,
810    ) -> R {
811        self.app.update_entity(handle, update)
812    }
813
814    #[inline]
815    fn as_mut<'a, E>(&'a mut self, handle: &Entity<E>) -> super::GpuiBorrow<'a, E>
816    where
817        E: 'static,
818    {
819        self.app.as_mut(handle)
820    }
821
822    #[inline]
823    fn read_entity<U, R>(&self, handle: &Entity<U>, read: impl FnOnce(&U, &App) -> R) -> R
824    where
825        U: 'static,
826    {
827        self.app.read_entity(handle, read)
828    }
829
830    #[inline]
831    fn update_window<R, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<R>
832    where
833        F: FnOnce(AnyView, &mut Window, &mut App) -> R,
834    {
835        self.app.update_window(window, update)
836    }
837
838    #[inline]
839    fn read_window<U, R>(
840        &self,
841        window: &WindowHandle<U>,
842        read: impl FnOnce(Entity<U>, &App) -> R,
843    ) -> Result<R>
844    where
845        U: 'static,
846    {
847        self.app.read_window(window, read)
848    }
849
850    #[inline]
851    fn background_spawn<R>(&self, future: impl Future<Output = R> + Send + 'static) -> Task<R>
852    where
853        R: Send + 'static,
854    {
855        self.app.background_executor.spawn(future)
856    }
857
858    #[inline]
859    fn read_global<G, R>(&self, callback: impl FnOnce(&G, &App) -> R) -> R
860    where
861        G: Global,
862    {
863        self.app.read_global(callback)
864    }
865}
866
867impl<T> Borrow<App> for Context<'_, T> {
868    fn borrow(&self) -> &App {
869        self.app
870    }
871}
872
873impl<T> BorrowMut<App> for Context<'_, T> {
874    fn borrow_mut(&mut self) -> &mut App {
875        self.app
876    }
877}