Skip to main content

gpui/app/
context.rs

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