window.rs

   1use crate::{
   2    point, px, size, transparent_black, Action, AnyDrag, AnyView, AppContext, Arena,
   3    AsyncWindowContext, Bounds, Context, Corners, CursorStyle, DevicePixels,
   4    DispatchActionListener, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity,
   5    EntityId, EventEmitter, FileDropEvent, Flatten, Global, GlobalElementId, Hsla, KeyBinding,
   6    KeyDownEvent, KeyMatch, KeymatchResult, Keystroke, KeystrokeEvent, Model, ModelContext,
   7    Modifiers, ModifiersChangedEvent, MouseButton, MouseMoveEvent, MouseUpEvent, Pixels,
   8    PlatformAtlas, PlatformDisplay, PlatformInput, PlatformWindow, Point, PromptLevel, Render,
   9    ScaledPixels, SharedString, Size, SubscriberSet, Subscription, TaffyLayoutEngine, Task,
  10    TextStyle, TextStyleRefinement, View, VisualContext, WeakView, WindowAppearance, WindowOptions,
  11    WindowParams, WindowTextSystem,
  12};
  13use anyhow::{anyhow, Context as _, Result};
  14use collections::FxHashSet;
  15use derive_more::{Deref, DerefMut};
  16use futures::channel::oneshot;
  17use parking_lot::RwLock;
  18use refineable::Refineable;
  19use slotmap::SlotMap;
  20use smallvec::SmallVec;
  21use std::{
  22    any::{Any, TypeId},
  23    borrow::{Borrow, BorrowMut},
  24    cell::{Cell, RefCell},
  25    fmt::{Debug, Display},
  26    future::Future,
  27    hash::{Hash, Hasher},
  28    marker::PhantomData,
  29    mem,
  30    rc::Rc,
  31    sync::{
  32        atomic::{AtomicUsize, Ordering::SeqCst},
  33        Arc, Weak,
  34    },
  35    time::{Duration, Instant},
  36};
  37use util::{measure, ResultExt};
  38
  39mod element_cx;
  40mod prompts;
  41
  42pub use element_cx::*;
  43pub use prompts::*;
  44
  45/// Represents the two different phases when dispatching events.
  46#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]
  47pub enum DispatchPhase {
  48    /// After the capture phase comes the bubble phase, in which mouse event listeners are
  49    /// invoked front to back and keyboard event listeners are invoked from the focused element
  50    /// to the root of the element tree. This is the phase you'll most commonly want to use when
  51    /// registering event listeners.
  52    #[default]
  53    Bubble,
  54    /// During the initial capture phase, mouse event listeners are invoked back to front, and keyboard
  55    /// listeners are invoked from the root of the tree downward toward the focused element. This phase
  56    /// is used for special purposes such as clearing the "pressed" state for click events. If
  57    /// you stop event propagation during this phase, you need to know what you're doing. Handlers
  58    /// outside of the immediate region may rely on detecting non-local events during this phase.
  59    Capture,
  60}
  61
  62impl DispatchPhase {
  63    /// Returns true if this represents the "bubble" phase.
  64    pub fn bubble(self) -> bool {
  65        self == DispatchPhase::Bubble
  66    }
  67
  68    /// Returns true if this represents the "capture" phase.
  69    pub fn capture(self) -> bool {
  70        self == DispatchPhase::Capture
  71    }
  72}
  73
  74type AnyObserver = Box<dyn FnMut(&mut WindowContext) -> bool + 'static>;
  75
  76type AnyWindowFocusListener = Box<dyn FnMut(&FocusEvent, &mut WindowContext) -> bool + 'static>;
  77
  78struct FocusEvent {
  79    previous_focus_path: SmallVec<[FocusId; 8]>,
  80    current_focus_path: SmallVec<[FocusId; 8]>,
  81}
  82
  83slotmap::new_key_type! {
  84    /// A globally unique identifier for a focusable element.
  85    pub struct FocusId;
  86}
  87
  88thread_local! {
  89    pub(crate) static ELEMENT_ARENA: RefCell<Arena> = RefCell::new(Arena::new(8 * 1024 * 1024));
  90}
  91
  92impl FocusId {
  93    /// Obtains whether the element associated with this handle is currently focused.
  94    pub fn is_focused(&self, cx: &WindowContext) -> bool {
  95        cx.window.focus == Some(*self)
  96    }
  97
  98    /// Obtains whether the element associated with this handle contains the focused
  99    /// element or is itself focused.
 100    pub fn contains_focused(&self, cx: &WindowContext) -> bool {
 101        cx.focused()
 102            .map_or(false, |focused| self.contains(focused.id, cx))
 103    }
 104
 105    /// Obtains whether the element associated with this handle is contained within the
 106    /// focused element or is itself focused.
 107    pub fn within_focused(&self, cx: &WindowContext) -> bool {
 108        let focused = cx.focused();
 109        focused.map_or(false, |focused| focused.id.contains(*self, cx))
 110    }
 111
 112    /// Obtains whether this handle contains the given handle in the most recently rendered frame.
 113    pub(crate) fn contains(&self, other: Self, cx: &WindowContext) -> bool {
 114        cx.window
 115            .rendered_frame
 116            .dispatch_tree
 117            .focus_contains(*self, other)
 118    }
 119}
 120
 121/// A handle which can be used to track and manipulate the focused element in a window.
 122pub struct FocusHandle {
 123    pub(crate) id: FocusId,
 124    handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
 125}
 126
 127impl std::fmt::Debug for FocusHandle {
 128    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 129        f.write_fmt(format_args!("FocusHandle({:?})", self.id))
 130    }
 131}
 132
 133impl FocusHandle {
 134    pub(crate) fn new(handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>) -> Self {
 135        let id = handles.write().insert(AtomicUsize::new(1));
 136        Self {
 137            id,
 138            handles: handles.clone(),
 139        }
 140    }
 141
 142    pub(crate) fn for_id(
 143        id: FocusId,
 144        handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
 145    ) -> Option<Self> {
 146        let lock = handles.read();
 147        let ref_count = lock.get(id)?;
 148        if ref_count.load(SeqCst) == 0 {
 149            None
 150        } else {
 151            ref_count.fetch_add(1, SeqCst);
 152            Some(Self {
 153                id,
 154                handles: handles.clone(),
 155            })
 156        }
 157    }
 158
 159    /// Converts this focus handle into a weak variant, which does not prevent it from being released.
 160    pub fn downgrade(&self) -> WeakFocusHandle {
 161        WeakFocusHandle {
 162            id: self.id,
 163            handles: Arc::downgrade(&self.handles),
 164        }
 165    }
 166
 167    /// Moves the focus to the element associated with this handle.
 168    pub fn focus(&self, cx: &mut WindowContext) {
 169        cx.focus(self)
 170    }
 171
 172    /// Obtains whether the element associated with this handle is currently focused.
 173    pub fn is_focused(&self, cx: &WindowContext) -> bool {
 174        self.id.is_focused(cx)
 175    }
 176
 177    /// Obtains whether the element associated with this handle contains the focused
 178    /// element or is itself focused.
 179    pub fn contains_focused(&self, cx: &WindowContext) -> bool {
 180        self.id.contains_focused(cx)
 181    }
 182
 183    /// Obtains whether the element associated with this handle is contained within the
 184    /// focused element or is itself focused.
 185    pub fn within_focused(&self, cx: &WindowContext) -> bool {
 186        self.id.within_focused(cx)
 187    }
 188
 189    /// Obtains whether this handle contains the given handle in the most recently rendered frame.
 190    pub fn contains(&self, other: &Self, cx: &WindowContext) -> bool {
 191        self.id.contains(other.id, cx)
 192    }
 193}
 194
 195impl Clone for FocusHandle {
 196    fn clone(&self) -> Self {
 197        Self::for_id(self.id, &self.handles).unwrap()
 198    }
 199}
 200
 201impl PartialEq for FocusHandle {
 202    fn eq(&self, other: &Self) -> bool {
 203        self.id == other.id
 204    }
 205}
 206
 207impl Eq for FocusHandle {}
 208
 209impl Drop for FocusHandle {
 210    fn drop(&mut self) {
 211        self.handles
 212            .read()
 213            .get(self.id)
 214            .unwrap()
 215            .fetch_sub(1, SeqCst);
 216    }
 217}
 218
 219/// A weak reference to a focus handle.
 220#[derive(Clone, Debug)]
 221pub struct WeakFocusHandle {
 222    pub(crate) id: FocusId,
 223    handles: Weak<RwLock<SlotMap<FocusId, AtomicUsize>>>,
 224}
 225
 226impl WeakFocusHandle {
 227    /// Attempts to upgrade the [WeakFocusHandle] to a [FocusHandle].
 228    pub fn upgrade(&self) -> Option<FocusHandle> {
 229        let handles = self.handles.upgrade()?;
 230        FocusHandle::for_id(self.id, &handles)
 231    }
 232}
 233
 234impl PartialEq for WeakFocusHandle {
 235    fn eq(&self, other: &WeakFocusHandle) -> bool {
 236        self.id == other.id
 237    }
 238}
 239
 240impl Eq for WeakFocusHandle {}
 241
 242impl PartialEq<FocusHandle> for WeakFocusHandle {
 243    fn eq(&self, other: &FocusHandle) -> bool {
 244        self.id == other.id
 245    }
 246}
 247
 248impl PartialEq<WeakFocusHandle> for FocusHandle {
 249    fn eq(&self, other: &WeakFocusHandle) -> bool {
 250        self.id == other.id
 251    }
 252}
 253
 254/// FocusableView allows users of your view to easily
 255/// focus it (using cx.focus_view(view))
 256pub trait FocusableView: 'static + Render {
 257    /// Returns the focus handle associated with this view.
 258    fn focus_handle(&self, cx: &AppContext) -> FocusHandle;
 259}
 260
 261/// ManagedView is a view (like a Modal, Popover, Menu, etc.)
 262/// where the lifecycle of the view is handled by another view.
 263pub trait ManagedView: FocusableView + EventEmitter<DismissEvent> {}
 264
 265impl<M: FocusableView + EventEmitter<DismissEvent>> ManagedView for M {}
 266
 267/// Emitted by implementers of [`ManagedView`] to indicate the view should be dismissed, such as when a view is presented as a modal.
 268pub struct DismissEvent;
 269
 270type FrameCallback = Box<dyn FnOnce(&mut WindowContext)>;
 271
 272// Holds the state for a specific window.
 273#[doc(hidden)]
 274pub struct Window {
 275    pub(crate) handle: AnyWindowHandle,
 276    pub(crate) removed: bool,
 277    pub(crate) platform_window: Box<dyn PlatformWindow>,
 278    display_id: DisplayId,
 279    sprite_atlas: Arc<dyn PlatformAtlas>,
 280    text_system: Arc<WindowTextSystem>,
 281    pub(crate) rem_size: Pixels,
 282    pub(crate) viewport_size: Size<Pixels>,
 283    layout_engine: Option<TaffyLayoutEngine>,
 284    pub(crate) root_view: Option<AnyView>,
 285    pub(crate) element_id_stack: GlobalElementId,
 286    pub(crate) text_style_stack: Vec<TextStyleRefinement>,
 287    pub(crate) rendered_frame: Frame,
 288    pub(crate) next_frame: Frame,
 289    pub(crate) next_hitbox_id: HitboxId,
 290    next_frame_callbacks: Rc<RefCell<Vec<FrameCallback>>>,
 291    pub(crate) dirty_views: FxHashSet<EntityId>,
 292    pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
 293    focus_listeners: SubscriberSet<(), AnyWindowFocusListener>,
 294    focus_lost_listeners: SubscriberSet<(), AnyObserver>,
 295    default_prevented: bool,
 296    mouse_position: Point<Pixels>,
 297    mouse_hit_test: HitTest,
 298    modifiers: Modifiers,
 299    scale_factor: f32,
 300    bounds_observers: SubscriberSet<(), AnyObserver>,
 301    appearance: WindowAppearance,
 302    appearance_observers: SubscriberSet<(), AnyObserver>,
 303    active: Rc<Cell<bool>>,
 304    pub(crate) dirty: Rc<Cell<bool>>,
 305    pub(crate) needs_present: Rc<Cell<bool>>,
 306    pub(crate) last_input_timestamp: Rc<Cell<Instant>>,
 307    pub(crate) refreshing: bool,
 308    pub(crate) draw_phase: DrawPhase,
 309    activation_observers: SubscriberSet<(), AnyObserver>,
 310    pub(crate) focus: Option<FocusId>,
 311    focus_enabled: bool,
 312    pending_input: Option<PendingInput>,
 313    prompt: Option<RenderablePromptHandle>,
 314}
 315
 316#[derive(Clone, Copy, Debug, Eq, PartialEq)]
 317pub(crate) enum DrawPhase {
 318    None,
 319    Layout,
 320    Paint,
 321    Focus,
 322}
 323
 324#[derive(Default, Debug)]
 325struct PendingInput {
 326    keystrokes: SmallVec<[Keystroke; 1]>,
 327    bindings: SmallVec<[KeyBinding; 1]>,
 328    focus: Option<FocusId>,
 329    timer: Option<Task<()>>,
 330}
 331
 332impl PendingInput {
 333    fn input(&self) -> String {
 334        self.keystrokes
 335            .iter()
 336            .flat_map(|k| k.ime_key.clone())
 337            .collect::<Vec<String>>()
 338            .join("")
 339    }
 340
 341    fn used_by_binding(&self, binding: &KeyBinding) -> bool {
 342        if self.keystrokes.is_empty() {
 343            return true;
 344        }
 345        let keystroke = &self.keystrokes[0];
 346        for candidate in keystroke.match_candidates() {
 347            if binding.match_keystrokes(&[candidate]) == KeyMatch::Pending {
 348                return true;
 349            }
 350        }
 351        false
 352    }
 353}
 354
 355pub(crate) struct ElementStateBox {
 356    pub(crate) inner: Box<dyn Any>,
 357    #[cfg(debug_assertions)]
 358    pub(crate) type_name: &'static str,
 359}
 360
 361fn default_bounds(display_id: Option<DisplayId>, cx: &mut AppContext) -> Bounds<DevicePixels> {
 362    const DEFAULT_WINDOW_SIZE: Size<DevicePixels> = size(DevicePixels(1024), DevicePixels(700));
 363    const DEFAULT_WINDOW_OFFSET: Point<DevicePixels> = point(DevicePixels(0), DevicePixels(35));
 364
 365    cx.active_window()
 366        .and_then(|w| w.update(cx, |_, cx| cx.window_bounds()).ok())
 367        .map(|bounds| bounds.map_origin(|origin| origin + DEFAULT_WINDOW_OFFSET))
 368        .unwrap_or_else(|| {
 369            let display = display_id
 370                .map(|id| cx.find_display(id))
 371                .unwrap_or_else(|| cx.primary_display());
 372
 373            display
 374                .map(|display| {
 375                    let center = display.bounds().center();
 376                    let offset = DEFAULT_WINDOW_SIZE / 2;
 377                    let origin = point(center.x - offset.width, center.y - offset.height);
 378                    Bounds::new(origin, DEFAULT_WINDOW_SIZE)
 379                })
 380                .unwrap_or_else(|| {
 381                    Bounds::new(point(DevicePixels(0), DevicePixels(0)), DEFAULT_WINDOW_SIZE)
 382                })
 383        })
 384}
 385
 386impl Window {
 387    pub(crate) fn new(
 388        handle: AnyWindowHandle,
 389        options: WindowOptions,
 390        cx: &mut AppContext,
 391    ) -> Self {
 392        let WindowOptions {
 393            bounds,
 394            titlebar,
 395            focus,
 396            show,
 397            kind,
 398            is_movable,
 399            display_id,
 400            fullscreen,
 401        } = options;
 402
 403        let bounds = bounds.unwrap_or_else(|| default_bounds(display_id, cx));
 404        let platform_window = cx.platform.open_window(
 405            handle,
 406            WindowParams {
 407                bounds,
 408                titlebar,
 409                kind,
 410                is_movable,
 411                focus,
 412                show,
 413                display_id,
 414            },
 415        );
 416        let display_id = platform_window.display().id();
 417        let sprite_atlas = platform_window.sprite_atlas();
 418        let mouse_position = platform_window.mouse_position();
 419        let modifiers = platform_window.modifiers();
 420        let content_size = platform_window.content_size();
 421        let scale_factor = platform_window.scale_factor();
 422        let appearance = platform_window.appearance();
 423        let text_system = Arc::new(WindowTextSystem::new(cx.text_system().clone()));
 424        let dirty = Rc::new(Cell::new(true));
 425        let active = Rc::new(Cell::new(platform_window.is_active()));
 426        let needs_present = Rc::new(Cell::new(false));
 427        let next_frame_callbacks: Rc<RefCell<Vec<FrameCallback>>> = Default::default();
 428        let last_input_timestamp = Rc::new(Cell::new(Instant::now()));
 429
 430        if fullscreen {
 431            platform_window.toggle_fullscreen();
 432        }
 433
 434        platform_window.on_close(Box::new({
 435            let mut cx = cx.to_async();
 436            move || {
 437                let _ = handle.update(&mut cx, |_, cx| cx.remove_window());
 438            }
 439        }));
 440        platform_window.on_request_frame(Box::new({
 441            let mut cx = cx.to_async();
 442            let dirty = dirty.clone();
 443            let active = active.clone();
 444            let needs_present = needs_present.clone();
 445            let next_frame_callbacks = next_frame_callbacks.clone();
 446            let last_input_timestamp = last_input_timestamp.clone();
 447            move || {
 448                let next_frame_callbacks = next_frame_callbacks.take();
 449                if !next_frame_callbacks.is_empty() {
 450                    handle
 451                        .update(&mut cx, |_, cx| {
 452                            for callback in next_frame_callbacks {
 453                                callback(cx);
 454                            }
 455                        })
 456                        .log_err();
 457                }
 458
 459                // Keep presenting the current scene for 1 extra second since the
 460                // last input to prevent the display from underclocking the refresh rate.
 461                let needs_present = needs_present.get()
 462                    || (active.get()
 463                        && last_input_timestamp.get().elapsed() < Duration::from_secs(1));
 464
 465                if dirty.get() {
 466                    measure("frame duration", || {
 467                        handle
 468                            .update(&mut cx, |_, cx| {
 469                                cx.draw();
 470                                cx.present();
 471                            })
 472                            .log_err();
 473                    })
 474                } else if needs_present {
 475                    handle.update(&mut cx, |_, cx| cx.present()).log_err();
 476                }
 477            }
 478        }));
 479        platform_window.on_resize(Box::new({
 480            let mut cx = cx.to_async();
 481            move |_, _| {
 482                handle
 483                    .update(&mut cx, |_, cx| cx.window_bounds_changed())
 484                    .log_err();
 485            }
 486        }));
 487        platform_window.on_moved(Box::new({
 488            let mut cx = cx.to_async();
 489            move || {
 490                handle
 491                    .update(&mut cx, |_, cx| cx.window_bounds_changed())
 492                    .log_err();
 493            }
 494        }));
 495        platform_window.on_appearance_changed(Box::new({
 496            let mut cx = cx.to_async();
 497            move || {
 498                handle
 499                    .update(&mut cx, |_, cx| cx.appearance_changed())
 500                    .log_err();
 501            }
 502        }));
 503        platform_window.on_active_status_change(Box::new({
 504            let mut cx = cx.to_async();
 505            move |active| {
 506                handle
 507                    .update(&mut cx, |_, cx| {
 508                        cx.window.active.set(active);
 509                        cx.window
 510                            .activation_observers
 511                            .clone()
 512                            .retain(&(), |callback| callback(cx));
 513                        cx.refresh();
 514                    })
 515                    .log_err();
 516            }
 517        }));
 518
 519        platform_window.on_input({
 520            let mut cx = cx.to_async();
 521            Box::new(move |event| {
 522                handle
 523                    .update(&mut cx, |_, cx| cx.dispatch_event(event))
 524                    .log_err()
 525                    .unwrap_or(DispatchEventResult::default())
 526            })
 527        });
 528
 529        Window {
 530            handle,
 531            removed: false,
 532            platform_window,
 533            display_id,
 534            sprite_atlas,
 535            text_system,
 536            rem_size: px(16.),
 537            viewport_size: content_size,
 538            layout_engine: Some(TaffyLayoutEngine::new()),
 539            root_view: None,
 540            element_id_stack: GlobalElementId::default(),
 541            text_style_stack: Vec::new(),
 542            rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
 543            next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
 544            next_frame_callbacks,
 545            next_hitbox_id: HitboxId::default(),
 546            dirty_views: FxHashSet::default(),
 547            focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
 548            focus_listeners: SubscriberSet::new(),
 549            focus_lost_listeners: SubscriberSet::new(),
 550            default_prevented: true,
 551            mouse_position,
 552            mouse_hit_test: HitTest::default(),
 553            modifiers,
 554            scale_factor,
 555            bounds_observers: SubscriberSet::new(),
 556            appearance,
 557            appearance_observers: SubscriberSet::new(),
 558            active,
 559            dirty,
 560            needs_present,
 561            last_input_timestamp,
 562            refreshing: false,
 563            draw_phase: DrawPhase::None,
 564            activation_observers: SubscriberSet::new(),
 565            focus: None,
 566            focus_enabled: true,
 567            pending_input: None,
 568            prompt: None,
 569        }
 570    }
 571    fn new_focus_listener(
 572        &mut self,
 573        value: AnyWindowFocusListener,
 574    ) -> (Subscription, impl FnOnce()) {
 575        self.focus_listeners.insert((), value)
 576    }
 577}
 578
 579#[derive(Clone, Debug, Default, PartialEq, Eq)]
 580pub(crate) struct DispatchEventResult {
 581    pub propagate: bool,
 582    pub default_prevented: bool,
 583}
 584
 585/// Indicates which region of the window is visible. Content falling outside of this mask will not be
 586/// rendered. Currently, only rectangular content masks are supported, but we give the mask its own type
 587/// to leave room to support more complex shapes in the future.
 588#[derive(Clone, Debug, Default, PartialEq, Eq)]
 589#[repr(C)]
 590pub struct ContentMask<P: Clone + Default + Debug> {
 591    /// The bounds
 592    pub bounds: Bounds<P>,
 593}
 594
 595impl ContentMask<Pixels> {
 596    /// Scale the content mask's pixel units by the given scaling factor.
 597    pub fn scale(&self, factor: f32) -> ContentMask<ScaledPixels> {
 598        ContentMask {
 599            bounds: self.bounds.scale(factor),
 600        }
 601    }
 602
 603    /// Intersect the content mask with the given content mask.
 604    pub fn intersect(&self, other: &Self) -> Self {
 605        let bounds = self.bounds.intersect(&other.bounds);
 606        ContentMask { bounds }
 607    }
 608}
 609
 610/// Provides access to application state in the context of a single window. Derefs
 611/// to an [`AppContext`], so you can also pass a [`WindowContext`] to any method that takes
 612/// an [`AppContext`] and call any [`AppContext`] methods.
 613pub struct WindowContext<'a> {
 614    pub(crate) app: &'a mut AppContext,
 615    pub(crate) window: &'a mut Window,
 616}
 617
 618impl<'a> WindowContext<'a> {
 619    pub(crate) fn new(app: &'a mut AppContext, window: &'a mut Window) -> Self {
 620        Self { app, window }
 621    }
 622
 623    /// Obtain a handle to the window that belongs to this context.
 624    pub fn window_handle(&self) -> AnyWindowHandle {
 625        self.window.handle
 626    }
 627
 628    /// Mark the window as dirty, scheduling it to be redrawn on the next frame.
 629    pub fn refresh(&mut self) {
 630        if self.window.draw_phase == DrawPhase::None {
 631            self.window.refreshing = true;
 632            self.window.dirty.set(true);
 633        }
 634    }
 635
 636    /// Indicate that this view has changed, which will invoke any observers and also mark the window as dirty.
 637    /// If this view or any of its ancestors are *cached*, notifying it will cause it or its ancestors to be redrawn.
 638    pub fn notify(&mut self, view_id: EntityId) {
 639        for view_id in self
 640            .window
 641            .rendered_frame
 642            .dispatch_tree
 643            .view_path(view_id)
 644            .into_iter()
 645            .rev()
 646        {
 647            if !self.window.dirty_views.insert(view_id) {
 648                break;
 649            }
 650        }
 651
 652        if self.window.draw_phase == DrawPhase::None {
 653            self.window.dirty.set(true);
 654            self.app.push_effect(Effect::Notify { emitter: view_id });
 655        }
 656    }
 657
 658    /// Close this window.
 659    pub fn remove_window(&mut self) {
 660        self.window.removed = true;
 661    }
 662
 663    /// Obtain a new [`FocusHandle`], which allows you to track and manipulate the keyboard focus
 664    /// for elements rendered within this window.
 665    pub fn focus_handle(&mut self) -> FocusHandle {
 666        FocusHandle::new(&self.window.focus_handles)
 667    }
 668
 669    /// Obtain the currently focused [`FocusHandle`]. If no elements are focused, returns `None`.
 670    pub fn focused(&self) -> Option<FocusHandle> {
 671        self.window
 672            .focus
 673            .and_then(|id| FocusHandle::for_id(id, &self.window.focus_handles))
 674    }
 675
 676    /// Move focus to the element associated with the given [`FocusHandle`].
 677    pub fn focus(&mut self, handle: &FocusHandle) {
 678        if !self.window.focus_enabled || self.window.focus == Some(handle.id) {
 679            return;
 680        }
 681
 682        self.window.focus = Some(handle.id);
 683        self.window
 684            .rendered_frame
 685            .dispatch_tree
 686            .clear_pending_keystrokes();
 687        self.refresh();
 688    }
 689
 690    /// Remove focus from all elements within this context's window.
 691    pub fn blur(&mut self) {
 692        if !self.window.focus_enabled {
 693            return;
 694        }
 695
 696        self.window.focus = None;
 697        self.refresh();
 698    }
 699
 700    /// Blur the window and don't allow anything in it to be focused again.
 701    pub fn disable_focus(&mut self) {
 702        self.blur();
 703        self.window.focus_enabled = false;
 704    }
 705
 706    /// Accessor for the text system.
 707    pub fn text_system(&self) -> &Arc<WindowTextSystem> {
 708        &self.window.text_system
 709    }
 710
 711    /// The current text style. Which is composed of all the style refinements provided to `with_text_style`.
 712    pub fn text_style(&self) -> TextStyle {
 713        let mut style = TextStyle::default();
 714        for refinement in &self.window.text_style_stack {
 715            style.refine(refinement);
 716        }
 717        style
 718    }
 719
 720    /// Check if the platform window is maximized
 721    /// On some platforms (namely Windows) this is different than the bounds being the size of the display
 722    pub fn is_maximized(&self) -> bool {
 723        self.window.platform_window.is_maximized()
 724    }
 725
 726    /// Check if the platform window is minimized
 727    /// On some platforms (namely Windows) the position is incorrect when minimized
 728    pub fn is_minimized(&self) -> bool {
 729        self.window.platform_window.is_minimized()
 730    }
 731
 732    /// Dispatch the given action on the currently focused element.
 733    pub fn dispatch_action(&mut self, action: Box<dyn Action>) {
 734        let focus_handle = self.focused();
 735
 736        let window = self.window.handle;
 737        self.app.defer(move |cx| {
 738            window
 739                .update(cx, |_, cx| {
 740                    let node_id = focus_handle
 741                        .and_then(|handle| {
 742                            cx.window
 743                                .rendered_frame
 744                                .dispatch_tree
 745                                .focusable_node_id(handle.id)
 746                        })
 747                        .unwrap_or_else(|| cx.window.rendered_frame.dispatch_tree.root_node_id());
 748
 749                    cx.dispatch_action_on_node(node_id, action.as_ref());
 750                })
 751                .log_err();
 752        })
 753    }
 754
 755    pub(crate) fn dispatch_keystroke_observers(
 756        &mut self,
 757        event: &dyn Any,
 758        action: Option<Box<dyn Action>>,
 759    ) {
 760        let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() else {
 761            return;
 762        };
 763
 764        self.keystroke_observers
 765            .clone()
 766            .retain(&(), move |callback| {
 767                (callback)(
 768                    &KeystrokeEvent {
 769                        keystroke: key_down_event.keystroke.clone(),
 770                        action: action.as_ref().map(|action| action.boxed_clone()),
 771                    },
 772                    self,
 773                );
 774                true
 775            });
 776    }
 777
 778    pub(crate) fn clear_pending_keystrokes(&mut self) {
 779        self.window
 780            .rendered_frame
 781            .dispatch_tree
 782            .clear_pending_keystrokes();
 783        self.window
 784            .next_frame
 785            .dispatch_tree
 786            .clear_pending_keystrokes();
 787    }
 788
 789    /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
 790    /// that are currently on the stack to be returned to the app.
 791    pub fn defer(&mut self, f: impl FnOnce(&mut WindowContext) + 'static) {
 792        let handle = self.window.handle;
 793        self.app.defer(move |cx| {
 794            handle.update(cx, |_, cx| f(cx)).ok();
 795        });
 796    }
 797
 798    /// Subscribe to events emitted by a model or view.
 799    /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
 800    /// The callback will be invoked a handle to the emitting entity (either a [`View`] or [`Model`]), the event, and a window context for the current window.
 801    pub fn subscribe<Emitter, E, Evt>(
 802        &mut self,
 803        entity: &E,
 804        mut on_event: impl FnMut(E, &Evt, &mut WindowContext<'_>) + 'static,
 805    ) -> Subscription
 806    where
 807        Emitter: EventEmitter<Evt>,
 808        E: Entity<Emitter>,
 809        Evt: 'static,
 810    {
 811        let entity_id = entity.entity_id();
 812        let entity = entity.downgrade();
 813        let window_handle = self.window.handle;
 814        self.app.new_subscription(
 815            entity_id,
 816            (
 817                TypeId::of::<Evt>(),
 818                Box::new(move |event, cx| {
 819                    window_handle
 820                        .update(cx, |_, cx| {
 821                            if let Some(handle) = E::upgrade_from(&entity) {
 822                                let event = event.downcast_ref().expect("invalid event type");
 823                                on_event(handle, event, cx);
 824                                true
 825                            } else {
 826                                false
 827                            }
 828                        })
 829                        .unwrap_or(false)
 830                }),
 831            ),
 832        )
 833    }
 834
 835    /// Creates an [`AsyncWindowContext`], which has a static lifetime and can be held across
 836    /// await points in async code.
 837    pub fn to_async(&self) -> AsyncWindowContext {
 838        AsyncWindowContext::new(self.app.to_async(), self.window.handle)
 839    }
 840
 841    /// Schedule the given closure to be run directly after the current frame is rendered.
 842    pub fn on_next_frame(&mut self, callback: impl FnOnce(&mut WindowContext) + 'static) {
 843        RefCell::borrow_mut(&self.window.next_frame_callbacks).push(Box::new(callback));
 844    }
 845
 846    /// Spawn the future returned by the given closure on the application thread pool.
 847    /// The closure is provided a handle to the current window and an `AsyncWindowContext` for
 848    /// use within your future.
 849    pub fn spawn<Fut, R>(&mut self, f: impl FnOnce(AsyncWindowContext) -> Fut) -> Task<R>
 850    where
 851        R: 'static,
 852        Fut: Future<Output = R> + 'static,
 853    {
 854        self.app
 855            .spawn(|app| f(AsyncWindowContext::new(app, self.window.handle)))
 856    }
 857
 858    fn window_bounds_changed(&mut self) {
 859        self.window.scale_factor = self.window.platform_window.scale_factor();
 860        self.window.viewport_size = self.window.platform_window.content_size();
 861        self.window.display_id = self.window.platform_window.display().id();
 862        self.refresh();
 863
 864        self.window
 865            .bounds_observers
 866            .clone()
 867            .retain(&(), |callback| callback(self));
 868    }
 869
 870    /// Returns the bounds of the current window in the global coordinate space, which could span across multiple displays.
 871    pub fn window_bounds(&self) -> Bounds<DevicePixels> {
 872        self.window.platform_window.bounds()
 873    }
 874
 875    /// Retusn whether or not the window is currently fullscreen
 876    pub fn is_fullscreen(&self) -> bool {
 877        self.window.platform_window.is_fullscreen()
 878    }
 879
 880    fn appearance_changed(&mut self) {
 881        self.window.appearance = self.window.platform_window.appearance();
 882
 883        self.window
 884            .appearance_observers
 885            .clone()
 886            .retain(&(), |callback| callback(self));
 887    }
 888
 889    /// Returns the appearance of the current window.
 890    pub fn appearance(&self) -> WindowAppearance {
 891        self.window.appearance
 892    }
 893
 894    /// Returns the size of the drawable area within the window.
 895    pub fn viewport_size(&self) -> Size<Pixels> {
 896        self.window.viewport_size
 897    }
 898
 899    /// Returns whether this window is focused by the operating system (receiving key events).
 900    pub fn is_window_active(&self) -> bool {
 901        self.window.active.get()
 902    }
 903
 904    /// Toggle zoom on the window.
 905    pub fn zoom_window(&self) {
 906        self.window.platform_window.zoom();
 907    }
 908
 909    /// Updates the window's title at the platform level.
 910    pub fn set_window_title(&mut self, title: &str) {
 911        self.window.platform_window.set_title(title);
 912    }
 913
 914    /// Mark the window as dirty at the platform level.
 915    pub fn set_window_edited(&mut self, edited: bool) {
 916        self.window.platform_window.set_edited(edited);
 917    }
 918
 919    /// Determine the display on which the window is visible.
 920    pub fn display(&self) -> Option<Rc<dyn PlatformDisplay>> {
 921        self.platform
 922            .displays()
 923            .into_iter()
 924            .find(|display| display.id() == self.window.display_id)
 925    }
 926
 927    /// Show the platform character palette.
 928    pub fn show_character_palette(&self) {
 929        self.window.platform_window.show_character_palette();
 930    }
 931
 932    /// The scale factor of the display associated with the window. For example, it could
 933    /// return 2.0 for a "retina" display, indicating that each logical pixel should actually
 934    /// be rendered as two pixels on screen.
 935    pub fn scale_factor(&self) -> f32 {
 936        self.window.scale_factor
 937    }
 938
 939    /// The size of an em for the base font of the application. Adjusting this value allows the
 940    /// UI to scale, just like zooming a web page.
 941    pub fn rem_size(&self) -> Pixels {
 942        self.window.rem_size
 943    }
 944
 945    /// Sets the size of an em for the base font of the application. Adjusting this value allows the
 946    /// UI to scale, just like zooming a web page.
 947    pub fn set_rem_size(&mut self, rem_size: impl Into<Pixels>) {
 948        self.window.rem_size = rem_size.into();
 949    }
 950
 951    /// The line height associated with the current text style.
 952    pub fn line_height(&self) -> Pixels {
 953        let rem_size = self.rem_size();
 954        let text_style = self.text_style();
 955        text_style
 956            .line_height
 957            .to_pixels(text_style.font_size, rem_size)
 958    }
 959
 960    /// Call to prevent the default action of an event. Currently only used to prevent
 961    /// parent elements from becoming focused on mouse down.
 962    pub fn prevent_default(&mut self) {
 963        self.window.default_prevented = true;
 964    }
 965
 966    /// Obtain whether default has been prevented for the event currently being dispatched.
 967    pub fn default_prevented(&self) -> bool {
 968        self.window.default_prevented
 969    }
 970
 971    /// Determine whether the given action is available along the dispatch path to the currently focused element.
 972    pub fn is_action_available(&self, action: &dyn Action) -> bool {
 973        let target = self
 974            .focused()
 975            .and_then(|focused_handle| {
 976                self.window
 977                    .rendered_frame
 978                    .dispatch_tree
 979                    .focusable_node_id(focused_handle.id)
 980            })
 981            .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
 982        self.window
 983            .rendered_frame
 984            .dispatch_tree
 985            .is_action_available(action, target)
 986    }
 987
 988    /// The position of the mouse relative to the window.
 989    pub fn mouse_position(&self) -> Point<Pixels> {
 990        self.window.mouse_position
 991    }
 992
 993    /// The current state of the keyboard's modifiers
 994    pub fn modifiers(&self) -> Modifiers {
 995        self.window.modifiers
 996    }
 997
 998    /// Produces a new frame and assigns it to `rendered_frame`. To actually show
 999    /// the contents of the new [Scene], use [present].
1000    #[profiling::function]
1001    pub fn draw(&mut self) {
1002        self.window.dirty.set(false);
1003
1004        // Restore the previously-used input handler.
1005        if let Some(input_handler) = self.window.platform_window.take_input_handler() {
1006            self.window
1007                .rendered_frame
1008                .input_handlers
1009                .push(Some(input_handler));
1010        }
1011
1012        self.with_element_context(|cx| cx.draw_roots());
1013        self.window.dirty_views.clear();
1014
1015        self.window
1016            .next_frame
1017            .dispatch_tree
1018            .preserve_pending_keystrokes(
1019                &mut self.window.rendered_frame.dispatch_tree,
1020                self.window.focus,
1021            );
1022        self.window.next_frame.focus = self.window.focus;
1023        self.window.next_frame.window_active = self.window.active.get();
1024
1025        // Register requested input handler with the platform window.
1026        if let Some(input_handler) = self.window.next_frame.input_handlers.pop() {
1027            self.window
1028                .platform_window
1029                .set_input_handler(input_handler.unwrap());
1030        }
1031
1032        self.window.layout_engine.as_mut().unwrap().clear();
1033        self.text_system().finish_frame();
1034        self.window
1035            .next_frame
1036            .finish(&mut self.window.rendered_frame);
1037        ELEMENT_ARENA.with_borrow_mut(|element_arena| {
1038            let percentage = (element_arena.len() as f32 / element_arena.capacity() as f32) * 100.;
1039            if percentage >= 80. {
1040                log::warn!("elevated element arena occupation: {}.", percentage);
1041            }
1042            element_arena.clear();
1043        });
1044
1045        self.window.draw_phase = DrawPhase::Focus;
1046        let previous_focus_path = self.window.rendered_frame.focus_path();
1047        let previous_window_active = self.window.rendered_frame.window_active;
1048        mem::swap(&mut self.window.rendered_frame, &mut self.window.next_frame);
1049        self.window.next_frame.clear();
1050        let current_focus_path = self.window.rendered_frame.focus_path();
1051        let current_window_active = self.window.rendered_frame.window_active;
1052
1053        if previous_focus_path != current_focus_path
1054            || previous_window_active != current_window_active
1055        {
1056            if !previous_focus_path.is_empty() && current_focus_path.is_empty() {
1057                self.window
1058                    .focus_lost_listeners
1059                    .clone()
1060                    .retain(&(), |listener| listener(self));
1061            }
1062
1063            let event = FocusEvent {
1064                previous_focus_path: if previous_window_active {
1065                    previous_focus_path
1066                } else {
1067                    Default::default()
1068                },
1069                current_focus_path: if current_window_active {
1070                    current_focus_path
1071                } else {
1072                    Default::default()
1073                },
1074            };
1075            self.window
1076                .focus_listeners
1077                .clone()
1078                .retain(&(), |listener| listener(&event, self));
1079        }
1080
1081        self.reset_cursor_style();
1082        self.window.refreshing = false;
1083        self.window.draw_phase = DrawPhase::None;
1084        self.window.needs_present.set(true);
1085    }
1086
1087    #[profiling::function]
1088    fn present(&self) {
1089        self.window
1090            .platform_window
1091            .draw(&self.window.rendered_frame.scene);
1092        self.window.needs_present.set(false);
1093        profiling::finish_frame!();
1094    }
1095
1096    fn reset_cursor_style(&self) {
1097        // Set the cursor only if we're the active window.
1098        if self.is_window_active() {
1099            let style = self
1100                .window
1101                .rendered_frame
1102                .cursor_styles
1103                .iter()
1104                .rev()
1105                .find(|request| request.hitbox_id.is_hovered(self))
1106                .map(|request| request.style)
1107                .unwrap_or(CursorStyle::Arrow);
1108            self.platform.set_cursor_style(style);
1109        }
1110    }
1111
1112    /// Dispatch a given keystroke as though the user had typed it.
1113    /// You can create a keystroke with Keystroke::parse("").
1114    pub fn dispatch_keystroke(&mut self, keystroke: Keystroke) -> bool {
1115        let keystroke = keystroke.with_simulated_ime();
1116        let result = self.dispatch_event(PlatformInput::KeyDown(KeyDownEvent {
1117            keystroke: keystroke.clone(),
1118            is_held: false,
1119        }));
1120        if !result.propagate {
1121            return true;
1122        }
1123
1124        if let Some(input) = keystroke.ime_key {
1125            if let Some(mut input_handler) = self.window.platform_window.take_input_handler() {
1126                input_handler.dispatch_input(&input, self);
1127                self.window.platform_window.set_input_handler(input_handler);
1128                return true;
1129            }
1130        }
1131
1132        false
1133    }
1134
1135    /// Represent this action as a key binding string, to display in the UI.
1136    pub fn keystroke_text_for(&self, action: &dyn Action) -> String {
1137        self.bindings_for_action(action)
1138            .into_iter()
1139            .next()
1140            .map(|binding| {
1141                binding
1142                    .keystrokes()
1143                    .iter()
1144                    .map(ToString::to_string)
1145                    .collect::<Vec<_>>()
1146                    .join(" ")
1147            })
1148            .unwrap_or_else(|| action.name().to_string())
1149    }
1150
1151    /// Dispatch a mouse or keyboard event on the window.
1152    #[profiling::function]
1153    pub fn dispatch_event(&mut self, event: PlatformInput) -> DispatchEventResult {
1154        self.window.last_input_timestamp.set(Instant::now());
1155        // Handlers may set this to false by calling `stop_propagation`.
1156        self.app.propagate_event = true;
1157        // Handlers may set this to true by calling `prevent_default`.
1158        self.window.default_prevented = false;
1159
1160        let event = match event {
1161            // Track the mouse position with our own state, since accessing the platform
1162            // API for the mouse position can only occur on the main thread.
1163            PlatformInput::MouseMove(mouse_move) => {
1164                self.window.mouse_position = mouse_move.position;
1165                self.window.modifiers = mouse_move.modifiers;
1166                PlatformInput::MouseMove(mouse_move)
1167            }
1168            PlatformInput::MouseDown(mouse_down) => {
1169                self.window.mouse_position = mouse_down.position;
1170                self.window.modifiers = mouse_down.modifiers;
1171                PlatformInput::MouseDown(mouse_down)
1172            }
1173            PlatformInput::MouseUp(mouse_up) => {
1174                self.window.mouse_position = mouse_up.position;
1175                self.window.modifiers = mouse_up.modifiers;
1176                PlatformInput::MouseUp(mouse_up)
1177            }
1178            PlatformInput::MouseExited(mouse_exited) => {
1179                self.window.modifiers = mouse_exited.modifiers;
1180                PlatformInput::MouseExited(mouse_exited)
1181            }
1182            PlatformInput::ModifiersChanged(modifiers_changed) => {
1183                self.window.modifiers = modifiers_changed.modifiers;
1184                PlatformInput::ModifiersChanged(modifiers_changed)
1185            }
1186            PlatformInput::ScrollWheel(scroll_wheel) => {
1187                self.window.mouse_position = scroll_wheel.position;
1188                self.window.modifiers = scroll_wheel.modifiers;
1189                PlatformInput::ScrollWheel(scroll_wheel)
1190            }
1191            // Translate dragging and dropping of external files from the operating system
1192            // to internal drag and drop events.
1193            PlatformInput::FileDrop(file_drop) => match file_drop {
1194                FileDropEvent::Entered { position, paths } => {
1195                    self.window.mouse_position = position;
1196                    if self.active_drag.is_none() {
1197                        self.active_drag = Some(AnyDrag {
1198                            value: Box::new(paths.clone()),
1199                            view: self.new_view(|_| paths).into(),
1200                            cursor_offset: position,
1201                        });
1202                    }
1203                    PlatformInput::MouseMove(MouseMoveEvent {
1204                        position,
1205                        pressed_button: Some(MouseButton::Left),
1206                        modifiers: Modifiers::default(),
1207                    })
1208                }
1209                FileDropEvent::Pending { position } => {
1210                    self.window.mouse_position = position;
1211                    PlatformInput::MouseMove(MouseMoveEvent {
1212                        position,
1213                        pressed_button: Some(MouseButton::Left),
1214                        modifiers: Modifiers::default(),
1215                    })
1216                }
1217                FileDropEvent::Submit { position } => {
1218                    self.activate(true);
1219                    self.window.mouse_position = position;
1220                    PlatformInput::MouseUp(MouseUpEvent {
1221                        button: MouseButton::Left,
1222                        position,
1223                        modifiers: Modifiers::default(),
1224                        click_count: 1,
1225                    })
1226                }
1227                FileDropEvent::Exited => {
1228                    self.active_drag.take();
1229                    PlatformInput::FileDrop(FileDropEvent::Exited)
1230                }
1231            },
1232            PlatformInput::KeyDown(_) | PlatformInput::KeyUp(_) => event,
1233        };
1234
1235        if let Some(any_mouse_event) = event.mouse_event() {
1236            self.dispatch_mouse_event(any_mouse_event);
1237        } else if let Some(any_key_event) = event.keyboard_event() {
1238            self.dispatch_key_event(any_key_event);
1239        }
1240
1241        DispatchEventResult {
1242            propagate: self.app.propagate_event,
1243            default_prevented: self.window.default_prevented,
1244        }
1245    }
1246
1247    fn dispatch_mouse_event(&mut self, event: &dyn Any) {
1248        let hit_test = self.window.rendered_frame.hit_test(self.mouse_position());
1249        if hit_test != self.window.mouse_hit_test {
1250            self.window.mouse_hit_test = hit_test;
1251            self.reset_cursor_style();
1252        }
1253
1254        let mut mouse_listeners = mem::take(&mut self.window.rendered_frame.mouse_listeners);
1255        self.with_element_context(|cx| {
1256            // Capture phase, events bubble from back to front. Handlers for this phase are used for
1257            // special purposes, such as detecting events outside of a given Bounds.
1258            for listener in &mut mouse_listeners {
1259                let listener = listener.as_mut().unwrap();
1260                listener(event, DispatchPhase::Capture, cx);
1261                if !cx.app.propagate_event {
1262                    break;
1263                }
1264            }
1265
1266            // Bubble phase, where most normal handlers do their work.
1267            if cx.app.propagate_event {
1268                for listener in mouse_listeners.iter_mut().rev() {
1269                    let listener = listener.as_mut().unwrap();
1270                    listener(event, DispatchPhase::Bubble, cx);
1271                    if !cx.app.propagate_event {
1272                        break;
1273                    }
1274                }
1275            }
1276        });
1277        self.window.rendered_frame.mouse_listeners = mouse_listeners;
1278
1279        if self.app.propagate_event && self.has_active_drag() {
1280            if event.is::<MouseMoveEvent>() {
1281                // If this was a mouse move event, redraw the window so that the
1282                // active drag can follow the mouse cursor.
1283                self.refresh();
1284            } else if event.is::<MouseUpEvent>() {
1285                // If this was a mouse up event, cancel the active drag and redraw
1286                // the window.
1287                self.active_drag = None;
1288                self.refresh();
1289            }
1290        }
1291    }
1292
1293    fn dispatch_key_event(&mut self, event: &dyn Any) {
1294        if self.window.dirty.get() {
1295            self.draw();
1296        }
1297
1298        let node_id = self
1299            .window
1300            .focus
1301            .and_then(|focus_id| {
1302                self.window
1303                    .rendered_frame
1304                    .dispatch_tree
1305                    .focusable_node_id(focus_id)
1306            })
1307            .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
1308
1309        let dispatch_path = self
1310            .window
1311            .rendered_frame
1312            .dispatch_tree
1313            .dispatch_path(node_id);
1314
1315        if let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() {
1316            let KeymatchResult { bindings, pending } = self
1317                .window
1318                .rendered_frame
1319                .dispatch_tree
1320                .dispatch_key(&key_down_event.keystroke, &dispatch_path);
1321
1322            if pending {
1323                let mut currently_pending = self.window.pending_input.take().unwrap_or_default();
1324                if currently_pending.focus.is_some() && currently_pending.focus != self.window.focus
1325                {
1326                    currently_pending = PendingInput::default();
1327                }
1328                currently_pending.focus = self.window.focus;
1329                currently_pending
1330                    .keystrokes
1331                    .push(key_down_event.keystroke.clone());
1332                for binding in bindings {
1333                    currently_pending.bindings.push(binding);
1334                }
1335
1336                currently_pending.timer = Some(self.spawn(|mut cx| async move {
1337                    cx.background_executor.timer(Duration::from_secs(1)).await;
1338                    cx.update(move |cx| {
1339                        cx.clear_pending_keystrokes();
1340                        let Some(currently_pending) = cx.window.pending_input.take() else {
1341                            return;
1342                        };
1343                        cx.replay_pending_input(currently_pending)
1344                    })
1345                    .log_err();
1346                }));
1347
1348                self.window.pending_input = Some(currently_pending);
1349
1350                self.propagate_event = false;
1351                return;
1352            } else if let Some(currently_pending) = self.window.pending_input.take() {
1353                if bindings
1354                    .iter()
1355                    .all(|binding| !currently_pending.used_by_binding(binding))
1356                {
1357                    self.replay_pending_input(currently_pending)
1358                }
1359            }
1360
1361            if !bindings.is_empty() {
1362                self.clear_pending_keystrokes();
1363            }
1364
1365            self.propagate_event = true;
1366            for binding in bindings {
1367                self.dispatch_action_on_node(node_id, binding.action.as_ref());
1368                if !self.propagate_event {
1369                    self.dispatch_keystroke_observers(event, Some(binding.action));
1370                    return;
1371                }
1372            }
1373        }
1374
1375        self.dispatch_key_down_up_event(event, &dispatch_path);
1376        if !self.propagate_event {
1377            return;
1378        }
1379
1380        self.dispatch_modifiers_changed_event(event, &dispatch_path);
1381        if !self.propagate_event {
1382            return;
1383        }
1384
1385        self.dispatch_keystroke_observers(event, None);
1386    }
1387
1388    fn dispatch_key_down_up_event(
1389        &mut self,
1390        event: &dyn Any,
1391        dispatch_path: &SmallVec<[DispatchNodeId; 32]>,
1392    ) {
1393        // Capture phase
1394        for node_id in dispatch_path {
1395            let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1396
1397            for key_listener in node.key_listeners.clone() {
1398                self.with_element_context(|cx| {
1399                    key_listener(event, DispatchPhase::Capture, cx);
1400                });
1401                if !self.propagate_event {
1402                    return;
1403                }
1404            }
1405        }
1406
1407        // Bubble phase
1408        for node_id in dispatch_path.iter().rev() {
1409            // Handle low level key events
1410            let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1411            for key_listener in node.key_listeners.clone() {
1412                self.with_element_context(|cx| {
1413                    key_listener(event, DispatchPhase::Bubble, cx);
1414                });
1415                if !self.propagate_event {
1416                    return;
1417                }
1418            }
1419        }
1420    }
1421
1422    fn dispatch_modifiers_changed_event(
1423        &mut self,
1424        event: &dyn Any,
1425        dispatch_path: &SmallVec<[DispatchNodeId; 32]>,
1426    ) {
1427        let Some(event) = event.downcast_ref::<ModifiersChangedEvent>() else {
1428            return;
1429        };
1430        for node_id in dispatch_path.iter().rev() {
1431            let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1432            for listener in node.modifiers_changed_listeners.clone() {
1433                self.with_element_context(|cx| {
1434                    listener(event, cx);
1435                });
1436                if !self.propagate_event {
1437                    return;
1438                }
1439            }
1440        }
1441    }
1442
1443    /// Determine whether a potential multi-stroke key binding is in progress on this window.
1444    pub fn has_pending_keystrokes(&self) -> bool {
1445        self.window
1446            .rendered_frame
1447            .dispatch_tree
1448            .has_pending_keystrokes()
1449    }
1450
1451    fn replay_pending_input(&mut self, currently_pending: PendingInput) {
1452        let node_id = self
1453            .window
1454            .focus
1455            .and_then(|focus_id| {
1456                self.window
1457                    .rendered_frame
1458                    .dispatch_tree
1459                    .focusable_node_id(focus_id)
1460            })
1461            .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
1462
1463        if self.window.focus != currently_pending.focus {
1464            return;
1465        }
1466
1467        let input = currently_pending.input();
1468
1469        self.propagate_event = true;
1470        for binding in currently_pending.bindings {
1471            self.dispatch_action_on_node(node_id, binding.action.as_ref());
1472            if !self.propagate_event {
1473                return;
1474            }
1475        }
1476
1477        let dispatch_path = self
1478            .window
1479            .rendered_frame
1480            .dispatch_tree
1481            .dispatch_path(node_id);
1482
1483        for keystroke in currently_pending.keystrokes {
1484            let event = KeyDownEvent {
1485                keystroke,
1486                is_held: false,
1487            };
1488
1489            self.dispatch_key_down_up_event(&event, &dispatch_path);
1490            if !self.propagate_event {
1491                return;
1492            }
1493        }
1494
1495        if !input.is_empty() {
1496            if let Some(mut input_handler) = self.window.platform_window.take_input_handler() {
1497                input_handler.dispatch_input(&input, self);
1498                self.window.platform_window.set_input_handler(input_handler)
1499            }
1500        }
1501    }
1502
1503    fn dispatch_action_on_node(&mut self, node_id: DispatchNodeId, action: &dyn Action) {
1504        let dispatch_path = self
1505            .window
1506            .rendered_frame
1507            .dispatch_tree
1508            .dispatch_path(node_id);
1509
1510        // Capture phase for global actions.
1511        self.propagate_event = true;
1512        if let Some(mut global_listeners) = self
1513            .global_action_listeners
1514            .remove(&action.as_any().type_id())
1515        {
1516            for listener in &global_listeners {
1517                listener(action.as_any(), DispatchPhase::Capture, self);
1518                if !self.propagate_event {
1519                    break;
1520                }
1521            }
1522
1523            global_listeners.extend(
1524                self.global_action_listeners
1525                    .remove(&action.as_any().type_id())
1526                    .unwrap_or_default(),
1527            );
1528
1529            self.global_action_listeners
1530                .insert(action.as_any().type_id(), global_listeners);
1531        }
1532
1533        if !self.propagate_event {
1534            return;
1535        }
1536
1537        // Capture phase for window actions.
1538        for node_id in &dispatch_path {
1539            let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1540            for DispatchActionListener {
1541                action_type,
1542                listener,
1543            } in node.action_listeners.clone()
1544            {
1545                let any_action = action.as_any();
1546                if action_type == any_action.type_id() {
1547                    self.with_element_context(|cx| {
1548                        listener(any_action, DispatchPhase::Capture, cx);
1549                    });
1550
1551                    if !self.propagate_event {
1552                        return;
1553                    }
1554                }
1555            }
1556        }
1557
1558        // Bubble phase for window actions.
1559        for node_id in dispatch_path.iter().rev() {
1560            let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1561            for DispatchActionListener {
1562                action_type,
1563                listener,
1564            } in node.action_listeners.clone()
1565            {
1566                let any_action = action.as_any();
1567                if action_type == any_action.type_id() {
1568                    self.propagate_event = false; // Actions stop propagation by default during the bubble phase
1569
1570                    self.with_element_context(|cx| {
1571                        listener(any_action, DispatchPhase::Bubble, cx);
1572                    });
1573
1574                    if !self.propagate_event {
1575                        return;
1576                    }
1577                }
1578            }
1579        }
1580
1581        // Bubble phase for global actions.
1582        if let Some(mut global_listeners) = self
1583            .global_action_listeners
1584            .remove(&action.as_any().type_id())
1585        {
1586            for listener in global_listeners.iter().rev() {
1587                self.propagate_event = false; // Actions stop propagation by default during the bubble phase
1588
1589                listener(action.as_any(), DispatchPhase::Bubble, self);
1590                if !self.propagate_event {
1591                    break;
1592                }
1593            }
1594
1595            global_listeners.extend(
1596                self.global_action_listeners
1597                    .remove(&action.as_any().type_id())
1598                    .unwrap_or_default(),
1599            );
1600
1601            self.global_action_listeners
1602                .insert(action.as_any().type_id(), global_listeners);
1603        }
1604    }
1605
1606    /// Register the given handler to be invoked whenever the global of the given type
1607    /// is updated.
1608    pub fn observe_global<G: Global>(
1609        &mut self,
1610        f: impl Fn(&mut WindowContext<'_>) + 'static,
1611    ) -> Subscription {
1612        let window_handle = self.window.handle;
1613        let (subscription, activate) = self.global_observers.insert(
1614            TypeId::of::<G>(),
1615            Box::new(move |cx| window_handle.update(cx, |_, cx| f(cx)).is_ok()),
1616        );
1617        self.app.defer(move |_| activate());
1618        subscription
1619    }
1620
1621    /// Focus the current window and bring it to the foreground at the platform level.
1622    pub fn activate_window(&self) {
1623        self.window.platform_window.activate();
1624    }
1625
1626    /// Minimize the current window at the platform level.
1627    pub fn minimize_window(&self) {
1628        self.window.platform_window.minimize();
1629    }
1630
1631    /// Toggle full screen status on the current window at the platform level.
1632    pub fn toggle_fullscreen(&self) {
1633        self.window.platform_window.toggle_fullscreen();
1634    }
1635
1636    /// Present a platform dialog.
1637    /// The provided message will be presented, along with buttons for each answer.
1638    /// When a button is clicked, the returned Receiver will receive the index of the clicked button.
1639    pub fn prompt(
1640        &mut self,
1641        level: PromptLevel,
1642        message: &str,
1643        detail: Option<&str>,
1644        answers: &[&str],
1645    ) -> oneshot::Receiver<usize> {
1646        let prompt_builder = self.app.prompt_builder.take();
1647        let Some(prompt_builder) = prompt_builder else {
1648            unreachable!("Re-entrant window prompting is not supported by GPUI");
1649        };
1650
1651        let receiver = match &prompt_builder {
1652            PromptBuilder::Default => self
1653                .window
1654                .platform_window
1655                .prompt(level, message, detail, answers)
1656                .unwrap_or_else(|| {
1657                    self.build_custom_prompt(&prompt_builder, level, message, detail, answers)
1658                }),
1659            PromptBuilder::Custom(_) => {
1660                self.build_custom_prompt(&prompt_builder, level, message, detail, answers)
1661            }
1662        };
1663
1664        self.app.prompt_builder = Some(prompt_builder);
1665
1666        receiver
1667    }
1668
1669    fn build_custom_prompt(
1670        &mut self,
1671        prompt_builder: &PromptBuilder,
1672        level: PromptLevel,
1673        message: &str,
1674        detail: Option<&str>,
1675        answers: &[&str],
1676    ) -> oneshot::Receiver<usize> {
1677        let (sender, receiver) = oneshot::channel();
1678        let handle = PromptHandle::new(sender);
1679        let handle = (prompt_builder)(level, message, detail, answers, handle, self);
1680        self.window.prompt = Some(handle);
1681        receiver
1682    }
1683
1684    /// Returns all available actions for the focused element.
1685    pub fn available_actions(&self) -> Vec<Box<dyn Action>> {
1686        let node_id = self
1687            .window
1688            .focus
1689            .and_then(|focus_id| {
1690                self.window
1691                    .rendered_frame
1692                    .dispatch_tree
1693                    .focusable_node_id(focus_id)
1694            })
1695            .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
1696
1697        let mut actions = self
1698            .window
1699            .rendered_frame
1700            .dispatch_tree
1701            .available_actions(node_id);
1702        for action_type in self.global_action_listeners.keys() {
1703            if let Err(ix) = actions.binary_search_by_key(action_type, |a| a.as_any().type_id()) {
1704                let action = self.actions.build_action_type(action_type).ok();
1705                if let Some(action) = action {
1706                    actions.insert(ix, action);
1707                }
1708            }
1709        }
1710        actions
1711    }
1712
1713    /// Returns key bindings that invoke the given action on the currently focused element.
1714    pub fn bindings_for_action(&self, action: &dyn Action) -> Vec<KeyBinding> {
1715        self.window
1716            .rendered_frame
1717            .dispatch_tree
1718            .bindings_for_action(
1719                action,
1720                &self.window.rendered_frame.dispatch_tree.context_stack,
1721            )
1722    }
1723
1724    /// Returns any bindings that would invoke the given action on the given focus handle if it were focused.
1725    pub fn bindings_for_action_in(
1726        &self,
1727        action: &dyn Action,
1728        focus_handle: &FocusHandle,
1729    ) -> Vec<KeyBinding> {
1730        let dispatch_tree = &self.window.rendered_frame.dispatch_tree;
1731
1732        let Some(node_id) = dispatch_tree.focusable_node_id(focus_handle.id) else {
1733            return vec![];
1734        };
1735        let context_stack: Vec<_> = dispatch_tree
1736            .dispatch_path(node_id)
1737            .into_iter()
1738            .filter_map(|node_id| dispatch_tree.node(node_id).context.clone())
1739            .collect();
1740        dispatch_tree.bindings_for_action(action, &context_stack)
1741    }
1742
1743    /// Returns a generic event listener that invokes the given listener with the view and context associated with the given view handle.
1744    pub fn listener_for<V: Render, E>(
1745        &self,
1746        view: &View<V>,
1747        f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
1748    ) -> impl Fn(&E, &mut WindowContext) + 'static {
1749        let view = view.downgrade();
1750        move |e: &E, cx: &mut WindowContext| {
1751            view.update(cx, |view, cx| f(view, e, cx)).ok();
1752        }
1753    }
1754
1755    /// Returns a generic handler that invokes the given handler with the view and context associated with the given view handle.
1756    pub fn handler_for<V: Render>(
1757        &self,
1758        view: &View<V>,
1759        f: impl Fn(&mut V, &mut ViewContext<V>) + 'static,
1760    ) -> impl Fn(&mut WindowContext) {
1761        let view = view.downgrade();
1762        move |cx: &mut WindowContext| {
1763            view.update(cx, |view, cx| f(view, cx)).ok();
1764        }
1765    }
1766
1767    /// Register a callback that can interrupt the closing of the current window based the returned boolean.
1768    /// If the callback returns false, the window won't be closed.
1769    pub fn on_window_should_close(&mut self, f: impl Fn(&mut WindowContext) -> bool + 'static) {
1770        let mut this = self.to_async();
1771        self.window
1772            .platform_window
1773            .on_should_close(Box::new(move || this.update(|cx| f(cx)).unwrap_or(true)))
1774    }
1775
1776    /// Register an action listener on the window for the next frame. The type of action
1777    /// is determined by the first parameter of the given listener. When the next frame is rendered
1778    /// the listener will be cleared.
1779    ///
1780    /// This is a fairly low-level method, so prefer using action handlers on elements unless you have
1781    /// a specific need to register a global listener.
1782    pub fn on_action(
1783        &mut self,
1784        action_type: TypeId,
1785        listener: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static,
1786    ) {
1787        self.window
1788            .next_frame
1789            .dispatch_tree
1790            .on_action(action_type, Rc::new(listener));
1791    }
1792}
1793
1794#[cfg(target_os = "windows")]
1795impl WindowContext<'_> {
1796    /// Returns the raw HWND handle for the window.
1797    pub fn get_raw_handle(&self) -> windows::Win32::Foundation::HWND {
1798        self.window.platform_window.get_raw_handle()
1799    }
1800}
1801
1802impl Context for WindowContext<'_> {
1803    type Result<T> = T;
1804
1805    fn new_model<T>(&mut self, build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T) -> Model<T>
1806    where
1807        T: 'static,
1808    {
1809        let slot = self.app.entities.reserve();
1810        let model = build_model(&mut ModelContext::new(&mut *self.app, slot.downgrade()));
1811        self.entities.insert(slot, model)
1812    }
1813
1814    fn update_model<T: 'static, R>(
1815        &mut self,
1816        model: &Model<T>,
1817        update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
1818    ) -> R {
1819        let mut entity = self.entities.lease(model);
1820        let result = update(
1821            &mut *entity,
1822            &mut ModelContext::new(&mut *self.app, model.downgrade()),
1823        );
1824        self.entities.end_lease(entity);
1825        result
1826    }
1827
1828    fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
1829    where
1830        F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
1831    {
1832        if window == self.window.handle {
1833            let root_view = self.window.root_view.clone().unwrap();
1834            Ok(update(root_view, self))
1835        } else {
1836            window.update(self.app, update)
1837        }
1838    }
1839
1840    fn read_model<T, R>(
1841        &self,
1842        handle: &Model<T>,
1843        read: impl FnOnce(&T, &AppContext) -> R,
1844    ) -> Self::Result<R>
1845    where
1846        T: 'static,
1847    {
1848        let entity = self.entities.read(handle);
1849        read(entity, &*self.app)
1850    }
1851
1852    fn read_window<T, R>(
1853        &self,
1854        window: &WindowHandle<T>,
1855        read: impl FnOnce(View<T>, &AppContext) -> R,
1856    ) -> Result<R>
1857    where
1858        T: 'static,
1859    {
1860        if window.any_handle == self.window.handle {
1861            let root_view = self
1862                .window
1863                .root_view
1864                .clone()
1865                .unwrap()
1866                .downcast::<T>()
1867                .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
1868            Ok(read(root_view, self))
1869        } else {
1870            self.app.read_window(window, read)
1871        }
1872    }
1873}
1874
1875impl VisualContext for WindowContext<'_> {
1876    fn new_view<V>(
1877        &mut self,
1878        build_view_state: impl FnOnce(&mut ViewContext<'_, V>) -> V,
1879    ) -> Self::Result<View<V>>
1880    where
1881        V: 'static + Render,
1882    {
1883        let slot = self.app.entities.reserve();
1884        let view = View {
1885            model: slot.clone(),
1886        };
1887        let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view);
1888        let entity = build_view_state(&mut cx);
1889        cx.entities.insert(slot, entity);
1890
1891        // Non-generic part to avoid leaking SubscriberSet to invokers of `new_view`.
1892        fn notify_observers(cx: &mut WindowContext, tid: TypeId, view: AnyView) {
1893            cx.new_view_observers.clone().retain(&tid, |observer| {
1894                let any_view = view.clone();
1895                (observer)(any_view, cx);
1896                true
1897            });
1898        }
1899        notify_observers(self, TypeId::of::<V>(), AnyView::from(view.clone()));
1900
1901        view
1902    }
1903
1904    /// Updates the given view. Prefer calling [`View::update`] instead, which calls this method.
1905    fn update_view<T: 'static, R>(
1906        &mut self,
1907        view: &View<T>,
1908        update: impl FnOnce(&mut T, &mut ViewContext<'_, T>) -> R,
1909    ) -> Self::Result<R> {
1910        let mut lease = self.app.entities.lease(&view.model);
1911        let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, view);
1912        let result = update(&mut *lease, &mut cx);
1913        cx.app.entities.end_lease(lease);
1914        result
1915    }
1916
1917    fn replace_root_view<V>(
1918        &mut self,
1919        build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V,
1920    ) -> Self::Result<View<V>>
1921    where
1922        V: 'static + Render,
1923    {
1924        let view = self.new_view(build_view);
1925        self.window.root_view = Some(view.clone().into());
1926        self.refresh();
1927        view
1928    }
1929
1930    fn focus_view<V: crate::FocusableView>(&mut self, view: &View<V>) -> Self::Result<()> {
1931        self.update_view(view, |view, cx| {
1932            view.focus_handle(cx).clone().focus(cx);
1933        })
1934    }
1935
1936    fn dismiss_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
1937    where
1938        V: ManagedView,
1939    {
1940        self.update_view(view, |_, cx| cx.emit(DismissEvent))
1941    }
1942}
1943
1944impl<'a> std::ops::Deref for WindowContext<'a> {
1945    type Target = AppContext;
1946
1947    fn deref(&self) -> &Self::Target {
1948        self.app
1949    }
1950}
1951
1952impl<'a> std::ops::DerefMut for WindowContext<'a> {
1953    fn deref_mut(&mut self) -> &mut Self::Target {
1954        self.app
1955    }
1956}
1957
1958impl<'a> Borrow<AppContext> for WindowContext<'a> {
1959    fn borrow(&self) -> &AppContext {
1960        self.app
1961    }
1962}
1963
1964impl<'a> BorrowMut<AppContext> for WindowContext<'a> {
1965    fn borrow_mut(&mut self) -> &mut AppContext {
1966        self.app
1967    }
1968}
1969
1970/// This trait contains functionality that is shared across [`ViewContext`] and [`WindowContext`]
1971pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
1972    #[doc(hidden)]
1973    fn app_mut(&mut self) -> &mut AppContext {
1974        self.borrow_mut()
1975    }
1976
1977    #[doc(hidden)]
1978    fn app(&self) -> &AppContext {
1979        self.borrow()
1980    }
1981
1982    #[doc(hidden)]
1983    fn window(&self) -> &Window {
1984        self.borrow()
1985    }
1986
1987    #[doc(hidden)]
1988    fn window_mut(&mut self) -> &mut Window {
1989        self.borrow_mut()
1990    }
1991}
1992
1993impl Borrow<Window> for WindowContext<'_> {
1994    fn borrow(&self) -> &Window {
1995        self.window
1996    }
1997}
1998
1999impl BorrowMut<Window> for WindowContext<'_> {
2000    fn borrow_mut(&mut self) -> &mut Window {
2001        self.window
2002    }
2003}
2004
2005impl<T> BorrowWindow for T where T: BorrowMut<AppContext> + BorrowMut<Window> {}
2006
2007/// Provides access to application state that is specialized for a particular [`View`].
2008/// Allows you to interact with focus, emit events, etc.
2009/// ViewContext also derefs to [`WindowContext`], giving you access to all of its methods as well.
2010/// When you call [`View::update`], you're passed a `&mut V` and an `&mut ViewContext<V>`.
2011pub struct ViewContext<'a, V> {
2012    window_cx: WindowContext<'a>,
2013    view: &'a View<V>,
2014}
2015
2016impl<V> Borrow<AppContext> for ViewContext<'_, V> {
2017    fn borrow(&self) -> &AppContext {
2018        &*self.window_cx.app
2019    }
2020}
2021
2022impl<V> BorrowMut<AppContext> for ViewContext<'_, V> {
2023    fn borrow_mut(&mut self) -> &mut AppContext {
2024        &mut *self.window_cx.app
2025    }
2026}
2027
2028impl<V> Borrow<Window> for ViewContext<'_, V> {
2029    fn borrow(&self) -> &Window {
2030        &*self.window_cx.window
2031    }
2032}
2033
2034impl<V> BorrowMut<Window> for ViewContext<'_, V> {
2035    fn borrow_mut(&mut self) -> &mut Window {
2036        &mut *self.window_cx.window
2037    }
2038}
2039
2040impl<'a, V: 'static> ViewContext<'a, V> {
2041    pub(crate) fn new(app: &'a mut AppContext, window: &'a mut Window, view: &'a View<V>) -> Self {
2042        Self {
2043            window_cx: WindowContext::new(app, window),
2044            view,
2045        }
2046    }
2047
2048    /// Get the entity_id of this view.
2049    pub fn entity_id(&self) -> EntityId {
2050        self.view.entity_id()
2051    }
2052
2053    /// Get the view pointer underlying this context.
2054    pub fn view(&self) -> &View<V> {
2055        self.view
2056    }
2057
2058    /// Get the model underlying this view.
2059    pub fn model(&self) -> &Model<V> {
2060        &self.view.model
2061    }
2062
2063    /// Access the underlying window context.
2064    pub fn window_context(&mut self) -> &mut WindowContext<'a> {
2065        &mut self.window_cx
2066    }
2067
2068    /// Sets a given callback to be run on the next frame.
2069    pub fn on_next_frame(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + 'static)
2070    where
2071        V: 'static,
2072    {
2073        let view = self.view().clone();
2074        self.window_cx.on_next_frame(move |cx| view.update(cx, f));
2075    }
2076
2077    /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
2078    /// that are currently on the stack to be returned to the app.
2079    pub fn defer(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + 'static) {
2080        let view = self.view().downgrade();
2081        self.window_cx.defer(move |cx| {
2082            view.update(cx, f).ok();
2083        });
2084    }
2085
2086    /// Observe another model or view for changes to its state, as tracked by [`ModelContext::notify`].
2087    pub fn observe<V2, E>(
2088        &mut self,
2089        entity: &E,
2090        mut on_notify: impl FnMut(&mut V, E, &mut ViewContext<'_, V>) + 'static,
2091    ) -> Subscription
2092    where
2093        V2: 'static,
2094        V: 'static,
2095        E: Entity<V2>,
2096    {
2097        let view = self.view().downgrade();
2098        let entity_id = entity.entity_id();
2099        let entity = entity.downgrade();
2100        let window_handle = self.window.handle;
2101        self.app.new_observer(
2102            entity_id,
2103            Box::new(move |cx| {
2104                window_handle
2105                    .update(cx, |_, cx| {
2106                        if let Some(handle) = E::upgrade_from(&entity) {
2107                            view.update(cx, |this, cx| on_notify(this, handle, cx))
2108                                .is_ok()
2109                        } else {
2110                            false
2111                        }
2112                    })
2113                    .unwrap_or(false)
2114            }),
2115        )
2116    }
2117
2118    /// Subscribe to events emitted by another model or view.
2119    /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
2120    /// The callback will be invoked with a reference to the current view, a handle to the emitting entity (either a [`View`] or [`Model`]), the event, and a view context for the current view.
2121    pub fn subscribe<V2, E, Evt>(
2122        &mut self,
2123        entity: &E,
2124        mut on_event: impl FnMut(&mut V, E, &Evt, &mut ViewContext<'_, V>) + 'static,
2125    ) -> Subscription
2126    where
2127        V2: EventEmitter<Evt>,
2128        E: Entity<V2>,
2129        Evt: 'static,
2130    {
2131        let view = self.view().downgrade();
2132        let entity_id = entity.entity_id();
2133        let handle = entity.downgrade();
2134        let window_handle = self.window.handle;
2135        self.app.new_subscription(
2136            entity_id,
2137            (
2138                TypeId::of::<Evt>(),
2139                Box::new(move |event, cx| {
2140                    window_handle
2141                        .update(cx, |_, cx| {
2142                            if let Some(handle) = E::upgrade_from(&handle) {
2143                                let event = event.downcast_ref().expect("invalid event type");
2144                                view.update(cx, |this, cx| on_event(this, handle, event, cx))
2145                                    .is_ok()
2146                            } else {
2147                                false
2148                            }
2149                        })
2150                        .unwrap_or(false)
2151                }),
2152            ),
2153        )
2154    }
2155
2156    /// Register a callback to be invoked when the view is released.
2157    ///
2158    /// The callback receives a handle to the view's window. This handle may be
2159    /// invalid, if the window was closed before the view was released.
2160    pub fn on_release(
2161        &mut self,
2162        on_release: impl FnOnce(&mut V, AnyWindowHandle, &mut AppContext) + 'static,
2163    ) -> Subscription {
2164        let window_handle = self.window.handle;
2165        let (subscription, activate) = self.app.release_listeners.insert(
2166            self.view.model.entity_id,
2167            Box::new(move |this, cx| {
2168                let this = this.downcast_mut().expect("invalid entity type");
2169                on_release(this, window_handle, cx)
2170            }),
2171        );
2172        activate();
2173        subscription
2174    }
2175
2176    /// Register a callback to be invoked when the given Model or View is released.
2177    pub fn observe_release<V2, E>(
2178        &mut self,
2179        entity: &E,
2180        mut on_release: impl FnMut(&mut V, &mut V2, &mut ViewContext<'_, V>) + 'static,
2181    ) -> Subscription
2182    where
2183        V: 'static,
2184        V2: 'static,
2185        E: Entity<V2>,
2186    {
2187        let view = self.view().downgrade();
2188        let entity_id = entity.entity_id();
2189        let window_handle = self.window.handle;
2190        let (subscription, activate) = self.app.release_listeners.insert(
2191            entity_id,
2192            Box::new(move |entity, cx| {
2193                let entity = entity.downcast_mut().expect("invalid entity type");
2194                let _ = window_handle.update(cx, |_, cx| {
2195                    view.update(cx, |this, cx| on_release(this, entity, cx))
2196                });
2197            }),
2198        );
2199        activate();
2200        subscription
2201    }
2202
2203    /// Indicate that this view has changed, which will invoke any observers and also mark the window as dirty.
2204    /// If this view or any of its ancestors are *cached*, notifying it will cause it or its ancestors to be redrawn.
2205    pub fn notify(&mut self) {
2206        self.window_cx.notify(self.view.entity_id());
2207    }
2208
2209    /// Register a callback to be invoked when the window is resized.
2210    pub fn observe_window_bounds(
2211        &mut self,
2212        mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2213    ) -> Subscription {
2214        let view = self.view.downgrade();
2215        let (subscription, activate) = self.window.bounds_observers.insert(
2216            (),
2217            Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
2218        );
2219        activate();
2220        subscription
2221    }
2222
2223    /// Register a callback to be invoked when the window is activated or deactivated.
2224    pub fn observe_window_activation(
2225        &mut self,
2226        mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2227    ) -> Subscription {
2228        let view = self.view.downgrade();
2229        let (subscription, activate) = self.window.activation_observers.insert(
2230            (),
2231            Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
2232        );
2233        activate();
2234        subscription
2235    }
2236
2237    /// Registers a callback to be invoked when the window appearance changes.
2238    pub fn observe_window_appearance(
2239        &mut self,
2240        mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2241    ) -> Subscription {
2242        let view = self.view.downgrade();
2243        let (subscription, activate) = self.window.appearance_observers.insert(
2244            (),
2245            Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
2246        );
2247        activate();
2248        subscription
2249    }
2250
2251    /// Register a listener to be called when the given focus handle receives focus.
2252    /// Returns a subscription and persists until the subscription is dropped.
2253    pub fn on_focus(
2254        &mut self,
2255        handle: &FocusHandle,
2256        mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2257    ) -> Subscription {
2258        let view = self.view.downgrade();
2259        let focus_id = handle.id;
2260        let (subscription, activate) =
2261            self.window.new_focus_listener(Box::new(move |event, cx| {
2262                view.update(cx, |view, cx| {
2263                    if event.previous_focus_path.last() != Some(&focus_id)
2264                        && event.current_focus_path.last() == Some(&focus_id)
2265                    {
2266                        listener(view, cx)
2267                    }
2268                })
2269                .is_ok()
2270            }));
2271        self.app.defer(|_| activate());
2272        subscription
2273    }
2274
2275    /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
2276    /// Returns a subscription and persists until the subscription is dropped.
2277    pub fn on_focus_in(
2278        &mut self,
2279        handle: &FocusHandle,
2280        mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2281    ) -> Subscription {
2282        let view = self.view.downgrade();
2283        let focus_id = handle.id;
2284        let (subscription, activate) =
2285            self.window.new_focus_listener(Box::new(move |event, cx| {
2286                view.update(cx, |view, cx| {
2287                    if !event.previous_focus_path.contains(&focus_id)
2288                        && event.current_focus_path.contains(&focus_id)
2289                    {
2290                        listener(view, cx)
2291                    }
2292                })
2293                .is_ok()
2294            }));
2295        self.app.defer(move |_| activate());
2296        subscription
2297    }
2298
2299    /// Register a listener to be called when the given focus handle loses focus.
2300    /// Returns a subscription and persists until the subscription is dropped.
2301    pub fn on_blur(
2302        &mut self,
2303        handle: &FocusHandle,
2304        mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2305    ) -> Subscription {
2306        let view = self.view.downgrade();
2307        let focus_id = handle.id;
2308        let (subscription, activate) =
2309            self.window.new_focus_listener(Box::new(move |event, cx| {
2310                view.update(cx, |view, cx| {
2311                    if event.previous_focus_path.last() == Some(&focus_id)
2312                        && event.current_focus_path.last() != Some(&focus_id)
2313                    {
2314                        listener(view, cx)
2315                    }
2316                })
2317                .is_ok()
2318            }));
2319        self.app.defer(move |_| activate());
2320        subscription
2321    }
2322
2323    /// Register a listener to be called when nothing in the window has focus.
2324    /// This typically happens when the node that was focused is removed from the tree,
2325    /// and this callback lets you chose a default place to restore the users focus.
2326    /// Returns a subscription and persists until the subscription is dropped.
2327    pub fn on_focus_lost(
2328        &mut self,
2329        mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2330    ) -> Subscription {
2331        let view = self.view.downgrade();
2332        let (subscription, activate) = self.window.focus_lost_listeners.insert(
2333            (),
2334            Box::new(move |cx| view.update(cx, |view, cx| listener(view, cx)).is_ok()),
2335        );
2336        activate();
2337        subscription
2338    }
2339
2340    /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
2341    /// Returns a subscription and persists until the subscription is dropped.
2342    pub fn on_focus_out(
2343        &mut self,
2344        handle: &FocusHandle,
2345        mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2346    ) -> Subscription {
2347        let view = self.view.downgrade();
2348        let focus_id = handle.id;
2349        let (subscription, activate) =
2350            self.window.new_focus_listener(Box::new(move |event, cx| {
2351                view.update(cx, |view, cx| {
2352                    if event.previous_focus_path.contains(&focus_id)
2353                        && !event.current_focus_path.contains(&focus_id)
2354                    {
2355                        listener(view, cx)
2356                    }
2357                })
2358                .is_ok()
2359            }));
2360        self.app.defer(move |_| activate());
2361        subscription
2362    }
2363
2364    /// Schedule a future to be run asynchronously.
2365    /// The given callback is invoked with a [`WeakView<V>`] to avoid leaking the view for a long-running process.
2366    /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the view across await points.
2367    /// The returned future will be polled on the main thread.
2368    pub fn spawn<Fut, R>(
2369        &mut self,
2370        f: impl FnOnce(WeakView<V>, AsyncWindowContext) -> Fut,
2371    ) -> Task<R>
2372    where
2373        R: 'static,
2374        Fut: Future<Output = R> + 'static,
2375    {
2376        let view = self.view().downgrade();
2377        self.window_cx.spawn(|cx| f(view, cx))
2378    }
2379
2380    /// Register a callback to be invoked when the given global state changes.
2381    pub fn observe_global<G: Global>(
2382        &mut self,
2383        mut f: impl FnMut(&mut V, &mut ViewContext<'_, V>) + 'static,
2384    ) -> Subscription {
2385        let window_handle = self.window.handle;
2386        let view = self.view().downgrade();
2387        let (subscription, activate) = self.global_observers.insert(
2388            TypeId::of::<G>(),
2389            Box::new(move |cx| {
2390                window_handle
2391                    .update(cx, |_, cx| view.update(cx, |view, cx| f(view, cx)).is_ok())
2392                    .unwrap_or(false)
2393            }),
2394        );
2395        self.app.defer(move |_| activate());
2396        subscription
2397    }
2398
2399    /// Register a callback to be invoked when the given Action type is dispatched to the window.
2400    pub fn on_action(
2401        &mut self,
2402        action_type: TypeId,
2403        listener: impl Fn(&mut V, &dyn Any, DispatchPhase, &mut ViewContext<V>) + 'static,
2404    ) {
2405        let handle = self.view().clone();
2406        self.window_cx
2407            .on_action(action_type, move |action, phase, cx| {
2408                handle.update(cx, |view, cx| {
2409                    listener(view, action, phase, cx);
2410                })
2411            });
2412    }
2413
2414    /// Emit an event to be handled any other views that have subscribed via [ViewContext::subscribe].
2415    pub fn emit<Evt>(&mut self, event: Evt)
2416    where
2417        Evt: 'static,
2418        V: EventEmitter<Evt>,
2419    {
2420        let emitter = self.view.model.entity_id;
2421        self.app.push_effect(Effect::Emit {
2422            emitter,
2423            event_type: TypeId::of::<Evt>(),
2424            event: Box::new(event),
2425        });
2426    }
2427
2428    /// Move focus to the current view, assuming it implements [`FocusableView`].
2429    pub fn focus_self(&mut self)
2430    where
2431        V: FocusableView,
2432    {
2433        self.defer(|view, cx| view.focus_handle(cx).focus(cx))
2434    }
2435
2436    /// Convenience method for accessing view state in an event callback.
2437    ///
2438    /// Many GPUI callbacks take the form of `Fn(&E, &mut WindowContext)`,
2439    /// but it's often useful to be able to access view state in these
2440    /// callbacks. This method provides a convenient way to do so.
2441    pub fn listener<E>(
2442        &self,
2443        f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
2444    ) -> impl Fn(&E, &mut WindowContext) + 'static {
2445        let view = self.view().downgrade();
2446        move |e: &E, cx: &mut WindowContext| {
2447            view.update(cx, |view, cx| f(view, e, cx)).ok();
2448        }
2449    }
2450}
2451
2452impl<V> Context for ViewContext<'_, V> {
2453    type Result<U> = U;
2454
2455    fn new_model<T: 'static>(
2456        &mut self,
2457        build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
2458    ) -> Model<T> {
2459        self.window_cx.new_model(build_model)
2460    }
2461
2462    fn update_model<T: 'static, R>(
2463        &mut self,
2464        model: &Model<T>,
2465        update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
2466    ) -> R {
2467        self.window_cx.update_model(model, update)
2468    }
2469
2470    fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
2471    where
2472        F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
2473    {
2474        self.window_cx.update_window(window, update)
2475    }
2476
2477    fn read_model<T, R>(
2478        &self,
2479        handle: &Model<T>,
2480        read: impl FnOnce(&T, &AppContext) -> R,
2481    ) -> Self::Result<R>
2482    where
2483        T: 'static,
2484    {
2485        self.window_cx.read_model(handle, read)
2486    }
2487
2488    fn read_window<T, R>(
2489        &self,
2490        window: &WindowHandle<T>,
2491        read: impl FnOnce(View<T>, &AppContext) -> R,
2492    ) -> Result<R>
2493    where
2494        T: 'static,
2495    {
2496        self.window_cx.read_window(window, read)
2497    }
2498}
2499
2500impl<V: 'static> VisualContext for ViewContext<'_, V> {
2501    fn new_view<W: Render + 'static>(
2502        &mut self,
2503        build_view_state: impl FnOnce(&mut ViewContext<'_, W>) -> W,
2504    ) -> Self::Result<View<W>> {
2505        self.window_cx.new_view(build_view_state)
2506    }
2507
2508    fn update_view<V2: 'static, R>(
2509        &mut self,
2510        view: &View<V2>,
2511        update: impl FnOnce(&mut V2, &mut ViewContext<'_, V2>) -> R,
2512    ) -> Self::Result<R> {
2513        self.window_cx.update_view(view, update)
2514    }
2515
2516    fn replace_root_view<W>(
2517        &mut self,
2518        build_view: impl FnOnce(&mut ViewContext<'_, W>) -> W,
2519    ) -> Self::Result<View<W>>
2520    where
2521        W: 'static + Render,
2522    {
2523        self.window_cx.replace_root_view(build_view)
2524    }
2525
2526    fn focus_view<W: FocusableView>(&mut self, view: &View<W>) -> Self::Result<()> {
2527        self.window_cx.focus_view(view)
2528    }
2529
2530    fn dismiss_view<W: ManagedView>(&mut self, view: &View<W>) -> Self::Result<()> {
2531        self.window_cx.dismiss_view(view)
2532    }
2533}
2534
2535impl<'a, V> std::ops::Deref for ViewContext<'a, V> {
2536    type Target = WindowContext<'a>;
2537
2538    fn deref(&self) -> &Self::Target {
2539        &self.window_cx
2540    }
2541}
2542
2543impl<'a, V> std::ops::DerefMut for ViewContext<'a, V> {
2544    fn deref_mut(&mut self) -> &mut Self::Target {
2545        &mut self.window_cx
2546    }
2547}
2548
2549// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
2550slotmap::new_key_type! {
2551    /// A unique identifier for a window.
2552    pub struct WindowId;
2553}
2554
2555impl WindowId {
2556    /// Converts this window ID to a `u64`.
2557    pub fn as_u64(&self) -> u64 {
2558        self.0.as_ffi()
2559    }
2560}
2561
2562/// A handle to a window with a specific root view type.
2563/// Note that this does not keep the window alive on its own.
2564#[derive(Deref, DerefMut)]
2565pub struct WindowHandle<V> {
2566    #[deref]
2567    #[deref_mut]
2568    pub(crate) any_handle: AnyWindowHandle,
2569    state_type: PhantomData<V>,
2570}
2571
2572impl<V: 'static + Render> WindowHandle<V> {
2573    /// Creates a new handle from a window ID.
2574    /// This does not check if the root type of the window is `V`.
2575    pub fn new(id: WindowId) -> Self {
2576        WindowHandle {
2577            any_handle: AnyWindowHandle {
2578                id,
2579                state_type: TypeId::of::<V>(),
2580            },
2581            state_type: PhantomData,
2582        }
2583    }
2584
2585    /// Get the root view out of this window.
2586    ///
2587    /// This will fail if the window is closed or if the root view's type does not match `V`.
2588    pub fn root<C>(&self, cx: &mut C) -> Result<View<V>>
2589    where
2590        C: Context,
2591    {
2592        Flatten::flatten(cx.update_window(self.any_handle, |root_view, _| {
2593            root_view
2594                .downcast::<V>()
2595                .map_err(|_| anyhow!("the type of the window's root view has changed"))
2596        }))
2597    }
2598
2599    /// Updates the root view of this window.
2600    ///
2601    /// This will fail if the window has been closed or if the root view's type does not match
2602    pub fn update<C, R>(
2603        &self,
2604        cx: &mut C,
2605        update: impl FnOnce(&mut V, &mut ViewContext<'_, V>) -> R,
2606    ) -> Result<R>
2607    where
2608        C: Context,
2609    {
2610        cx.update_window(self.any_handle, |root_view, cx| {
2611            let view = root_view
2612                .downcast::<V>()
2613                .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
2614            Ok(cx.update_view(&view, update))
2615        })?
2616    }
2617
2618    /// Read the root view out of this window.
2619    ///
2620    /// This will fail if the window is closed or if the root view's type does not match `V`.
2621    pub fn read<'a>(&self, cx: &'a AppContext) -> Result<&'a V> {
2622        let x = cx
2623            .windows
2624            .get(self.id)
2625            .and_then(|window| {
2626                window
2627                    .as_ref()
2628                    .and_then(|window| window.root_view.clone())
2629                    .map(|root_view| root_view.downcast::<V>())
2630            })
2631            .ok_or_else(|| anyhow!("window not found"))?
2632            .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
2633
2634        Ok(x.read(cx))
2635    }
2636
2637    /// Read the root view out of this window, with a callback
2638    ///
2639    /// This will fail if the window is closed or if the root view's type does not match `V`.
2640    pub fn read_with<C, R>(&self, cx: &C, read_with: impl FnOnce(&V, &AppContext) -> R) -> Result<R>
2641    where
2642        C: Context,
2643    {
2644        cx.read_window(self, |root_view, cx| read_with(root_view.read(cx), cx))
2645    }
2646
2647    /// Read the root view pointer off of this window.
2648    ///
2649    /// This will fail if the window is closed or if the root view's type does not match `V`.
2650    pub fn root_view<C>(&self, cx: &C) -> Result<View<V>>
2651    where
2652        C: Context,
2653    {
2654        cx.read_window(self, |root_view, _cx| root_view.clone())
2655    }
2656
2657    /// Check if this window is 'active'.
2658    ///
2659    /// Will return `None` if the window is closed or currently
2660    /// borrowed.
2661    pub fn is_active(&self, cx: &mut AppContext) -> Option<bool> {
2662        cx.update_window(self.any_handle, |_, cx| cx.is_window_active())
2663            .ok()
2664    }
2665}
2666
2667impl<V> Copy for WindowHandle<V> {}
2668
2669impl<V> Clone for WindowHandle<V> {
2670    fn clone(&self) -> Self {
2671        *self
2672    }
2673}
2674
2675impl<V> PartialEq for WindowHandle<V> {
2676    fn eq(&self, other: &Self) -> bool {
2677        self.any_handle == other.any_handle
2678    }
2679}
2680
2681impl<V> Eq for WindowHandle<V> {}
2682
2683impl<V> Hash for WindowHandle<V> {
2684    fn hash<H: Hasher>(&self, state: &mut H) {
2685        self.any_handle.hash(state);
2686    }
2687}
2688
2689impl<V: 'static> From<WindowHandle<V>> for AnyWindowHandle {
2690    fn from(val: WindowHandle<V>) -> Self {
2691        val.any_handle
2692    }
2693}
2694
2695/// A handle to a window with any root view type, which can be downcast to a window with a specific root view type.
2696#[derive(Copy, Clone, PartialEq, Eq, Hash)]
2697pub struct AnyWindowHandle {
2698    pub(crate) id: WindowId,
2699    state_type: TypeId,
2700}
2701
2702impl AnyWindowHandle {
2703    /// Get the ID of this window.
2704    pub fn window_id(&self) -> WindowId {
2705        self.id
2706    }
2707
2708    /// Attempt to convert this handle to a window handle with a specific root view type.
2709    /// If the types do not match, this will return `None`.
2710    pub fn downcast<T: 'static>(&self) -> Option<WindowHandle<T>> {
2711        if TypeId::of::<T>() == self.state_type {
2712            Some(WindowHandle {
2713                any_handle: *self,
2714                state_type: PhantomData,
2715            })
2716        } else {
2717            None
2718        }
2719    }
2720
2721    /// Updates the state of the root view of this window.
2722    ///
2723    /// This will fail if the window has been closed.
2724    pub fn update<C, R>(
2725        self,
2726        cx: &mut C,
2727        update: impl FnOnce(AnyView, &mut WindowContext<'_>) -> R,
2728    ) -> Result<R>
2729    where
2730        C: Context,
2731    {
2732        cx.update_window(self, update)
2733    }
2734
2735    /// Read the state of the root view of this window.
2736    ///
2737    /// This will fail if the window has been closed.
2738    pub fn read<T, C, R>(self, cx: &C, read: impl FnOnce(View<T>, &AppContext) -> R) -> Result<R>
2739    where
2740        C: Context,
2741        T: 'static,
2742    {
2743        let view = self
2744            .downcast::<T>()
2745            .context("the type of the window's root view has changed")?;
2746
2747        cx.read_window(&view, read)
2748    }
2749}
2750
2751/// An identifier for an [`Element`](crate::Element).
2752///
2753/// Can be constructed with a string, a number, or both, as well
2754/// as other internal representations.
2755#[derive(Clone, Debug, Eq, PartialEq, Hash)]
2756pub enum ElementId {
2757    /// The ID of a View element
2758    View(EntityId),
2759    /// An integer ID.
2760    Integer(usize),
2761    /// A string based ID.
2762    Name(SharedString),
2763    /// An ID that's equated with a focus handle.
2764    FocusHandle(FocusId),
2765    /// A combination of a name and an integer.
2766    NamedInteger(SharedString, usize),
2767}
2768
2769impl Display for ElementId {
2770    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2771        match self {
2772            ElementId::View(entity_id) => write!(f, "view-{}", entity_id)?,
2773            ElementId::Integer(ix) => write!(f, "{}", ix)?,
2774            ElementId::Name(name) => write!(f, "{}", name)?,
2775            ElementId::FocusHandle(_) => write!(f, "FocusHandle")?,
2776            ElementId::NamedInteger(s, i) => write!(f, "{}-{}", s, i)?,
2777        }
2778
2779        Ok(())
2780    }
2781}
2782
2783impl TryInto<SharedString> for ElementId {
2784    type Error = anyhow::Error;
2785
2786    fn try_into(self) -> anyhow::Result<SharedString> {
2787        if let ElementId::Name(name) = self {
2788            Ok(name)
2789        } else {
2790            Err(anyhow!("element id is not string"))
2791        }
2792    }
2793}
2794
2795impl From<usize> for ElementId {
2796    fn from(id: usize) -> Self {
2797        ElementId::Integer(id)
2798    }
2799}
2800
2801impl From<i32> for ElementId {
2802    fn from(id: i32) -> Self {
2803        Self::Integer(id as usize)
2804    }
2805}
2806
2807impl From<SharedString> for ElementId {
2808    fn from(name: SharedString) -> Self {
2809        ElementId::Name(name)
2810    }
2811}
2812
2813impl From<&'static str> for ElementId {
2814    fn from(name: &'static str) -> Self {
2815        ElementId::Name(name.into())
2816    }
2817}
2818
2819impl<'a> From<&'a FocusHandle> for ElementId {
2820    fn from(handle: &'a FocusHandle) -> Self {
2821        ElementId::FocusHandle(handle.id)
2822    }
2823}
2824
2825impl From<(&'static str, EntityId)> for ElementId {
2826    fn from((name, id): (&'static str, EntityId)) -> Self {
2827        ElementId::NamedInteger(name.into(), id.as_u64() as usize)
2828    }
2829}
2830
2831impl From<(&'static str, usize)> for ElementId {
2832    fn from((name, id): (&'static str, usize)) -> Self {
2833        ElementId::NamedInteger(name.into(), id)
2834    }
2835}
2836
2837impl From<(&'static str, u64)> for ElementId {
2838    fn from((name, id): (&'static str, u64)) -> Self {
2839        ElementId::NamedInteger(name.into(), id as usize)
2840    }
2841}
2842
2843/// A rectangle to be rendered in the window at the given position and size.
2844/// Passed as an argument [`ElementContext::paint_quad`].
2845#[derive(Clone)]
2846pub struct PaintQuad {
2847    bounds: Bounds<Pixels>,
2848    corner_radii: Corners<Pixels>,
2849    background: Hsla,
2850    border_widths: Edges<Pixels>,
2851    border_color: Hsla,
2852}
2853
2854impl PaintQuad {
2855    /// Sets the corner radii of the quad.
2856    pub fn corner_radii(self, corner_radii: impl Into<Corners<Pixels>>) -> Self {
2857        PaintQuad {
2858            corner_radii: corner_radii.into(),
2859            ..self
2860        }
2861    }
2862
2863    /// Sets the border widths of the quad.
2864    pub fn border_widths(self, border_widths: impl Into<Edges<Pixels>>) -> Self {
2865        PaintQuad {
2866            border_widths: border_widths.into(),
2867            ..self
2868        }
2869    }
2870
2871    /// Sets the border color of the quad.
2872    pub fn border_color(self, border_color: impl Into<Hsla>) -> Self {
2873        PaintQuad {
2874            border_color: border_color.into(),
2875            ..self
2876        }
2877    }
2878
2879    /// Sets the background color of the quad.
2880    pub fn background(self, background: impl Into<Hsla>) -> Self {
2881        PaintQuad {
2882            background: background.into(),
2883            ..self
2884        }
2885    }
2886}
2887
2888/// Creates a quad with the given parameters.
2889pub fn quad(
2890    bounds: Bounds<Pixels>,
2891    corner_radii: impl Into<Corners<Pixels>>,
2892    background: impl Into<Hsla>,
2893    border_widths: impl Into<Edges<Pixels>>,
2894    border_color: impl Into<Hsla>,
2895) -> PaintQuad {
2896    PaintQuad {
2897        bounds,
2898        corner_radii: corner_radii.into(),
2899        background: background.into(),
2900        border_widths: border_widths.into(),
2901        border_color: border_color.into(),
2902    }
2903}
2904
2905/// Creates a filled quad with the given bounds and background color.
2906pub fn fill(bounds: impl Into<Bounds<Pixels>>, background: impl Into<Hsla>) -> PaintQuad {
2907    PaintQuad {
2908        bounds: bounds.into(),
2909        corner_radii: (0.).into(),
2910        background: background.into(),
2911        border_widths: (0.).into(),
2912        border_color: transparent_black(),
2913    }
2914}
2915
2916/// Creates a rectangle outline with the given bounds, border color, and a 1px border width
2917pub fn outline(bounds: impl Into<Bounds<Pixels>>, border_color: impl Into<Hsla>) -> PaintQuad {
2918    PaintQuad {
2919        bounds: bounds.into(),
2920        corner_radii: (0.).into(),
2921        background: transparent_black(),
2922        border_widths: (1.).into(),
2923        border_color: border_color.into(),
2924    }
2925}