use crate::{ AnyView, AnyWindowHandle, AppContext, AsyncApp, DispatchPhase, Effect, EntityId, EventEmitter, FocusHandle, FocusOutEvent, Focusable, Global, KeystrokeObserver, Reservation, SubscriberSet, Subscription, Task, WeakEntity, WeakFocusHandle, Window, WindowHandle,};use anyhow::Result;use derive_more::{Deref, DerefMut};use futures::FutureExt;use std::{ any::{Any, TypeId}, borrow::{Borrow, BorrowMut}, future::Future, sync::Arc,};use util::Deferred; use super::{App, AsyncWindowContext, Entity, KeystrokeEvent}; /// The app context, with specialized behavior for the given entity.#[derive(Deref, DerefMut)]pub struct Context<'a, T> { #[deref] #[deref_mut] app: &'a mut App, entity_state: WeakEntity<T>,} impl<'a, T: 'static> Context<'a, T> { pub(crate) fn new_context(app: &'a mut App, entity_state: WeakEntity<T>) -> Self { Self { app, entity_state } } /// The entity id of the entity backing this context. pub fn entity_id(&self) -> EntityId { self.entity_state.entity_id } /// Returns a handle to the entity belonging to this context. pub fn entity(&self) -> Entity<T> { self.weak_entity() .upgrade() .expect("The entity must be alive if we have a entity context") } /// Returns a weak handle to the entity belonging to this context. pub fn weak_entity(&self) -> WeakEntity<T> { self.entity_state.clone() } /// Arranges for the given function to be called whenever [`Context::notify`] is /// called with the given entity. pub fn observe<W>( &mut self, entity: &Entity<W>, mut on_notify: impl FnMut(&mut T, Entity<W>, &mut Context<T>) + 'static, ) -> Subscription where T: 'static, W: 'static, { let this = self.weak_entity(); self.app.observe_internal(entity, move |e, cx| { if let Some(this) = this.upgrade() { this.update(cx, |this, cx| on_notify(this, e, cx)); true } else { false } }) } /// Subscribe to an event type from another entity pub fn subscribe<T2, Evt>( &mut self, entity: &Entity<T2>, mut on_event: impl FnMut(&mut T, Entity<T2>, &Evt, &mut Context<T>) + 'static, ) -> Subscription where T: 'static, T2: 'static + EventEmitter<Evt>, Evt: 'static, { let this = self.weak_entity(); self.app.subscribe_internal(entity, move |e, event, cx| { if let Some(this) = this.upgrade() { this.update(cx, |this, cx| on_event(this, e, event, cx)); true } else { false } }) } /// Subscribe to an event type from ourself pub fn subscribe_self<Evt>( &mut self, mut on_event: impl FnMut(&mut T, &Evt, &mut Context<T>) + 'static, ) -> Subscription where T: 'static + EventEmitter<Evt>, Evt: 'static, { let this = self.entity(); self.app.subscribe(&this, move |this, evt, cx| { this.update(cx, |this, cx| on_event(this, evt, cx)) }) } /// Register a callback to be invoked when GPUI releases this entity. pub fn on_release(&self, on_release: impl FnOnce(&mut T, &mut App) + 'static) -> Subscription where T: 'static, { let (subscription, activate) = self.app.release_listeners.insert( self.entity_state.entity_id, Box::new(move |this, cx| { let this = this.downcast_mut().expect("invalid entity type"); on_release(this, cx); }), ); activate(); subscription } /// Register a callback to be run on the release of another entity pub fn observe_release<T2>( &self, entity: &Entity<T2>, on_release: impl FnOnce(&mut T, &mut T2, &mut Context<T>) + 'static, ) -> Subscription where T: Any, T2: 'static, { let entity_id = entity.entity_id(); let this = self.weak_entity(); let (subscription, activate) = self.app.release_listeners.insert( entity_id, Box::new(move |entity, cx| { let entity = entity.downcast_mut().expect("invalid entity type"); if let Some(this) = this.upgrade() { this.update(cx, |this, cx| on_release(this, entity, cx)); } }), ); activate(); subscription } /// Register a callback to for updates to the given global pub fn observe_global<G: 'static>( &mut self, mut f: impl FnMut(&mut T, &mut Context<T>) + 'static, ) -> Subscription where T: 'static, { let handle = self.weak_entity(); let (subscription, activate) = self.global_observers.insert( TypeId::of::<G>(), Box::new(move |cx| handle.update(cx, |view, cx| f(view, cx)).is_ok()), ); self.defer(move |_| activate()); subscription } /// Arrange for the given function to be invoked whenever the application is quit. /// The future returned from this callback will be polled for up to [crate::SHUTDOWN_TIMEOUT] until the app fully quits. pub fn on_app_quit<Fut>( &self, mut on_quit: impl FnMut(&mut T, &mut Context<T>) -> Fut + 'static, ) -> Subscription where Fut: 'static + Future<Output = ()>, T: 'static, { let handle = self.weak_entity(); let (subscription, activate) = self.app.quit_observers.insert( (), Box::new(move |cx| { let future = handle.update(cx, |entity, cx| on_quit(entity, cx)).ok(); async move { if let Some(future) = future { future.await; } } .boxed_local() }), ); activate(); subscription } /// Tell GPUI that this entity has changed and observers of it should be notified. pub fn notify(&mut self) { self.app.notify(self.entity_state.entity_id); } /// Spawn the future returned by the given function. /// The function is provided a weak handle to the entity owned by this context and a context that can be held across await points. /// The returned task must be held or detached. #[track_caller] pub fn spawn<AsyncFn, R>(&self, f: AsyncFn) -> Task<R> where T: 'static, AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncApp) -> R + 'static, R: 'static, { let this = self.weak_entity(); self.app.spawn(async move |cx| f(this, cx).await) } /// Convenience method for accessing view state in an event callback. /// /// Many GPUI callbacks take the form of `Fn(&E, &mut Window, &mut App)`, /// but it's often useful to be able to access view state in these /// callbacks. This method provides a convenient way to do so. pub fn listener<E: ?Sized>( &self, f: impl Fn(&mut T, &E, &mut Window, &mut Context<T>) + 'static, ) -> impl Fn(&E, &mut Window, &mut App) + 'static { let view = self.entity().downgrade(); move |e: &E, window: &mut Window, cx: &mut App| { view.update(cx, |view, cx| f(view, e, window, cx)).ok(); } } /// Run something using this entity and cx, when the returned struct is dropped pub fn on_drop( &self, f: impl FnOnce(&mut T, &mut Context<T>) + 'static, ) -> Deferred<impl FnOnce()> { let this = self.weak_entity(); let mut cx = self.to_async(); util::defer(move || { this.update(&mut cx, f).ok(); }) } /// Focus the given view in the given window. View type is required to implement Focusable. pub fn focus_view<W: Focusable>(&mut self, view: &Entity<W>, window: &mut Window) { window.focus(&view.focus_handle(self)); } /// Sets a given callback to be run on the next frame. pub fn on_next_frame( &self, window: &mut Window, f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static, ) where T: 'static, { let view = self.entity(); window.on_next_frame(move |window, cx| view.update(cx, |view, cx| f(view, window, cx))); } /// Schedules the given function to be run at the end of the current effect cycle, allowing entities /// that are currently on the stack to be returned to the app. pub fn defer_in( &mut self, window: &Window, f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static, ) { let view = self.entity(); window.defer(self, move |window, cx| { view.update(cx, |view, cx| f(view, window, cx)) }); } /// Observe another entity for changes to its state, as tracked by [`Context::notify`]. pub fn observe_in<V2>( &mut self, observed: &Entity<V2>, window: &mut Window, mut on_notify: impl FnMut(&mut T, Entity<V2>, &mut Window, &mut Context<T>) + 'static, ) -> Subscription where V2: 'static, T: 'static, { let observed_id = observed.entity_id(); let observed = observed.downgrade(); let window_handle = window.handle; let observer = self.weak_entity(); self.new_observer( observed_id, Box::new(move |cx| { window_handle .update(cx, |_, window, cx| { if let Some((observer, observed)) = observer.upgrade().zip(observed.upgrade()) { observer.update(cx, |observer, cx| { on_notify(observer, observed, window, cx); }); true } else { false } }) .unwrap_or(false) }), ) } /// Subscribe to events emitted by another entity. /// The entity to which you're subscribing must implement the [`EventEmitter`] trait. /// 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. pub fn subscribe_in<Emitter, Evt>( &mut self, emitter: &Entity<Emitter>, window: &Window, mut on_event: impl FnMut(&mut T, &Entity<Emitter>, &Evt, &mut Window, &mut Context<T>) + 'static, ) -> Subscription where Emitter: EventEmitter<Evt>, Evt: 'static, { let emitter = emitter.downgrade(); let window_handle = window.handle; let subscriber = self.weak_entity(); self.new_subscription( emitter.entity_id(), ( TypeId::of::<Evt>(), Box::new(move |event, cx| { window_handle .update(cx, |_, window, cx| { if let Some((subscriber, emitter)) = subscriber.upgrade().zip(emitter.upgrade()) { let event = event.downcast_ref().expect("invalid event type"); subscriber.update(cx, |subscriber, cx| { on_event(subscriber, &emitter, event, window, cx); }); true } else { false } }) .unwrap_or(false) }), ), ) } /// Register a callback to be invoked when the view is released. /// /// The callback receives a handle to the view's window. This handle may be /// invalid, if the window was closed before the view was released. pub fn on_release_in( &mut self, window: &Window, on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static, ) -> Subscription { let entity = self.entity(); self.app.observe_release_in(&entity, window, on_release) } /// Register a callback to be invoked when the given Entity is released. pub fn observe_release_in<T2>( &self, observed: &Entity<T2>, window: &Window, mut on_release: impl FnMut(&mut T, &mut T2, &mut Window, &mut Context<T>) + 'static, ) -> Subscription where T: 'static, T2: 'static, { let observer = self.weak_entity(); self.app .observe_release_in(observed, window, move |observed, window, cx| { observer .update(cx, |observer, cx| { on_release(observer, observed, window, cx) }) .ok(); }) } /// Register a callback to be invoked when the window is resized. pub fn observe_window_bounds( &self, window: &mut Window, mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { let view = self.weak_entity(); let (subscription, activate) = window.bounds_observers.insert( (), Box::new(move |window, cx| { view.update(cx, |view, cx| callback(view, window, cx)) .is_ok() }), ); activate(); subscription } /// Register a callback to be invoked when the window is activated or deactivated. pub fn observe_window_activation( &self, window: &mut Window, mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { let view = self.weak_entity(); let (subscription, activate) = window.activation_observers.insert( (), Box::new(move |window, cx| { view.update(cx, |view, cx| callback(view, window, cx)) .is_ok() }), ); activate(); subscription } /// Registers a callback to be invoked when the window appearance changes. pub fn observe_window_appearance( &self, window: &mut Window, mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { let view = self.weak_entity(); let (subscription, activate) = window.appearance_observers.insert( (), Box::new(move |window, cx| { view.update(cx, |view, cx| callback(view, window, cx)) .is_ok() }), ); activate(); subscription } /// Register a callback to be invoked when a keystroke is received by the application /// in any window. Note that this fires after all other action and event mechanisms have resolved /// and that this API will not be invoked if the event's propagation is stopped. pub fn observe_keystrokes( &mut self, mut f: impl FnMut(&mut T, &KeystrokeEvent, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { fn inner( keystroke_observers: &SubscriberSet<(), KeystrokeObserver>, handler: KeystrokeObserver, ) -> Subscription { let (subscription, activate) = keystroke_observers.insert((), handler); activate(); subscription } let view = self.weak_entity(); inner( &mut self.keystroke_observers, Box::new(move |event, window, cx| { if let Some(view) = view.upgrade() { view.update(cx, |view, cx| f(view, event, window, cx)); true } else { false } }), ) } /// Register a callback to be invoked when the window's pending input changes. pub fn observe_pending_input( &self, window: &mut Window, mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { let view = self.weak_entity(); let (subscription, activate) = window.pending_input_observers.insert( (), Box::new(move |window, cx| { view.update(cx, |view, cx| callback(view, window, cx)) .is_ok() }), ); activate(); subscription } /// Register a listener to be called when the given focus handle receives focus. /// Returns a subscription and persists until the subscription is dropped. pub fn on_focus( &mut self, handle: &FocusHandle, window: &mut Window, mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { let view = self.weak_entity(); let focus_id = handle.id; let (subscription, activate) = window.new_focus_listener(Box::new(move |event, window, cx| { view.update(cx, |view, cx| { if event.previous_focus_path.last() != Some(&focus_id) && event.current_focus_path.last() == Some(&focus_id) { listener(view, window, cx)Lines 1–500 of 771. Load more
use crate::{ AnyView, AnyWindowHandle, AppContext, AsyncApp, DispatchPhase, Effect, EntityId, EventEmitter, FocusHandle, FocusOutEvent, Focusable, Global, KeystrokeObserver, Reservation, SubscriberSet, Subscription, Task, WeakEntity, WeakFocusHandle, Window, WindowHandle, }; use anyhow::Result; use derive_more::{Deref, DerefMut}; use futures::FutureExt; use std::{ any::{Any, TypeId}, borrow::{Borrow, BorrowMut}, future::Future, sync::Arc, }; use util::Deferred; use super::{App, AsyncWindowContext, Entity, KeystrokeEvent}; /// The app context, with specialized behavior for the given entity. #[derive(Deref, DerefMut)] pub struct Context<'a, T> { #[deref] #[deref_mut] app: &'a mut App, entity_state: WeakEntity<T>, } impl<'a, T: 'static> Context<'a, T> { pub(crate) fn new_context(app: &'a mut App, entity_state: WeakEntity<T>) -> Self { Self { app, entity_state } } /// The entity id of the entity backing this context. pub fn entity_id(&self) -> EntityId { self.entity_state.entity_id } /// Returns a handle to the entity belonging to this context. pub fn entity(&self) -> Entity<T> { self.weak_entity() .upgrade() .expect("The entity must be alive if we have a entity context") } /// Returns a weak handle to the entity belonging to this context. pub fn weak_entity(&self) -> WeakEntity<T> { self.entity_state.clone() } /// Arranges for the given function to be called whenever [`Context::notify`] is /// called with the given entity. pub fn observe<W>( &mut self, entity: &Entity<W>, mut on_notify: impl FnMut(&mut T, Entity<W>, &mut Context<T>) + 'static, ) -> Subscription where T: 'static, W: 'static, { let this = self.weak_entity(); self.app.observe_internal(entity, move |e, cx| { if let Some(this) = this.upgrade() { this.update(cx, |this, cx| on_notify(this, e, cx)); true } else { false } }) } /// Subscribe to an event type from another entity pub fn subscribe<T2, Evt>( &mut self, entity: &Entity<T2>, mut on_event: impl FnMut(&mut T, Entity<T2>, &Evt, &mut Context<T>) + 'static, ) -> Subscription where T: 'static, T2: 'static + EventEmitter<Evt>, Evt: 'static, { let this = self.weak_entity(); self.app.subscribe_internal(entity, move |e, event, cx| { if let Some(this) = this.upgrade() { this.update(cx, |this, cx| on_event(this, e, event, cx)); true } else { false } }) } /// Subscribe to an event type from ourself pub fn subscribe_self<Evt>( &mut self, mut on_event: impl FnMut(&mut T, &Evt, &mut Context<T>) + 'static, ) -> Subscription where T: 'static + EventEmitter<Evt>, Evt: 'static, { let this = self.entity(); self.app.subscribe(&this, move |this, evt, cx| { this.update(cx, |this, cx| on_event(this, evt, cx)) }) } /// Register a callback to be invoked when GPUI releases this entity. pub fn on_release(&self, on_release: impl FnOnce(&mut T, &mut App) + 'static) -> Subscription where T: 'static, { let (subscription, activate) = self.app.release_listeners.insert( self.entity_state.entity_id, Box::new(move |this, cx| { let this = this.downcast_mut().expect("invalid entity type"); on_release(this, cx); }), ); activate(); subscription } /// Register a callback to be run on the release of another entity pub fn observe_release<T2>( &self, entity: &Entity<T2>, on_release: impl FnOnce(&mut T, &mut T2, &mut Context<T>) + 'static, ) -> Subscription where T: Any, T2: 'static, { let entity_id = entity.entity_id(); let this = self.weak_entity(); let (subscription, activate) = self.app.release_listeners.insert( entity_id, Box::new(move |entity, cx| { let entity = entity.downcast_mut().expect("invalid entity type"); if let Some(this) = this.upgrade() { this.update(cx, |this, cx| on_release(this, entity, cx)); } }), ); activate(); subscription } /// Register a callback to for updates to the given global pub fn observe_global<G: 'static>( &mut self, mut f: impl FnMut(&mut T, &mut Context<T>) + 'static, ) -> Subscription where T: 'static, { let handle = self.weak_entity(); let (subscription, activate) = self.global_observers.insert( TypeId::of::<G>(), Box::new(move |cx| handle.update(cx, |view, cx| f(view, cx)).is_ok()), ); self.defer(move |_| activate()); subscription } /// Arrange for the given function to be invoked whenever the application is quit. /// The future returned from this callback will be polled for up to [crate::SHUTDOWN_TIMEOUT] until the app fully quits. pub fn on_app_quit<Fut>( &self, mut on_quit: impl FnMut(&mut T, &mut Context<T>) -> Fut + 'static, ) -> Subscription where Fut: 'static + Future<Output = ()>, T: 'static, { let handle = self.weak_entity(); let (subscription, activate) = self.app.quit_observers.insert( (), Box::new(move |cx| { let future = handle.update(cx, |entity, cx| on_quit(entity, cx)).ok(); async move { if let Some(future) = future { future.await; } } .boxed_local() }), ); activate(); subscription } /// Tell GPUI that this entity has changed and observers of it should be notified. pub fn notify(&mut self) { self.app.notify(self.entity_state.entity_id); } /// Spawn the future returned by the given function. /// The function is provided a weak handle to the entity owned by this context and a context that can be held across await points. /// The returned task must be held or detached. #[track_caller] pub fn spawn<AsyncFn, R>(&self, f: AsyncFn) -> Task<R> where T: 'static, AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncApp) -> R + 'static, R: 'static, { let this = self.weak_entity(); self.app.spawn(async move |cx| f(this, cx).await) } /// Convenience method for accessing view state in an event callback. /// /// Many GPUI callbacks take the form of `Fn(&E, &mut Window, &mut App)`, /// but it's often useful to be able to access view state in these /// callbacks. This method provides a convenient way to do so. pub fn listener<E: ?Sized>( &self, f: impl Fn(&mut T, &E, &mut Window, &mut Context<T>) + 'static, ) -> impl Fn(&E, &mut Window, &mut App) + 'static { let view = self.entity().downgrade(); move |e: &E, window: &mut Window, cx: &mut App| { view.update(cx, |view, cx| f(view, e, window, cx)).ok(); } } /// Run something using this entity and cx, when the returned struct is dropped pub fn on_drop( &self, f: impl FnOnce(&mut T, &mut Context<T>) + 'static, ) -> Deferred<impl FnOnce()> { let this = self.weak_entity(); let mut cx = self.to_async(); util::defer(move || { this.update(&mut cx, f).ok(); }) } /// Focus the given view in the given window. View type is required to implement Focusable. pub fn focus_view<W: Focusable>(&mut self, view: &Entity<W>, window: &mut Window) { window.focus(&view.focus_handle(self)); } /// Sets a given callback to be run on the next frame. pub fn on_next_frame( &self, window: &mut Window, f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static, ) where T: 'static, { let view = self.entity(); window.on_next_frame(move |window, cx| view.update(cx, |view, cx| f(view, window, cx))); } /// Schedules the given function to be run at the end of the current effect cycle, allowing entities /// that are currently on the stack to be returned to the app. pub fn defer_in( &mut self, window: &Window, f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static, ) { let view = self.entity(); window.defer(self, move |window, cx| { view.update(cx, |view, cx| f(view, window, cx)) }); } /// Observe another entity for changes to its state, as tracked by [`Context::notify`]. pub fn observe_in<V2>( &mut self, observed: &Entity<V2>, window: &mut Window, mut on_notify: impl FnMut(&mut T, Entity<V2>, &mut Window, &mut Context<T>) + 'static, ) -> Subscription where V2: 'static, T: 'static, { let observed_id = observed.entity_id(); let observed = observed.downgrade(); let window_handle = window.handle; let observer = self.weak_entity(); self.new_observer( observed_id, Box::new(move |cx| { window_handle .update(cx, |_, window, cx| { if let Some((observer, observed)) = observer.upgrade().zip(observed.upgrade()) { observer.update(cx, |observer, cx| { on_notify(observer, observed, window, cx); }); true } else { false } }) .unwrap_or(false) }), ) } /// Subscribe to events emitted by another entity. /// The entity to which you're subscribing must implement the [`EventEmitter`] trait. /// 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. pub fn subscribe_in<Emitter, Evt>( &mut self, emitter: &Entity<Emitter>, window: &Window, mut on_event: impl FnMut(&mut T, &Entity<Emitter>, &Evt, &mut Window, &mut Context<T>) + 'static, ) -> Subscription where Emitter: EventEmitter<Evt>, Evt: 'static, { let emitter = emitter.downgrade(); let window_handle = window.handle; let subscriber = self.weak_entity(); self.new_subscription( emitter.entity_id(), ( TypeId::of::<Evt>(), Box::new(move |event, cx| { window_handle .update(cx, |_, window, cx| { if let Some((subscriber, emitter)) = subscriber.upgrade().zip(emitter.upgrade()) { let event = event.downcast_ref().expect("invalid event type"); subscriber.update(cx, |subscriber, cx| { on_event(subscriber, &emitter, event, window, cx); }); true } else { false } }) .unwrap_or(false) }), ), ) } /// Register a callback to be invoked when the view is released. /// /// The callback receives a handle to the view's window. This handle may be /// invalid, if the window was closed before the view was released. pub fn on_release_in( &mut self, window: &Window, on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static, ) -> Subscription { let entity = self.entity(); self.app.observe_release_in(&entity, window, on_release) } /// Register a callback to be invoked when the given Entity is released. pub fn observe_release_in<T2>( &self, observed: &Entity<T2>, window: &Window, mut on_release: impl FnMut(&mut T, &mut T2, &mut Window, &mut Context<T>) + 'static, ) -> Subscription where T: 'static, T2: 'static, { let observer = self.weak_entity(); self.app .observe_release_in(observed, window, move |observed, window, cx| { observer .update(cx, |observer, cx| { on_release(observer, observed, window, cx) }) .ok(); }) } /// Register a callback to be invoked when the window is resized. pub fn observe_window_bounds( &self, window: &mut Window, mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { let view = self.weak_entity(); let (subscription, activate) = window.bounds_observers.insert( (), Box::new(move |window, cx| { view.update(cx, |view, cx| callback(view, window, cx)) .is_ok() }), ); activate(); subscription } /// Register a callback to be invoked when the window is activated or deactivated. pub fn observe_window_activation( &self, window: &mut Window, mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { let view = self.weak_entity(); let (subscription, activate) = window.activation_observers.insert( (), Box::new(move |window, cx| { view.update(cx, |view, cx| callback(view, window, cx)) .is_ok() }), ); activate(); subscription } /// Registers a callback to be invoked when the window appearance changes. pub fn observe_window_appearance( &self, window: &mut Window, mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { let view = self.weak_entity(); let (subscription, activate) = window.appearance_observers.insert( (), Box::new(move |window, cx| { view.update(cx, |view, cx| callback(view, window, cx)) .is_ok() }), ); activate(); subscription } /// Register a callback to be invoked when a keystroke is received by the application /// in any window. Note that this fires after all other action and event mechanisms have resolved /// and that this API will not be invoked if the event's propagation is stopped. pub fn observe_keystrokes( &mut self, mut f: impl FnMut(&mut T, &KeystrokeEvent, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { fn inner( keystroke_observers: &SubscriberSet<(), KeystrokeObserver>, handler: KeystrokeObserver, ) -> Subscription { let (subscription, activate) = keystroke_observers.insert((), handler); activate(); subscription } let view = self.weak_entity(); inner( &mut self.keystroke_observers, Box::new(move |event, window, cx| { if let Some(view) = view.upgrade() { view.update(cx, |view, cx| f(view, event, window, cx)); true } else { false } }), ) } /// Register a callback to be invoked when the window's pending input changes. pub fn observe_pending_input( &self, window: &mut Window, mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { let view = self.weak_entity(); let (subscription, activate) = window.pending_input_observers.insert( (), Box::new(move |window, cx| { view.update(cx, |view, cx| callback(view, window, cx)) .is_ok() }), ); activate(); subscription } /// Register a listener to be called when the given focus handle receives focus. /// Returns a subscription and persists until the subscription is dropped. pub fn on_focus( &mut self, handle: &FocusHandle, window: &mut Window, mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static, ) -> Subscription { let view = self.weak_entity(); let focus_id = handle.id; let (subscription, activate) = window.new_focus_listener(Box::new(move |event, window, cx| { view.update(cx, |view, cx| { if event.previous_focus_path.last() != Some(&focus_id) && event.current_focus_path.last() == Some(&focus_id) { listener(view, window, cx)