app.rs

   1#![deny(missing_docs)]
   2
   3mod async_context;
   4mod entity_map;
   5mod model_context;
   6#[cfg(any(test, feature = "test-support"))]
   7mod test_context;
   8
   9pub use async_context::*;
  10use derive_more::{Deref, DerefMut};
  11pub use entity_map::*;
  12pub use model_context::*;
  13use refineable::Refineable;
  14use smol::future::FutureExt;
  15#[cfg(any(test, feature = "test-support"))]
  16pub use test_context::*;
  17use time::UtcOffset;
  18
  19use crate::{
  20    current_platform, image_cache::ImageCache, init_app_menus, Action, ActionRegistry, Any,
  21    AnyView, AnyWindowHandle, AppMetadata, AssetSource, BackgroundExecutor, ClipboardItem, Context,
  22    DispatchPhase, DisplayId, Entity, EventEmitter, ForegroundExecutor, KeyBinding, Keymap,
  23    Keystroke, LayoutId, Menu, PathPromptOptions, Pixels, Platform, PlatformDisplay, Point, Render,
  24    SharedString, SubscriberSet, Subscription, SvgRenderer, Task, TextStyle, TextStyleRefinement,
  25    TextSystem, View, ViewContext, Window, WindowContext, WindowHandle, WindowId,
  26};
  27use anyhow::{anyhow, Result};
  28use collections::{FxHashMap, FxHashSet, VecDeque};
  29use futures::{channel::oneshot, future::LocalBoxFuture, Future};
  30use parking_lot::Mutex;
  31use slotmap::SlotMap;
  32use std::{
  33    any::{type_name, TypeId},
  34    cell::{Ref, RefCell, RefMut},
  35    marker::PhantomData,
  36    mem,
  37    ops::{Deref, DerefMut},
  38    path::{Path, PathBuf},
  39    rc::{Rc, Weak},
  40    sync::{atomic::Ordering::SeqCst, Arc},
  41    time::Duration,
  42};
  43use util::{
  44    http::{self, HttpClient},
  45    ResultExt,
  46};
  47
  48/// The duration for which futures returned from [AppContext::on_app_context] or [ModelContext::on_app_quit] can run before the application fully quits.
  49pub const SHUTDOWN_TIMEOUT: Duration = Duration::from_millis(100);
  50
  51/// Temporary(?) wrapper around [`RefCell<AppContext>`] to help us debug any double borrows.
  52/// Strongly consider removing after stabilization.
  53#[doc(hidden)]
  54pub struct AppCell {
  55    app: RefCell<AppContext>,
  56}
  57
  58impl AppCell {
  59    #[doc(hidden)]
  60    #[track_caller]
  61    pub fn borrow(&self) -> AppRef {
  62        if option_env!("TRACK_THREAD_BORROWS").is_some() {
  63            let thread_id = std::thread::current().id();
  64            eprintln!("borrowed {thread_id:?}");
  65        }
  66        AppRef(self.app.borrow())
  67    }
  68
  69    #[doc(hidden)]
  70    #[track_caller]
  71    pub fn borrow_mut(&self) -> AppRefMut {
  72        if option_env!("TRACK_THREAD_BORROWS").is_some() {
  73            let thread_id = std::thread::current().id();
  74            eprintln!("borrowed {thread_id:?}");
  75        }
  76        AppRefMut(self.app.borrow_mut())
  77    }
  78}
  79
  80#[doc(hidden)]
  81#[derive(Deref, DerefMut)]
  82pub struct AppRef<'a>(Ref<'a, AppContext>);
  83
  84impl<'a> Drop for AppRef<'a> {
  85    fn drop(&mut self) {
  86        if option_env!("TRACK_THREAD_BORROWS").is_some() {
  87            let thread_id = std::thread::current().id();
  88            eprintln!("dropped borrow from {thread_id:?}");
  89        }
  90    }
  91}
  92
  93#[doc(hidden)]
  94#[derive(Deref, DerefMut)]
  95pub struct AppRefMut<'a>(RefMut<'a, AppContext>);
  96
  97impl<'a> Drop for AppRefMut<'a> {
  98    fn drop(&mut self) {
  99        if option_env!("TRACK_THREAD_BORROWS").is_some() {
 100            let thread_id = std::thread::current().id();
 101            eprintln!("dropped {thread_id:?}");
 102        }
 103    }
 104}
 105
 106/// A reference to a GPUI application, typically constructed in the `main` function of your app.
 107/// You won't interact with this type much outside of initial configuration and startup.
 108pub struct App(Rc<AppCell>);
 109
 110/// Represents an application before it is fully launched. Once your app is
 111/// configured, you'll start the app with `App::run`.
 112impl App {
 113    /// Builds an app with the given asset source.
 114    pub fn production(asset_source: Arc<dyn AssetSource>) -> Self {
 115        Self(AppContext::new(
 116            current_platform(),
 117            asset_source,
 118            http::client(),
 119        ))
 120    }
 121
 122    /// Start the application. The provided callback will be called once the
 123    /// app is fully launched.
 124    pub fn run<F>(self, on_finish_launching: F)
 125    where
 126        F: 'static + FnOnce(&mut AppContext),
 127    {
 128        let this = self.0.clone();
 129        let platform = self.0.borrow().platform.clone();
 130        platform.run(Box::new(move || {
 131            let cx = &mut *this.borrow_mut();
 132            on_finish_launching(cx);
 133        }));
 134    }
 135
 136    /// Register a handler to be invoked when the platform instructs the application
 137    /// to open one or more URLs.
 138    pub fn on_open_urls<F>(&self, mut callback: F) -> &Self
 139    where
 140        F: 'static + FnMut(Vec<String>, &mut AppContext),
 141    {
 142        let this = Rc::downgrade(&self.0);
 143        self.0.borrow().platform.on_open_urls(Box::new(move |urls| {
 144            if let Some(app) = this.upgrade() {
 145                callback(urls, &mut app.borrow_mut());
 146            }
 147        }));
 148        self
 149    }
 150
 151    /// Invokes a handler when an already-running application is launched.
 152    /// On macOS, this can occur when the application icon is double-clicked or the app is launched via the dock.
 153    pub fn on_reopen<F>(&self, mut callback: F) -> &Self
 154    where
 155        F: 'static + FnMut(&mut AppContext),
 156    {
 157        let this = Rc::downgrade(&self.0);
 158        self.0.borrow_mut().platform.on_reopen(Box::new(move || {
 159            if let Some(app) = this.upgrade() {
 160                callback(&mut app.borrow_mut());
 161            }
 162        }));
 163        self
 164    }
 165
 166    /// Returns metadata associated with the application
 167    pub fn metadata(&self) -> AppMetadata {
 168        self.0.borrow().app_metadata.clone()
 169    }
 170
 171    /// Returns a handle to the [`BackgroundExecutor`] associated with this app, which can be used to spawn futures in the background.
 172    pub fn background_executor(&self) -> BackgroundExecutor {
 173        self.0.borrow().background_executor.clone()
 174    }
 175
 176    /// Returns a handle to the [`ForegroundExecutor`] associated with this app, which can be used to spawn futures in the foreground.
 177    pub fn foreground_executor(&self) -> ForegroundExecutor {
 178        self.0.borrow().foreground_executor.clone()
 179    }
 180
 181    /// Returns a reference to the [`TextSystem`] associated with this app.
 182    pub fn text_system(&self) -> Arc<TextSystem> {
 183        self.0.borrow().text_system.clone()
 184    }
 185}
 186
 187pub(crate) type FrameCallback = Box<dyn FnOnce(&mut AppContext)>;
 188type Handler = Box<dyn FnMut(&mut AppContext) -> bool + 'static>;
 189type Listener = Box<dyn FnMut(&dyn Any, &mut AppContext) -> bool + 'static>;
 190type KeystrokeObserver = Box<dyn FnMut(&KeystrokeEvent, &mut WindowContext) + 'static>;
 191type QuitHandler = Box<dyn FnOnce(&mut AppContext) -> LocalBoxFuture<'static, ()> + 'static>;
 192type ReleaseListener = Box<dyn FnOnce(&mut dyn Any, &mut AppContext) + 'static>;
 193type NewViewListener = Box<dyn FnMut(AnyView, &mut WindowContext) + 'static>;
 194
 195/// Contains the state of the full application, and passed as a reference to a variety of callbacks.
 196/// Other contexts such as [ModelContext], [WindowContext], and [ViewContext] deref to this type, making it the most general context type.
 197/// You need a reference to an `AppContext` to access the state of a [Model].
 198pub struct AppContext {
 199    pub(crate) this: Weak<AppCell>,
 200    pub(crate) platform: Rc<dyn Platform>,
 201    app_metadata: AppMetadata,
 202    text_system: Arc<TextSystem>,
 203    flushing_effects: bool,
 204    pending_updates: usize,
 205    pub(crate) actions: Rc<ActionRegistry>,
 206    pub(crate) active_drag: Option<AnyDrag>,
 207    pub(crate) next_frame_callbacks: FxHashMap<DisplayId, Vec<FrameCallback>>,
 208    pub(crate) frame_consumers: FxHashMap<DisplayId, Task<()>>,
 209    pub(crate) background_executor: BackgroundExecutor,
 210    pub(crate) foreground_executor: ForegroundExecutor,
 211    pub(crate) svg_renderer: SvgRenderer,
 212    asset_source: Arc<dyn AssetSource>,
 213    pub(crate) image_cache: ImageCache,
 214    pub(crate) text_style_stack: Vec<TextStyleRefinement>,
 215    pub(crate) globals_by_type: FxHashMap<TypeId, Box<dyn Any>>,
 216    pub(crate) entities: EntityMap,
 217    pub(crate) new_view_observers: SubscriberSet<TypeId, NewViewListener>,
 218    pub(crate) windows: SlotMap<WindowId, Option<Window>>,
 219    pub(crate) keymap: Arc<Mutex<Keymap>>,
 220    pub(crate) global_action_listeners:
 221        FxHashMap<TypeId, Vec<Rc<dyn Fn(&dyn Any, DispatchPhase, &mut Self)>>>,
 222    pending_effects: VecDeque<Effect>,
 223    pub(crate) pending_notifications: FxHashSet<EntityId>,
 224    pub(crate) pending_global_notifications: FxHashSet<TypeId>,
 225    pub(crate) observers: SubscriberSet<EntityId, Handler>,
 226    // TypeId is the type of the event that the listener callback expects
 227    pub(crate) event_listeners: SubscriberSet<EntityId, (TypeId, Listener)>,
 228    pub(crate) keystroke_observers: SubscriberSet<(), KeystrokeObserver>,
 229    pub(crate) release_listeners: SubscriberSet<EntityId, ReleaseListener>,
 230    pub(crate) global_observers: SubscriberSet<TypeId, Handler>,
 231    pub(crate) quit_observers: SubscriberSet<(), QuitHandler>,
 232    pub(crate) layout_id_buffer: Vec<LayoutId>, // We recycle this memory across layout requests.
 233    pub(crate) propagate_event: bool,
 234}
 235
 236impl AppContext {
 237    pub(crate) fn new(
 238        platform: Rc<dyn Platform>,
 239        asset_source: Arc<dyn AssetSource>,
 240        http_client: Arc<dyn HttpClient>,
 241    ) -> Rc<AppCell> {
 242        let executor = platform.background_executor();
 243        let foreground_executor = platform.foreground_executor();
 244        assert!(
 245            executor.is_main_thread(),
 246            "must construct App on main thread"
 247        );
 248
 249        let text_system = Arc::new(TextSystem::new(platform.text_system()));
 250        let entities = EntityMap::new();
 251
 252        let app_metadata = AppMetadata {
 253            os_name: platform.os_name(),
 254            os_version: platform.os_version().ok(),
 255            app_version: platform.app_version().ok(),
 256        };
 257
 258        let app = Rc::new_cyclic(|this| AppCell {
 259            app: RefCell::new(AppContext {
 260                this: this.clone(),
 261                platform: platform.clone(),
 262                app_metadata,
 263                text_system,
 264                actions: Rc::new(ActionRegistry::default()),
 265                flushing_effects: false,
 266                pending_updates: 0,
 267                active_drag: None,
 268                next_frame_callbacks: FxHashMap::default(),
 269                frame_consumers: FxHashMap::default(),
 270                background_executor: executor,
 271                foreground_executor,
 272                svg_renderer: SvgRenderer::new(asset_source.clone()),
 273                asset_source,
 274                image_cache: ImageCache::new(http_client),
 275                text_style_stack: Vec::new(),
 276                globals_by_type: FxHashMap::default(),
 277                entities,
 278                new_view_observers: SubscriberSet::new(),
 279                windows: SlotMap::with_key(),
 280                keymap: Arc::new(Mutex::new(Keymap::default())),
 281                global_action_listeners: FxHashMap::default(),
 282                pending_effects: VecDeque::new(),
 283                pending_notifications: FxHashSet::default(),
 284                pending_global_notifications: FxHashSet::default(),
 285                observers: SubscriberSet::new(),
 286                event_listeners: SubscriberSet::new(),
 287                release_listeners: SubscriberSet::new(),
 288                keystroke_observers: SubscriberSet::new(),
 289                global_observers: SubscriberSet::new(),
 290                quit_observers: SubscriberSet::new(),
 291                layout_id_buffer: Default::default(),
 292                propagate_event: true,
 293            }),
 294        });
 295
 296        init_app_menus(platform.as_ref(), &mut app.borrow_mut());
 297
 298        platform.on_quit(Box::new({
 299            let cx = app.clone();
 300            move || {
 301                cx.borrow_mut().shutdown();
 302            }
 303        }));
 304
 305        app
 306    }
 307
 308    /// Quit the application gracefully. Handlers registered with [`ModelContext::on_app_quit`]
 309    /// will be given 100ms to complete before exiting.
 310    pub fn shutdown(&mut self) {
 311        let mut futures = Vec::new();
 312
 313        for observer in self.quit_observers.remove(&()) {
 314            futures.push(observer(self));
 315        }
 316
 317        self.windows.clear();
 318        self.flush_effects();
 319
 320        let futures = futures::future::join_all(futures);
 321        if self
 322            .background_executor
 323            .block_with_timeout(SHUTDOWN_TIMEOUT, futures)
 324            .is_err()
 325        {
 326            log::error!("timed out waiting on app_will_quit");
 327        }
 328    }
 329
 330    /// Gracefully quit the application via the platform's standard routine.
 331    pub fn quit(&mut self) {
 332        self.platform.quit();
 333    }
 334
 335    /// Get metadata about the app and platform.
 336    pub fn app_metadata(&self) -> AppMetadata {
 337        self.app_metadata.clone()
 338    }
 339
 340    /// Schedules all windows in the application to be redrawn. This can be called
 341    /// multiple times in an update cycle and still result in a single redraw.
 342    pub fn refresh(&mut self) {
 343        self.pending_effects.push_back(Effect::Refresh);
 344    }
 345
 346    pub(crate) fn update<R>(&mut self, update: impl FnOnce(&mut Self) -> R) -> R {
 347        self.pending_updates += 1;
 348        let result = update(self);
 349        if !self.flushing_effects && self.pending_updates == 1 {
 350            self.flushing_effects = true;
 351            self.flush_effects();
 352            self.flushing_effects = false;
 353        }
 354        self.pending_updates -= 1;
 355        result
 356    }
 357
 358    /// Arrange a callback to be invoked when the given model or view calls `notify` on its respective context.
 359    pub fn observe<W, E>(
 360        &mut self,
 361        entity: &E,
 362        mut on_notify: impl FnMut(E, &mut AppContext) + 'static,
 363    ) -> Subscription
 364    where
 365        W: 'static,
 366        E: Entity<W>,
 367    {
 368        self.observe_internal(entity, move |e, cx| {
 369            on_notify(e, cx);
 370            true
 371        })
 372    }
 373
 374    pub(crate) fn observe_internal<W, E>(
 375        &mut self,
 376        entity: &E,
 377        mut on_notify: impl FnMut(E, &mut AppContext) -> bool + 'static,
 378    ) -> Subscription
 379    where
 380        W: 'static,
 381        E: Entity<W>,
 382    {
 383        let entity_id = entity.entity_id();
 384        let handle = entity.downgrade();
 385        let (subscription, activate) = self.observers.insert(
 386            entity_id,
 387            Box::new(move |cx| {
 388                if let Some(handle) = E::upgrade_from(&handle) {
 389                    on_notify(handle, cx)
 390                } else {
 391                    false
 392                }
 393            }),
 394        );
 395        self.defer(move |_| activate());
 396        subscription
 397    }
 398
 399    /// Arrange for the given callback to be invoked whenever the given model or view emits an event of a given type.
 400    /// The callback is provided a handle to the emitting entity and a reference to the emitted event.
 401    pub fn subscribe<T, E, Event>(
 402        &mut self,
 403        entity: &E,
 404        mut on_event: impl FnMut(E, &Event, &mut AppContext) + 'static,
 405    ) -> Subscription
 406    where
 407        T: 'static + EventEmitter<Event>,
 408        E: Entity<T>,
 409        Event: 'static,
 410    {
 411        self.subscribe_internal(entity, move |entity, event, cx| {
 412            on_event(entity, event, cx);
 413            true
 414        })
 415    }
 416
 417    pub(crate) fn subscribe_internal<T, E, Evt>(
 418        &mut self,
 419        entity: &E,
 420        mut on_event: impl FnMut(E, &Evt, &mut AppContext) -> bool + 'static,
 421    ) -> Subscription
 422    where
 423        T: 'static + EventEmitter<Evt>,
 424        E: Entity<T>,
 425        Evt: 'static,
 426    {
 427        let entity_id = entity.entity_id();
 428        let entity = entity.downgrade();
 429        let (subscription, activate) = self.event_listeners.insert(
 430            entity_id,
 431            (
 432                TypeId::of::<Evt>(),
 433                Box::new(move |event, cx| {
 434                    let event: &Evt = event.downcast_ref().expect("invalid event type");
 435                    if let Some(handle) = E::upgrade_from(&entity) {
 436                        on_event(handle, event, cx)
 437                    } else {
 438                        false
 439                    }
 440                }),
 441            ),
 442        );
 443        self.defer(move |_| activate());
 444        subscription
 445    }
 446
 447    /// Returns handles to all open windows in the application.
 448    /// Each handle could be downcast to a handle typed for the root view of that window.
 449    /// To find all windows of a given type, you could filter on
 450    pub fn windows(&self) -> Vec<AnyWindowHandle> {
 451        self.windows
 452            .values()
 453            .filter_map(|window| Some(window.as_ref()?.handle))
 454            .collect()
 455    }
 456
 457    /// Returns a handle to the window that is currently focused at the platform level, if one exists.
 458    pub fn active_window(&self) -> Option<AnyWindowHandle> {
 459        self.platform.active_window()
 460    }
 461
 462    /// Opens a new window with the given option and the root view returned by the given function.
 463    /// The function is invoked with a `WindowContext`, which can be used to interact with window-specific
 464    /// functionality.
 465    pub fn open_window<V: 'static + Render>(
 466        &mut self,
 467        options: crate::WindowOptions,
 468        build_root_view: impl FnOnce(&mut WindowContext) -> View<V>,
 469    ) -> WindowHandle<V> {
 470        self.update(|cx| {
 471            let id = cx.windows.insert(None);
 472            let handle = WindowHandle::new(id);
 473            let mut window = Window::new(handle.into(), options, cx);
 474            let root_view = build_root_view(&mut WindowContext::new(cx, &mut window));
 475            window.root_view.replace(root_view.into());
 476            cx.windows.get_mut(id).unwrap().replace(window);
 477            handle
 478        })
 479    }
 480
 481    /// Instructs the platform to activate the application by bringing it to the foreground.
 482    pub fn activate(&self, ignoring_other_apps: bool) {
 483        self.platform.activate(ignoring_other_apps);
 484    }
 485
 486    /// Hide the application at the platform level.
 487    pub fn hide(&self) {
 488        self.platform.hide();
 489    }
 490
 491    /// Hide other applications at the platform level.
 492    pub fn hide_other_apps(&self) {
 493        self.platform.hide_other_apps();
 494    }
 495
 496    /// Unhide other applications at the platform level.
 497    pub fn unhide_other_apps(&self) {
 498        self.platform.unhide_other_apps();
 499    }
 500
 501    /// Returns the list of currently active displays.
 502    pub fn displays(&self) -> Vec<Rc<dyn PlatformDisplay>> {
 503        self.platform.displays()
 504    }
 505
 506    /// Writes data to the platform clipboard.
 507    pub fn write_to_clipboard(&self, item: ClipboardItem) {
 508        self.platform.write_to_clipboard(item)
 509    }
 510
 511    /// Reads data from the platform clipboard.
 512    pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
 513        self.platform.read_from_clipboard()
 514    }
 515
 516    /// Writes credentials to the platform keychain.
 517    pub fn write_credentials(&self, url: &str, username: &str, password: &[u8]) -> Result<()> {
 518        self.platform.write_credentials(url, username, password)
 519    }
 520
 521    /// Reads credentials from the platform keychain.
 522    pub fn read_credentials(&self, url: &str) -> Result<Option<(String, Vec<u8>)>> {
 523        self.platform.read_credentials(url)
 524    }
 525
 526    /// Deletes credentials from the platform keychain.
 527    pub fn delete_credentials(&self, url: &str) -> Result<()> {
 528        self.platform.delete_credentials(url)
 529    }
 530
 531    /// Directs the platform's default browser to open the given URL.
 532    pub fn open_url(&self, url: &str) {
 533        self.platform.open_url(url);
 534    }
 535
 536    /// Returns the full pathname of the current app bundle.
 537    /// If the app is not being run from a bundle, returns an error.
 538    pub fn app_path(&self) -> Result<PathBuf> {
 539        self.platform.app_path()
 540    }
 541
 542    /// Returns the file URL of the executable with the specified name in the application bundle
 543    pub fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
 544        self.platform.path_for_auxiliary_executable(name)
 545    }
 546
 547    /// Returns the maximum duration in which a second mouse click must occur for an event to be a double-click event.
 548    pub fn double_click_interval(&self) -> Duration {
 549        self.platform.double_click_interval()
 550    }
 551
 552    /// Displays a platform modal for selecting paths.
 553    /// When one or more paths are selected, they'll be relayed asynchronously via the returned oneshot channel.
 554    /// If cancelled, a `None` will be relayed instead.
 555    pub fn prompt_for_paths(
 556        &self,
 557        options: PathPromptOptions,
 558    ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
 559        self.platform.prompt_for_paths(options)
 560    }
 561
 562    /// Displays a platform modal for selecting a new path where a file can be saved.
 563    /// The provided directory will be used to set the iniital location.
 564    /// When a path is selected, it is relayed asynchronously via the returned oneshot channel.
 565    /// If cancelled, a `None` will be relayed instead.
 566    pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
 567        self.platform.prompt_for_new_path(directory)
 568    }
 569
 570    /// Reveals the specified path at the platform level, such as in Finder on macOS.
 571    pub fn reveal_path(&self, path: &Path) {
 572        self.platform.reveal_path(path)
 573    }
 574
 575    /// Returns whether the user has configured scrollbars to auto-hide at the platform level.
 576    pub fn should_auto_hide_scrollbars(&self) -> bool {
 577        self.platform.should_auto_hide_scrollbars()
 578    }
 579
 580    /// Restart the application.
 581    pub fn restart(&self) {
 582        self.platform.restart()
 583    }
 584
 585    /// Returns the local timezone at the platform level.
 586    pub fn local_timezone(&self) -> UtcOffset {
 587        self.platform.local_timezone()
 588    }
 589
 590    pub(crate) fn push_effect(&mut self, effect: Effect) {
 591        match &effect {
 592            Effect::Notify { emitter } => {
 593                if !self.pending_notifications.insert(*emitter) {
 594                    return;
 595                }
 596            }
 597            Effect::NotifyGlobalObservers { global_type } => {
 598                if !self.pending_global_notifications.insert(*global_type) {
 599                    return;
 600                }
 601            }
 602            _ => {}
 603        };
 604
 605        self.pending_effects.push_back(effect);
 606    }
 607
 608    /// Called at the end of [`AppContext::update`] to complete any side effects
 609    /// such as notifying observers, emitting events, etc. Effects can themselves
 610    /// cause effects, so we continue looping until all effects are processed.
 611    fn flush_effects(&mut self) {
 612        loop {
 613            self.release_dropped_entities();
 614            self.release_dropped_focus_handles();
 615
 616            if let Some(effect) = self.pending_effects.pop_front() {
 617                match effect {
 618                    Effect::Notify { emitter } => {
 619                        self.apply_notify_effect(emitter);
 620                    }
 621
 622                    Effect::Emit {
 623                        emitter,
 624                        event_type,
 625                        event,
 626                    } => self.apply_emit_effect(emitter, event_type, event),
 627
 628                    Effect::Refresh => {
 629                        self.apply_refresh_effect();
 630                    }
 631
 632                    Effect::NotifyGlobalObservers { global_type } => {
 633                        self.apply_notify_global_observers_effect(global_type);
 634                    }
 635
 636                    Effect::Defer { callback } => {
 637                        self.apply_defer_effect(callback);
 638                    }
 639                }
 640            } else {
 641                for window in self.windows.values() {
 642                    if let Some(window) = window.as_ref() {
 643                        if window.dirty {
 644                            window.platform_window.invalidate();
 645                        }
 646                    }
 647                }
 648
 649                #[cfg(any(test, feature = "test-support"))]
 650                for window in self
 651                    .windows
 652                    .values()
 653                    .filter_map(|window| {
 654                        let window = window.as_ref()?;
 655                        (window.dirty || window.focus_invalidated).then_some(window.handle)
 656                    })
 657                    .collect::<Vec<_>>()
 658                {
 659                    self.update_window(window, |_, cx| cx.draw()).unwrap();
 660                }
 661
 662                if self.pending_effects.is_empty() {
 663                    break;
 664                }
 665            }
 666        }
 667    }
 668
 669    /// Repeatedly called during `flush_effects` to release any entities whose
 670    /// reference count has become zero. We invoke any release observers before dropping
 671    /// each entity.
 672    fn release_dropped_entities(&mut self) {
 673        loop {
 674            let dropped = self.entities.take_dropped();
 675            if dropped.is_empty() {
 676                break;
 677            }
 678
 679            for (entity_id, mut entity) in dropped {
 680                self.observers.remove(&entity_id);
 681                self.event_listeners.remove(&entity_id);
 682                for release_callback in self.release_listeners.remove(&entity_id) {
 683                    release_callback(entity.as_mut(), self);
 684                }
 685            }
 686        }
 687    }
 688
 689    /// Repeatedly called during `flush_effects` to handle a focused handle being dropped.
 690    fn release_dropped_focus_handles(&mut self) {
 691        for window_handle in self.windows() {
 692            window_handle
 693                .update(self, |_, cx| {
 694                    let mut blur_window = false;
 695                    let focus = cx.window.focus;
 696                    cx.window.focus_handles.write().retain(|handle_id, count| {
 697                        if count.load(SeqCst) == 0 {
 698                            if focus == Some(handle_id) {
 699                                blur_window = true;
 700                            }
 701                            false
 702                        } else {
 703                            true
 704                        }
 705                    });
 706
 707                    if blur_window {
 708                        cx.blur();
 709                    }
 710                })
 711                .unwrap();
 712        }
 713    }
 714
 715    fn apply_notify_effect(&mut self, emitter: EntityId) {
 716        self.pending_notifications.remove(&emitter);
 717
 718        self.observers
 719            .clone()
 720            .retain(&emitter, |handler| handler(self));
 721    }
 722
 723    fn apply_emit_effect(&mut self, emitter: EntityId, event_type: TypeId, event: Box<dyn Any>) {
 724        self.event_listeners
 725            .clone()
 726            .retain(&emitter, |(stored_type, handler)| {
 727                if *stored_type == event_type {
 728                    handler(event.as_ref(), self)
 729                } else {
 730                    true
 731                }
 732            });
 733    }
 734
 735    fn apply_refresh_effect(&mut self) {
 736        for window in self.windows.values_mut() {
 737            if let Some(window) = window.as_mut() {
 738                window.dirty = true;
 739            }
 740        }
 741    }
 742
 743    fn apply_notify_global_observers_effect(&mut self, type_id: TypeId) {
 744        self.pending_global_notifications.remove(&type_id);
 745        self.global_observers
 746            .clone()
 747            .retain(&type_id, |observer| observer(self));
 748    }
 749
 750    fn apply_defer_effect(&mut self, callback: Box<dyn FnOnce(&mut Self) + 'static>) {
 751        callback(self);
 752    }
 753
 754    /// Creates an `AsyncAppContext`, which can be cloned and has a static lifetime
 755    /// so it can be held across `await` points.
 756    pub fn to_async(&self) -> AsyncAppContext {
 757        AsyncAppContext {
 758            app: unsafe { mem::transmute(self.this.clone()) },
 759            background_executor: self.background_executor.clone(),
 760            foreground_executor: self.foreground_executor.clone(),
 761        }
 762    }
 763
 764    /// Obtains a reference to the executor, which can be used to spawn futures.
 765    pub fn background_executor(&self) -> &BackgroundExecutor {
 766        &self.background_executor
 767    }
 768
 769    /// Obtains a reference to the executor, which can be used to spawn futures.
 770    pub fn foreground_executor(&self) -> &ForegroundExecutor {
 771        &self.foreground_executor
 772    }
 773
 774    /// Spawns the future returned by the given function on the thread pool. The closure will be invoked
 775    /// with [AsyncAppContext], which allows the application state to be accessed across await points.
 776    pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut) -> Task<R>
 777    where
 778        Fut: Future<Output = R> + 'static,
 779        R: 'static,
 780    {
 781        self.foreground_executor.spawn(f(self.to_async()))
 782    }
 783
 784    /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
 785    /// that are currently on the stack to be returned to the app.
 786    pub fn defer(&mut self, f: impl FnOnce(&mut AppContext) + 'static) {
 787        self.push_effect(Effect::Defer {
 788            callback: Box::new(f),
 789        });
 790    }
 791
 792    /// Accessor for the application's asset source, which is provided when constructing the `App`.
 793    pub fn asset_source(&self) -> &Arc<dyn AssetSource> {
 794        &self.asset_source
 795    }
 796
 797    /// Accessor for the text system.
 798    pub fn text_system(&self) -> &Arc<TextSystem> {
 799        &self.text_system
 800    }
 801
 802    /// The current text style. Which is composed of all the style refinements provided to `with_text_style`.
 803    pub fn text_style(&self) -> TextStyle {
 804        let mut style = TextStyle::default();
 805        for refinement in &self.text_style_stack {
 806            style.refine(refinement);
 807        }
 808        style
 809    }
 810
 811    /// Check whether a global of the given type has been assigned.
 812    pub fn has_global<G: 'static>(&self) -> bool {
 813        self.globals_by_type.contains_key(&TypeId::of::<G>())
 814    }
 815
 816    /// Access the global of the given type. Panics if a global for that type has not been assigned.
 817    #[track_caller]
 818    pub fn global<G: 'static>(&self) -> &G {
 819        self.globals_by_type
 820            .get(&TypeId::of::<G>())
 821            .map(|any_state| any_state.downcast_ref::<G>().unwrap())
 822            .ok_or_else(|| anyhow!("no state of type {} exists", type_name::<G>()))
 823            .unwrap()
 824    }
 825
 826    /// Access the global of the given type if a value has been assigned.
 827    pub fn try_global<G: 'static>(&self) -> Option<&G> {
 828        self.globals_by_type
 829            .get(&TypeId::of::<G>())
 830            .map(|any_state| any_state.downcast_ref::<G>().unwrap())
 831    }
 832
 833    /// Access the global of the given type mutably. Panics if a global for that type has not been assigned.
 834    #[track_caller]
 835    pub fn global_mut<G: 'static>(&mut self) -> &mut G {
 836        let global_type = TypeId::of::<G>();
 837        self.push_effect(Effect::NotifyGlobalObservers { global_type });
 838        self.globals_by_type
 839            .get_mut(&global_type)
 840            .and_then(|any_state| any_state.downcast_mut::<G>())
 841            .ok_or_else(|| anyhow!("no state of type {} exists", type_name::<G>()))
 842            .unwrap()
 843    }
 844
 845    /// Access the global of the given type mutably. A default value is assigned if a global of this type has not
 846    /// yet been assigned.
 847    pub fn default_global<G: 'static + Default>(&mut self) -> &mut G {
 848        let global_type = TypeId::of::<G>();
 849        self.push_effect(Effect::NotifyGlobalObservers { global_type });
 850        self.globals_by_type
 851            .entry(global_type)
 852            .or_insert_with(|| Box::<G>::default())
 853            .downcast_mut::<G>()
 854            .unwrap()
 855    }
 856
 857    /// Set the value of the global of the given type.
 858    pub fn set_global<G: Any>(&mut self, global: G) {
 859        let global_type = TypeId::of::<G>();
 860        self.push_effect(Effect::NotifyGlobalObservers { global_type });
 861        self.globals_by_type.insert(global_type, Box::new(global));
 862    }
 863
 864    /// Clear all stored globals. Does not notify global observers.
 865    #[cfg(any(test, feature = "test-support"))]
 866    pub fn clear_globals(&mut self) {
 867        self.globals_by_type.drain();
 868    }
 869
 870    /// Remove the global of the given type from the app context. Does not notify global observers.
 871    pub fn remove_global<G: Any>(&mut self) -> G {
 872        let global_type = TypeId::of::<G>();
 873        self.push_effect(Effect::NotifyGlobalObservers { global_type });
 874        *self
 875            .globals_by_type
 876            .remove(&global_type)
 877            .unwrap_or_else(|| panic!("no global added for {}", std::any::type_name::<G>()))
 878            .downcast()
 879            .unwrap()
 880    }
 881
 882    /// Update the global of the given type with a closure. Unlike `global_mut`, this method provides
 883    /// your closure with mutable access to the `AppContext` and the global simultaneously.
 884    pub fn update_global<G: 'static, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R {
 885        self.update(|cx| {
 886            let mut global = cx.lease_global::<G>();
 887            let result = f(&mut global, cx);
 888            cx.end_global_lease(global);
 889            result
 890        })
 891    }
 892
 893    /// Register a callback to be invoked when a global of the given type is updated.
 894    pub fn observe_global<G: 'static>(
 895        &mut self,
 896        mut f: impl FnMut(&mut Self) + 'static,
 897    ) -> Subscription {
 898        let (subscription, activate) = self.global_observers.insert(
 899            TypeId::of::<G>(),
 900            Box::new(move |cx| {
 901                f(cx);
 902                true
 903            }),
 904        );
 905        self.defer(move |_| activate());
 906        subscription
 907    }
 908
 909    /// Move the global of the given type to the stack.
 910    pub(crate) fn lease_global<G: 'static>(&mut self) -> GlobalLease<G> {
 911        GlobalLease::new(
 912            self.globals_by_type
 913                .remove(&TypeId::of::<G>())
 914                .ok_or_else(|| anyhow!("no global registered of type {}", type_name::<G>()))
 915                .unwrap(),
 916        )
 917    }
 918
 919    /// Restore the global of the given type after it is moved to the stack.
 920    pub(crate) fn end_global_lease<G: 'static>(&mut self, lease: GlobalLease<G>) {
 921        let global_type = TypeId::of::<G>();
 922        self.push_effect(Effect::NotifyGlobalObservers { global_type });
 923        self.globals_by_type.insert(global_type, lease.global);
 924    }
 925
 926    /// Arrange for the given function to be invoked whenever a view of the specified type is created.
 927    /// The function will be passed a mutable reference to the view along with an appropriate context.
 928    pub fn observe_new_views<V: 'static>(
 929        &mut self,
 930        on_new: impl 'static + Fn(&mut V, &mut ViewContext<V>),
 931    ) -> Subscription {
 932        let (subscription, activate) = self.new_view_observers.insert(
 933            TypeId::of::<V>(),
 934            Box::new(move |any_view: AnyView, cx: &mut WindowContext| {
 935                any_view
 936                    .downcast::<V>()
 937                    .unwrap()
 938                    .update(cx, |view_state, cx| {
 939                        on_new(view_state, cx);
 940                    })
 941            }),
 942        );
 943        activate();
 944        subscription
 945    }
 946
 947    /// Observe the release of a model or view. The callback is invoked after the model or view
 948    /// has no more strong references but before it has been dropped.
 949    pub fn observe_release<E, T>(
 950        &mut self,
 951        handle: &E,
 952        on_release: impl FnOnce(&mut T, &mut AppContext) + 'static,
 953    ) -> Subscription
 954    where
 955        E: Entity<T>,
 956        T: 'static,
 957    {
 958        let (subscription, activate) = self.release_listeners.insert(
 959            handle.entity_id(),
 960            Box::new(move |entity, cx| {
 961                let entity = entity.downcast_mut().expect("invalid entity type");
 962                on_release(entity, cx)
 963            }),
 964        );
 965        activate();
 966        subscription
 967    }
 968
 969    /// Register a callback to be invoked when a keystroke is received by the application
 970    /// in any window. Note that this fires after all other action and event mechanisms have resolved
 971    /// and that this API will not be invoked if the event's propagation is stopped.
 972    pub fn observe_keystrokes(
 973        &mut self,
 974        f: impl FnMut(&KeystrokeEvent, &mut WindowContext) + 'static,
 975    ) -> Subscription {
 976        let (subscription, activate) = self.keystroke_observers.insert((), Box::new(f));
 977        activate();
 978        subscription
 979    }
 980
 981    pub(crate) fn push_text_style(&mut self, text_style: TextStyleRefinement) {
 982        self.text_style_stack.push(text_style);
 983    }
 984
 985    pub(crate) fn pop_text_style(&mut self) {
 986        self.text_style_stack.pop();
 987    }
 988
 989    /// Register key bindings.
 990    pub fn bind_keys(&mut self, bindings: impl IntoIterator<Item = KeyBinding>) {
 991        self.keymap.lock().add_bindings(bindings);
 992        self.pending_effects.push_back(Effect::Refresh);
 993    }
 994
 995    /// Clear all key bindings in the app.
 996    pub fn clear_key_bindings(&mut self) {
 997        self.keymap.lock().clear();
 998        self.pending_effects.push_back(Effect::Refresh);
 999    }
1000
1001    /// Register a global listener for actions invoked via the keyboard.
1002    pub fn on_action<A: Action>(&mut self, listener: impl Fn(&A, &mut Self) + 'static) {
1003        self.global_action_listeners
1004            .entry(TypeId::of::<A>())
1005            .or_default()
1006            .push(Rc::new(move |action, phase, cx| {
1007                if phase == DispatchPhase::Bubble {
1008                    let action = action.downcast_ref().unwrap();
1009                    listener(action, cx)
1010                }
1011            }));
1012    }
1013
1014    /// Event handlers propagate events by default. Call this method to stop dispatching to
1015    /// event handlers with a lower z-index (mouse) or higher in the tree (keyboard). This is
1016    /// the opposite of [`Self::propagate`]. It's also possible to cancel a call to [`Self::propagate`] by
1017    /// calling this method before effects are flushed.
1018    pub fn stop_propagation(&mut self) {
1019        self.propagate_event = false;
1020    }
1021
1022    /// Action handlers stop propagation by default during the bubble phase of action dispatch
1023    /// dispatching to action handlers higher in the element tree. This is the opposite of
1024    /// [`Self::stop_propagation`]. It's also possible to cancel a call to [`Self::stop_propagation`] by calling
1025    /// this method before effects are flushed.
1026    pub fn propagate(&mut self) {
1027        self.propagate_event = true;
1028    }
1029
1030    /// Build an action from some arbitrary data, typically a keymap entry.
1031    pub fn build_action(
1032        &self,
1033        name: &str,
1034        data: Option<serde_json::Value>,
1035    ) -> Result<Box<dyn Action>> {
1036        self.actions.build_action(name, data)
1037    }
1038
1039    /// Get a list of all action names that have been registered.
1040    /// in the application. Note that registration only allows for
1041    /// actions to be built dynamically, and is unrelated to binding
1042    /// actions in the element tree.
1043    pub fn all_action_names(&self) -> &[SharedString] {
1044        self.actions.all_action_names()
1045    }
1046
1047    /// Register a callback to be invoked when the application is about to quit.
1048    /// It is not possible to cancel the quit event at this point.
1049    pub fn on_app_quit<Fut>(
1050        &mut self,
1051        mut on_quit: impl FnMut(&mut AppContext) -> Fut + 'static,
1052    ) -> Subscription
1053    where
1054        Fut: 'static + Future<Output = ()>,
1055    {
1056        let (subscription, activate) = self.quit_observers.insert(
1057            (),
1058            Box::new(move |cx| {
1059                let future = on_quit(cx);
1060                future.boxed_local()
1061            }),
1062        );
1063        activate();
1064        subscription
1065    }
1066
1067    pub(crate) fn clear_pending_keystrokes(&mut self) {
1068        for window in self.windows() {
1069            window
1070                .update(self, |_, cx| {
1071                    cx.window
1072                        .rendered_frame
1073                        .dispatch_tree
1074                        .clear_pending_keystrokes();
1075                    cx.window
1076                        .next_frame
1077                        .dispatch_tree
1078                        .clear_pending_keystrokes();
1079                })
1080                .ok();
1081        }
1082    }
1083
1084    /// Checks if the given action is bound in the current context, as defined by the app's current focus,
1085    /// the bindings in the element tree, and any global action listeners.
1086    pub fn is_action_available(&mut self, action: &dyn Action) -> bool {
1087        if let Some(window) = self.active_window() {
1088            if let Ok(window_action_available) =
1089                window.update(self, |_, cx| cx.is_action_available(action))
1090            {
1091                return window_action_available;
1092            }
1093        }
1094
1095        self.global_action_listeners
1096            .contains_key(&action.as_any().type_id())
1097    }
1098
1099    /// Set the menu bar for this application. This will replace any existing menu bar.
1100    pub fn set_menus(&mut self, menus: Vec<Menu>) {
1101        self.platform.set_menus(menus, &self.keymap.lock());
1102    }
1103
1104    /// Dispatch an action to the currently active window or global action handler
1105    /// See [action::Action] for more information on how actions work
1106    pub fn dispatch_action(&mut self, action: &dyn Action) {
1107        if let Some(active_window) = self.active_window() {
1108            active_window
1109                .update(self, |_, cx| cx.dispatch_action(action.boxed_clone()))
1110                .log_err();
1111        } else {
1112            self.propagate_event = true;
1113
1114            if let Some(mut global_listeners) = self
1115                .global_action_listeners
1116                .remove(&action.as_any().type_id())
1117            {
1118                for listener in &global_listeners {
1119                    listener(action.as_any(), DispatchPhase::Capture, self);
1120                    if !self.propagate_event {
1121                        break;
1122                    }
1123                }
1124
1125                global_listeners.extend(
1126                    self.global_action_listeners
1127                        .remove(&action.as_any().type_id())
1128                        .unwrap_or_default(),
1129                );
1130
1131                self.global_action_listeners
1132                    .insert(action.as_any().type_id(), global_listeners);
1133            }
1134
1135            if self.propagate_event {
1136                if let Some(mut global_listeners) = self
1137                    .global_action_listeners
1138                    .remove(&action.as_any().type_id())
1139                {
1140                    for listener in global_listeners.iter().rev() {
1141                        listener(action.as_any(), DispatchPhase::Bubble, self);
1142                        if !self.propagate_event {
1143                            break;
1144                        }
1145                    }
1146
1147                    global_listeners.extend(
1148                        self.global_action_listeners
1149                            .remove(&action.as_any().type_id())
1150                            .unwrap_or_default(),
1151                    );
1152
1153                    self.global_action_listeners
1154                        .insert(action.as_any().type_id(), global_listeners);
1155                }
1156            }
1157        }
1158    }
1159
1160    /// Is there currently something being dragged?
1161    pub fn has_active_drag(&self) -> bool {
1162        self.active_drag.is_some()
1163    }
1164}
1165
1166impl Context for AppContext {
1167    type Result<T> = T;
1168
1169    /// Build an entity that is owned by the application. The given function will be invoked with
1170    /// a `ModelContext` and must return an object representing the entity. A `Model` will be returned
1171    /// which can be used to access the entity in a context.
1172    fn new_model<T: 'static>(
1173        &mut self,
1174        build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
1175    ) -> Model<T> {
1176        self.update(|cx| {
1177            let slot = cx.entities.reserve();
1178            let entity = build_model(&mut ModelContext::new(cx, slot.downgrade()));
1179            cx.entities.insert(slot, entity)
1180        })
1181    }
1182
1183    /// Update the entity referenced by the given model. The function is passed a mutable reference to the
1184    /// entity along with a `ModelContext` for the entity.
1185    fn update_model<T: 'static, R>(
1186        &mut self,
1187        model: &Model<T>,
1188        update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
1189    ) -> R {
1190        self.update(|cx| {
1191            let mut entity = cx.entities.lease(model);
1192            let result = update(&mut entity, &mut ModelContext::new(cx, model.downgrade()));
1193            cx.entities.end_lease(entity);
1194            result
1195        })
1196    }
1197
1198    fn update_window<T, F>(&mut self, handle: AnyWindowHandle, update: F) -> Result<T>
1199    where
1200        F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
1201    {
1202        self.update(|cx| {
1203            let mut window = cx
1204                .windows
1205                .get_mut(handle.id)
1206                .ok_or_else(|| anyhow!("window not found"))?
1207                .take()
1208                .unwrap();
1209
1210            let root_view = window.root_view.clone().unwrap();
1211            let result = update(root_view, &mut WindowContext::new(cx, &mut window));
1212
1213            if window.removed {
1214                cx.windows.remove(handle.id);
1215            } else {
1216                cx.windows
1217                    .get_mut(handle.id)
1218                    .ok_or_else(|| anyhow!("window not found"))?
1219                    .replace(window);
1220            }
1221
1222            Ok(result)
1223        })
1224    }
1225
1226    fn read_model<T, R>(
1227        &self,
1228        handle: &Model<T>,
1229        read: impl FnOnce(&T, &AppContext) -> R,
1230    ) -> Self::Result<R>
1231    where
1232        T: 'static,
1233    {
1234        let entity = self.entities.read(handle);
1235        read(entity, self)
1236    }
1237
1238    fn read_window<T, R>(
1239        &self,
1240        window: &WindowHandle<T>,
1241        read: impl FnOnce(View<T>, &AppContext) -> R,
1242    ) -> Result<R>
1243    where
1244        T: 'static,
1245    {
1246        let window = self
1247            .windows
1248            .get(window.id)
1249            .ok_or_else(|| anyhow!("window not found"))?
1250            .as_ref()
1251            .unwrap();
1252
1253        let root_view = window.root_view.clone().unwrap();
1254        let view = root_view
1255            .downcast::<T>()
1256            .map_err(|_| anyhow!("root view's type has changed"))?;
1257
1258        Ok(read(view, self))
1259    }
1260}
1261
1262/// These effects are processed at the end of each application update cycle.
1263pub(crate) enum Effect {
1264    Notify {
1265        emitter: EntityId,
1266    },
1267    Emit {
1268        emitter: EntityId,
1269        event_type: TypeId,
1270        event: Box<dyn Any>,
1271    },
1272    Refresh,
1273    NotifyGlobalObservers {
1274        global_type: TypeId,
1275    },
1276    Defer {
1277        callback: Box<dyn FnOnce(&mut AppContext) + 'static>,
1278    },
1279}
1280
1281/// Wraps a global variable value during `update_global` while the value has been moved to the stack.
1282pub(crate) struct GlobalLease<G: 'static> {
1283    global: Box<dyn Any>,
1284    global_type: PhantomData<G>,
1285}
1286
1287impl<G: 'static> GlobalLease<G> {
1288    fn new(global: Box<dyn Any>) -> Self {
1289        GlobalLease {
1290            global,
1291            global_type: PhantomData,
1292        }
1293    }
1294}
1295
1296impl<G: 'static> Deref for GlobalLease<G> {
1297    type Target = G;
1298
1299    fn deref(&self) -> &Self::Target {
1300        self.global.downcast_ref().unwrap()
1301    }
1302}
1303
1304impl<G: 'static> DerefMut for GlobalLease<G> {
1305    fn deref_mut(&mut self) -> &mut Self::Target {
1306        self.global.downcast_mut().unwrap()
1307    }
1308}
1309
1310/// Contains state associated with an active drag operation, started by dragging an element
1311/// within the window or by dragging into the app from the underlying platform.
1312pub struct AnyDrag {
1313    /// The view used to render this drag
1314    pub view: AnyView,
1315
1316    /// The value of the dragged item, to be dropped
1317    pub value: Box<dyn Any>,
1318
1319    /// This is used to render the dragged item in the same place
1320    /// on the original element that the drag was initiated
1321    pub cursor_offset: Point<Pixels>,
1322}
1323
1324/// Contains state associated with a tooltip. You'll only need this struct if you're implementing
1325/// tooltip behavior on a custom element. Otherwise, use [Div::tooltip].
1326#[derive(Clone)]
1327pub struct AnyTooltip {
1328    /// The view used to display the tooltip
1329    pub view: AnyView,
1330
1331    /// The offset from the cursor to use, relative to the parent view
1332    pub cursor_offset: Point<Pixels>,
1333}
1334
1335/// A keystroke event, and potentially the associated action
1336#[derive(Debug)]
1337pub struct KeystrokeEvent {
1338    /// The keystroke that occurred
1339    pub keystroke: Keystroke,
1340
1341    /// The action that was resolved for the keystroke, if any
1342    pub action: Option<Box<dyn Action>>,
1343}