Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T02:34:19.309Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

window.rs

6802 lines · 259.7 KB · rust
1#[cfg(any(feature = "inspector", debug_assertions))]
2use crate::Inspector;
3use crate::{
4    Action, AnyDrag, AnyElement, AnyImageCache, AnyTooltip, AnyView, App, AppContext, Arena, Asset,
5    AsyncWindowContext, AvailableSpace, Background, BorderStyle, Bounds, BoxShadow, Capslock,
6    Context, Corners, CursorHideMode, CursorStyle, Decorations, DevicePixels,
7    DispatchActionListener, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity,
8    EntityId, EventEmitter, FileDropEvent, FontId, Global, GlobalElementId, GlyphId, GpuSpecs,
9    Hsla, InputHandler, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeyEvent, Keystroke,
10    KeystrokeEvent, LayoutId, LineLayoutIndex, Modifiers, ModifiersChangedEvent, MonochromeSprite,
11    MouseButton, MouseEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels, PlatformAtlas,
12    PlatformDisplay, PlatformInput, PlatformInputHandler, PlatformWindow, Point, PolychromeSprite,
13    Priority, PromptButton, PromptLevel, Quad, Render, RenderGlyphParams, RenderImage,
14    RenderImageParams, RenderSvgParams, Replay, ResizeEdge, SMOOTH_SVG_SCALE_FACTOR,
15    SUBPIXEL_VARIANTS_X, SUBPIXEL_VARIANTS_Y, ScaledPixels, Scene, Shadow, SharedString, Size,
16    StrikethroughStyle, Style, SubpixelSprite, SubscriberSet, Subscription, SystemWindowTab,
17    SystemWindowTabController, TabStopMap, TaffyLayoutEngine, Task, TextRenderingMode, TextStyle,
18    TextStyleRefinement, ThermalState, TransformationMatrix, Underline, UnderlineStyle,
19    WindowAppearance, WindowBackgroundAppearance, WindowBounds, WindowControls, WindowDecorations,
20    WindowOptions, WindowParams, WindowTextSystem, point, prelude::*, profiler, px, rems, size,
21    transparent_black,
22};
23
24use anyhow::{Context as _, Result, anyhow};
25use collections::{FxHashMap, FxHashSet};
26#[cfg(target_os = "macos")]
27use core_video::pixel_buffer::CVPixelBuffer;
28use derive_more::{Deref, DerefMut};
29use futures::FutureExt;
30use futures::channel::oneshot;
31use gpui_util::post_inc;
32use gpui_util::{ResultExt, measure};
33#[cfg(feature = "input-latency-histogram")]
34use hdrhistogram::Histogram;
35use itertools::FoldWhile::{Continue, Done};
36use itertools::Itertools;
37use parking_lot::RwLock;
38use raw_window_handle::{HandleError, HasDisplayHandle, HasWindowHandle};
39use refineable::Refineable;
40use scheduler::Instant;
41use slotmap::SlotMap;
42use smallvec::SmallVec;
43use std::{
44    any::{Any, TypeId},
45    borrow::Cow,
46    cell::{Cell, RefCell},
47    cmp,
48    fmt::{Debug, Display},
49    hash::{Hash, Hasher},
50    marker::PhantomData,
51    mem,
52    ops::{DerefMut, Range},
53    rc::Rc,
54    sync::{
55        Arc, Weak,
56        atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
57    },
58    time::Duration,
59};
60use uuid::Uuid;
61
62pub(crate) mod a11y;
63mod prompts;
64
65pub use a11y::A11ySubtreeBuilder;
66
67use self::a11y::A11y;
68#[cfg(not(target_family = "wasm"))]
69use self::a11y::ROOT_NODE_ID;
70use crate::util::{
71    atomic_incr_if_not_zero, ceil_to_device_pixel, floor_to_device_pixel, round_half_toward_zero,
72    round_half_toward_zero_f64, round_stroke_to_device_pixel, round_to_device_pixel,
73};
74pub use prompts::*;
75
76/// Default window size used when no explicit size is provided.
77pub const DEFAULT_WINDOW_SIZE: Size<Pixels> = size(px(1536.), px(1095.));
78
79/// A 6:5 aspect ratio minimum window size to be used for functional,
80/// additional-to-main-Zed windows, like the settings and rules library windows.
81pub const DEFAULT_ADDITIONAL_WINDOW_SIZE: Size<Pixels> = Size {
82    width: Pixels(900.),
83    height: Pixels(750.),
84};
85
86/// Represents the two different phases when dispatching events.
87#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]
88pub enum DispatchPhase {
89    /// After the capture phase comes the bubble phase, in which mouse event listeners are
90    /// invoked front to back and keyboard event listeners are invoked from the focused element
91    /// to the root of the element tree. This is the phase you'll most commonly want to use when
92    /// registering event listeners.
93    #[default]
94    Bubble,
95    /// During the initial capture phase, mouse event listeners are invoked back to front, and keyboard
96    /// listeners are invoked from the root of the tree downward toward the focused element. This phase
97    /// is used for special purposes such as clearing the "pressed" state for click events. If
98    /// you stop event propagation during this phase, you need to know what you're doing. Handlers
99    /// outside of the immediate region may rely on detecting non-local events during this phase.
100    Capture,
101}
102
103impl DispatchPhase {
104    /// Returns true if this represents the "bubble" phase.
105    #[inline]
106    pub fn bubble(self) -> bool {
107        self == DispatchPhase::Bubble
108    }
109
110    /// Returns true if this represents the "capture" phase.
111    #[inline]
112    pub fn capture(self) -> bool {
113        self == DispatchPhase::Capture
114    }
115}
116
117struct WindowInvalidatorInner {
118    pub dirty: bool,
119    pub draw_phase: DrawPhase,
120    pub dirty_views: FxHashSet<EntityId>,
121    pub update_count: usize,
122    pub frame_dirty: FrameDirtyAccumulator,
123}
124
125/// Per-frame invalidation bookkeeping, drained at draw time and emitted to the
126/// frame profiler. Tracks when the current frame first became dirty and how
127/// many invalidations were coalesced into it. Only populated while
128/// `profiler::frame_trace_enabled()` is set.
129#[derive(Default)]
130struct FrameDirtyAccumulator {
131    dirty_at: Option<Instant>,
132    invalidations: u64,
133}
134
135#[derive(Clone)]
136pub(crate) struct WindowInvalidator {
137    inner: Rc<RefCell<WindowInvalidatorInner>>,
138}
139
140impl WindowInvalidator {
141    pub fn new() -> Self {
142        WindowInvalidator {
143            inner: Rc::new(RefCell::new(WindowInvalidatorInner {
144                dirty: true,
145                draw_phase: DrawPhase::None,
146                dirty_views: FxHashSet::default(),
147                update_count: 0,
148                frame_dirty: FrameDirtyAccumulator::default(),
149            })),
150        }
151    }
152
153    pub fn invalidate_view(&self, entity: EntityId, cx: &mut App) -> bool {
154        let mut inner = self.inner.borrow_mut();
155        inner.update_count += 1;
156        inner.dirty_views.insert(entity);
157        if inner.draw_phase == DrawPhase::None {
158            Self::record_frame_dirty(&mut inner);
159            inner.dirty = true;
160            cx.push_effect(Effect::Notify { emitter: entity });
161            true
162        } else {
163            false
164        }
165    }
166
167    pub fn is_dirty(&self) -> bool {
168        self.inner.borrow().dirty
169    }
170
171    pub fn set_dirty(&self, dirty: bool) {
172        let mut inner = self.inner.borrow_mut();
173        inner.dirty = dirty;
174        if dirty {
175            inner.update_count += 1;
176            Self::record_frame_dirty(&mut inner);
177        }
178    }
179
180    pub fn set_phase(&self, phase: DrawPhase) {
181        self.inner.borrow_mut().draw_phase = phase
182    }
183
184    pub fn update_count(&self) -> usize {
185        self.inner.borrow().update_count
186    }
187
188    fn record_frame_dirty(inner: &mut WindowInvalidatorInner) {
189        if profiler::frame_trace_enabled() {
190            inner.frame_dirty.dirty_at.get_or_insert_with(Instant::now);
191            inner.frame_dirty.invalidations += 1;
192        }
193    }
194
195    fn take_frame_dirty(&self) -> FrameDirtyAccumulator {
196        mem::take(&mut self.inner.borrow_mut().frame_dirty)
197    }
198
199    pub fn take_views(&self) -> FxHashSet<EntityId> {
200        mem::take(&mut self.inner.borrow_mut().dirty_views)
201    }
202
203    pub fn replace_views(&self, views: FxHashSet<EntityId>) {
204        self.inner.borrow_mut().dirty_views = views;
205    }
206
207    pub fn not_drawing(&self) -> bool {
208        self.inner.borrow().draw_phase == DrawPhase::None
209    }
210
211    #[track_caller]
212    pub fn debug_assert_paint(&self) {
213        debug_assert!(
214            matches!(self.inner.borrow().draw_phase, DrawPhase::Paint),
215            "this method can only be called during paint"
216        );
217    }
218
219    #[track_caller]
220    pub fn debug_assert_prepaint(&self) {
221        debug_assert!(
222            matches!(self.inner.borrow().draw_phase, DrawPhase::Prepaint),
223            "this method can only be called during request_layout, or prepaint"
224        );
225    }
226
227    #[track_caller]
228    pub fn debug_assert_paint_or_prepaint(&self) {
229        debug_assert!(
230            matches!(
231                self.inner.borrow().draw_phase,
232                DrawPhase::Paint | DrawPhase::Prepaint
233            ),
234            "this method can only be called during request_layout, prepaint, or paint"
235        );
236    }
237}
238
239type AnyObserver = Box<dyn FnMut(&mut Window, &mut App) -> bool + 'static>;
240
241pub(crate) type AnyWindowFocusListener =
242    Box<dyn FnMut(&WindowFocusEvent, &mut Window, &mut App) -> bool + 'static>;
243
244pub(crate) struct WindowFocusEvent {
245    pub(crate) previous_focus_path: SmallVec<[FocusId; 8]>,
246    pub(crate) current_focus_path: SmallVec<[FocusId; 8]>,
247}
248
249impl WindowFocusEvent {
250    pub fn is_focus_in(&self, focus_id: FocusId) -> bool {
251        !self.previous_focus_path.contains(&focus_id) && self.current_focus_path.contains(&focus_id)
252    }
253
254    pub fn is_focus_out(&self, focus_id: FocusId) -> bool {
255        self.previous_focus_path.contains(&focus_id) && !self.current_focus_path.contains(&focus_id)
256    }
257}
258
259/// This is provided when subscribing for `Context::on_focus_out` events.
260pub struct FocusOutEvent {
261    /// A weak focus handle representing what was blurred.
262    pub blurred: WeakFocusHandle,
263}
264
265slotmap::new_key_type! {
266    /// A globally unique identifier for a focusable element.
267    pub struct FocusId;
268}
269
270thread_local! {
271    /// Fallback arena used when no app-specific arena is active.
272    /// In production, each window draw sets CURRENT_ELEMENT_ARENA to the app's arena.
273    pub(crate) static ELEMENT_ARENA: RefCell<Arena> = RefCell::new(Arena::new(1024 * 1024));
274
275    /// Points to the current App's element arena during draw operations.
276    /// This allows multiple test Apps to have isolated arenas, preventing
277    /// cross-session corruption when the scheduler interleaves their tasks.
278    static CURRENT_ELEMENT_ARENA: Cell<Option<*const RefCell<Arena>>> = const { Cell::new(None) };
279}
280
281/// Whether a window draw is currently in progress on this thread.
282///
283/// This holds exactly while an `ElementArenaScope` is active: nested scopes
284/// restore the previous (still set) arena pointer, so `CURRENT_ELEMENT_ARENA`
285/// is `Some` from the outermost draw's start to its end.
286///
287/// The `on_request_frame` callback uses this to defer draw requests that
288/// arrive re-entrantly while a draw is already on the stack (e.g. via nested
289/// message pumping in the Windows window procedure), instead of running a
290/// nested draw or panicking on the already-borrowed App.
291fn draw_in_progress() -> bool {
292    CURRENT_ELEMENT_ARENA.with(|current| current.get().is_some())
293}
294
295/// Allocates an element in the current arena. Uses the app-specific arena if one
296/// is active (during draw), otherwise falls back to the thread-local ELEMENT_ARENA.
297pub(crate) fn with_element_arena<R>(f: impl FnOnce(&mut Arena) -> R) -> R {
298    CURRENT_ELEMENT_ARENA.with(|current| {
299        if let Some(arena_ptr) = current.get() {
300            // SAFETY: The pointer is valid for the duration of the draw operation
301            // that set it, and we're being called during that same draw.
302            let arena_cell = unsafe { &*arena_ptr };
303            f(&mut arena_cell.borrow_mut())
304        } else {
305            ELEMENT_ARENA.with_borrow_mut(f)
306        }
307    })
308}
309
310/// Scope guard that sets CURRENT_ELEMENT_ARENA for the duration of a draw
311/// operation and tracks the arena's scope depth, so that a nested draw's
312/// `ArenaClearNeeded::clear` is deferred rather than freeing memory the outer
313/// draw still references (see `Arena::clear`).
314///
315/// Call [`ElementArenaScope::exit`] with the same arena that was entered to
316/// obtain the [`ArenaClearNeeded`] token the draw now owes; requiring `exit`
317/// makes it impossible to request a clear before the scope has ended. The
318/// scope's teardown — restoring the thread-local and balancing `begin_scope`
319/// with `end_scope` — happens in `Drop`, so the arena's scope depth stays
320/// balanced on every path, including when a panic unwinds a draw before `exit`
321/// is reached. (If teardown lived only in `exit`, such a panic would leave the
322/// scope depth permanently elevated and defer every future clear, leaking
323/// memory unboundedly.)
324pub(crate) struct ElementArenaScope {
325    /// The entered arena: compared against the argument in `exit`, and
326    /// dereferenced in `Drop` to end its scope (see the SAFETY note there).
327    entered: *const RefCell<Arena>,
328    previous: Option<*const RefCell<Arena>>,
329    exited: bool,
330}
331
332impl ElementArenaScope {
333    /// Enter a scope where element allocations use the given arena.
334    pub(crate) fn enter(arena: &RefCell<Arena>) -> Self {
335        arena.borrow_mut().begin_scope();
336        let previous = CURRENT_ELEMENT_ARENA.with(|current| {
337            let prev = current.get();
338            current.set(Some(arena as *const RefCell<Arena>));
339            prev
340        });
341        Self {
342            entered: arena as *const RefCell<Arena>,
343            previous,
344            exited: false,
345        }
346    }
347
348    /// End the scope: restores the previously-current arena and ends the
349    /// arena's clear-deferral scope. Returns the token for the arena clear the
350    /// draw now owes; producing it here makes it impossible to request a clear
351    /// before the scope has ended (which would be silently deferred forever).
352    ///
353    /// Panics if passed a different arena than was entered: ending the scope
354    /// of the wrong arena would unbalance two arenas' scope depths, allowing
355    /// one of them to clear while a draw still references its memory.
356    pub(crate) fn exit(mut self, arena: &RefCell<Arena>) -> ArenaClearNeeded {
357        assert!(
358            std::ptr::eq(self.entered, arena),
359            "ElementArenaScope::exit called with a different arena than was entered"
360        );
361        self.exited = true;
362        // Teardown (restoring the thread-local and ending the arena's
363        // clear-deferral scope) runs in `Drop`, which fires both here — `self`
364        // is dropped as `exit` returns, before the token reaches the caller —
365        // and when a panic unwinds the draw before `exit` is reached.
366        ArenaClearNeeded::new(arena)
367    }
368}
369
370impl Drop for ElementArenaScope {
371    fn drop(&mut self) {
372        // Teardown lives here (rather than in `exit`) so it runs exactly once on
373        // every path: `exit` consumes and drops the guard on the normal path,
374        // and unwinding drops it on the panic path. Balancing `begin_scope` here
375        // keeps the arena's scope depth correct even when a draw panics; if this
376        // only happened in `exit`, a panic between `enter` and `exit` would leave
377        // the depth elevated and defer every future clear.
378        CURRENT_ELEMENT_ARENA.with(|current| {
379            current.set(self.previous);
380        });
381        // SAFETY: `entered` came from a `&RefCell<Arena>` in `enter`, and the
382        // arena (owned by the `App` being drawn) outlives this guard on both the
383        // normal and unwinding paths, since the guard is a local of the draw.
384        unsafe { &*self.entered }.borrow_mut().end_scope();
385        if !self.exited && !std::thread::panicking() {
386            debug_assert!(false, "ElementArenaScope dropped without calling exit()");
387            log::error!(
388                "ElementArenaScope dropped without calling exit(); \
389                 the arena clear for this draw was never requested"
390            );
391        }
392    }
393}
394
395/// Returned when the element arena has been used and so must be cleared before the next draw.
396#[must_use]
397pub struct ArenaClearNeeded {
398    /// Identity of the arena that was drawn into. Only ever compared against
399    /// another pointer in `clear`; never dereferenced.
400    arena: *const RefCell<Arena>,
401}
402
403impl ArenaClearNeeded {
404    /// Create a new ArenaClearNeeded token for the App whose arena was drawn
405    /// into. Private: the only way to obtain one is [`ElementArenaScope::exit`].
406    fn new(arena: &RefCell<Arena>) -> Self {
407        Self {
408            arena: arena as *const RefCell<Arena>,
409        }
410    }
411
412    /// Clear the element arena of the App the draw ran against. If an enclosing
413    /// draw is still in progress (this draw was nested inside it), the clear is
414    /// deferred to the enclosing draw's own `ArenaClearNeeded` so that its live
415    /// allocations aren't freed.
416    ///
417    /// Panics if passed a different App than the draw ran against, since
418    /// clearing another App's arena could free memory its draws still
419    /// reference.
420    pub fn clear(self, cx: &mut App) {
421        assert!(
422            std::ptr::eq(self.arena, &cx.element_arena),
423            "ArenaClearNeeded::clear called with a different App than the draw ran against"
424        );
425        cx.element_arena.borrow_mut().clear();
426    }
427}
428
429pub(crate) type FocusMap = RwLock<SlotMap<FocusId, FocusRef>>;
430pub(crate) struct FocusRef {
431    pub(crate) ref_count: AtomicUsize,
432    pub(crate) tab_index: isize,
433    pub(crate) tab_stop: bool,
434}
435
436impl FocusId {
437    /// Obtains whether the element associated with this handle is currently focused.
438    pub fn is_focused(&self, window: &Window) -> bool {
439        window.focus == Some(*self)
440    }
441
442    /// Obtains whether the element associated with this handle contains the focused
443    /// element or is itself focused.
444    pub fn contains_focused(&self, window: &Window, cx: &App) -> bool {
445        window
446            .focused(cx)
447            .is_some_and(|focused| self.contains(focused.id, window))
448    }
449
450    /// Obtains whether the element associated with this handle is contained within the
451    /// focused element or is itself focused.
452    pub fn within_focused(&self, window: &Window, cx: &App) -> bool {
453        let focused = window.focused(cx);
454        focused.is_some_and(|focused| focused.id.contains(*self, window))
455    }
456
457    /// Obtains whether this handle contains the given handle in the most recently rendered frame.
458    pub(crate) fn contains(&self, other: Self, window: &Window) -> bool {
459        window
460            .rendered_frame
461            .dispatch_tree
462            .focus_contains(*self, other)
463    }
464}
465
466/// A handle which can be used to track and manipulate the focused element in a window.
467pub struct FocusHandle {
468    pub(crate) id: FocusId,
469    handles: Arc<FocusMap>,
470    /// The index of this element in the tab order.
471    pub tab_index: isize,
472    /// Whether this element can be focused by tab navigation.
473    pub tab_stop: bool,
474}
475
476impl std::fmt::Debug for FocusHandle {
477    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
478        f.write_fmt(format_args!("FocusHandle({:?})", self.id))
479    }
480}
481
482impl FocusHandle {
483    pub(crate) fn new(handles: &Arc<FocusMap>) -> Self {
484        let id = handles.write().insert(FocusRef {
485            ref_count: AtomicUsize::new(1),
486            tab_index: 0,
487            tab_stop: false,
488        });
489
490        Self {
491            id,
492            tab_index: 0,
493            tab_stop: false,
494            handles: handles.clone(),
495        }
496    }
497
498    pub(crate) fn for_id(id: FocusId, handles: &Arc<FocusMap>) -> Option<Self> {
499        let lock = handles.read();
500        let focus = lock.get(id)?;
501        if atomic_incr_if_not_zero(&focus.ref_count) == 0 {
502            return None;
503        }
504        Some(Self {
505            id,
506            tab_index: focus.tab_index,
507            tab_stop: focus.tab_stop,
508            handles: handles.clone(),
509        })
510    }
511
512    /// Sets the tab index of the element associated with this handle.
513    pub fn tab_index(mut self, index: isize) -> Self {
514        self.tab_index = index;
515        if let Some(focus) = self.handles.write().get_mut(self.id) {
516            focus.tab_index = index;
517        }
518        self
519    }
520
521    /// Sets whether the element associated with this handle is a tab stop.
522    ///
523    /// When `false`, the element will not be included in the tab order.
524    pub fn tab_stop(mut self, tab_stop: bool) -> Self {
525        self.tab_stop = tab_stop;
526        if let Some(focus) = self.handles.write().get_mut(self.id) {
527            focus.tab_stop = tab_stop;
528        }
529        self
530    }
531
532    /// Converts this focus handle into a weak variant, which does not prevent it from being released.
533    pub fn downgrade(&self) -> WeakFocusHandle {
534        WeakFocusHandle {
535            id: self.id,
536            handles: Arc::downgrade(&self.handles),
537        }
538    }
539
540    /// Moves the focus to the element associated with this handle.
541    pub fn focus(&self, window: &mut Window, cx: &mut App) {
542        window.focus(self, cx)
543    }
544
545    /// Obtains whether the element associated with this handle is currently focused.
546    pub fn is_focused(&self, window: &Window) -> bool {
547        self.id.is_focused(window)
548    }
549
550    /// Obtains whether the element associated with this handle contains the focused
551    /// element or is itself focused.
552    pub fn contains_focused(&self, window: &Window, cx: &App) -> bool {
553        self.id.contains_focused(window, cx)
554    }
555
556    /// Obtains whether the element associated with this handle is contained within the
557    /// focused element or is itself focused.
558    pub fn within_focused(&self, window: &Window, cx: &mut App) -> bool {
559        self.id.within_focused(window, cx)
560    }
561
562    /// Obtains whether this handle contains the given handle in the most recently rendered frame.
563    pub fn contains(&self, other: &Self, window: &Window) -> bool {
564        self.id.contains(other.id, window)
565    }
566
567    /// Dispatch an action on the element that rendered this focus handle
568    pub fn dispatch_action(&self, action: &dyn Action, window: &mut Window, cx: &mut App) {
569        if let Some(node_id) = window
570            .rendered_frame
571            .dispatch_tree
572            .focusable_node_id(self.id)
573        {
574            window.dispatch_action_on_node(node_id, action, cx)
575        }
576    }
577}
578
579impl Clone for FocusHandle {
580    fn clone(&self) -> Self {
581        Self::for_id(self.id, &self.handles).unwrap()
582    }
583}
584
585impl PartialEq for FocusHandle {
586    fn eq(&self, other: &Self) -> bool {
587        self.id == other.id
588    }
589}
590
591impl Eq for FocusHandle {}
592
593impl Drop for FocusHandle {
594    fn drop(&mut self) {
595        self.handles
596            .read()
597            .get(self.id)
598            .unwrap()
599            .ref_count
600            .fetch_sub(1, SeqCst);
601    }
602}
603
604/// A weak reference to a focus handle.
605#[derive(Clone, Debug)]
606pub struct WeakFocusHandle {
607    pub(crate) id: FocusId,
608    pub(crate) handles: Weak<FocusMap>,
609}
610
611impl WeakFocusHandle {
612    /// Attempts to upgrade the [WeakFocusHandle] to a [FocusHandle].
613    pub fn upgrade(&self) -> Option<FocusHandle> {
614        let handles = self.handles.upgrade()?;
615        FocusHandle::for_id(self.id, &handles)
616    }
617}
618
619impl PartialEq for WeakFocusHandle {
620    fn eq(&self, other: &WeakFocusHandle) -> bool {
621        self.id == other.id
622    }
623}
624
625impl Eq for WeakFocusHandle {}
626
627impl PartialEq<FocusHandle> for WeakFocusHandle {
628    fn eq(&self, other: &FocusHandle) -> bool {
629        self.id == other.id
630    }
631}
632
633impl PartialEq<WeakFocusHandle> for FocusHandle {
634    fn eq(&self, other: &WeakFocusHandle) -> bool {
635        self.id == other.id
636    }
637}
638
639/// Focusable allows users of your view to easily
640/// focus it (using window.focus_view(cx, view))
641pub trait Focusable: 'static {
642    /// Returns the focus handle associated with this view.
643    fn focus_handle(&self, cx: &App) -> FocusHandle;
644}
645
646impl<V: Focusable> Focusable for Entity<V> {
647    fn focus_handle(&self, cx: &App) -> FocusHandle {
648        self.read(cx).focus_handle(cx)
649    }
650}
651
652/// ManagedView is a view (like a Modal, Popover, Menu, etc.)
653/// where the lifecycle of the view is handled by another view.
654pub trait ManagedView: Focusable + EventEmitter<DismissEvent> + Render {}
655
656impl<M: Focusable + EventEmitter<DismissEvent> + Render> ManagedView for M {}
657
658/// Emitted by implementers of [`ManagedView`] to indicate the view should be dismissed, such as when a view is presented as a modal.
659pub struct DismissEvent;
660
661type FrameCallback = Box<dyn FnOnce(&mut Window, &mut App)>;
662
663pub(crate) type AnyMouseListener =
664    Box<dyn FnMut(&dyn Any, DispatchPhase, &mut Window, &mut App) + 'static>;
665
666#[derive(Clone)]
667pub(crate) struct CursorStyleRequest {
668    pub(crate) hitbox_id: Option<HitboxId>,
669    pub(crate) style: CursorStyle,
670}
671
672#[derive(Default, Eq, PartialEq)]
673pub(crate) struct HitTest {
674    pub(crate) ids: SmallVec<[HitboxId; 8]>,
675    pub(crate) hover_hitbox_count: usize,
676}
677
678/// A type of window control area that corresponds to the platform window.
679#[derive(Clone, Copy, Debug, Eq, PartialEq)]
680pub enum WindowControlArea {
681    /// An area that allows dragging of the platform window.
682    Drag,
683    /// An area that allows closing of the platform window.
684    Close,
685    /// An area that allows maximizing of the platform window.
686    Max,
687    /// An area that allows minimizing of the platform window.
688    Min,
689}
690
691/// An identifier for a [Hitbox] which also includes [HitboxBehavior].
692#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
693pub struct HitboxId(u64);
694
695#[cfg(feature = "test-support")]
696impl HitboxId {
697    /// A placeholder HitboxId exclusively for integration testing API's that
698    /// need a hitbox but where the value of the hitbox does not matter. The
699    /// alternative is to make the Hitbox optional but that complicates the
700    /// implementation.
701    pub const fn placeholder() -> Self {
702        Self(0)
703    }
704}
705
706impl HitboxId {
707    /// Checks if the hitbox with this ID is currently hovered. Returns `false` during keyboard
708    /// input modality so that keyboard navigation suppresses hover highlights. Except when handling
709    /// `ScrollWheelEvent`, this is typically what you want when determining whether to handle mouse
710    /// events or paint hover styles.
711    ///
712    /// See [`Hitbox::is_hovered`] for details.
713    pub fn is_hovered(self, window: &Window) -> bool {
714        // If this hitbox has captured the pointer, it's always considered hovered
715        if window.captured_hitbox == Some(self) {
716            return true;
717        }
718        if window.last_input_was_keyboard() {
719            return false;
720        }
721        self.hit_test(window)
722    }
723
724    /// Checks if the hitbox with this ID is currently hovered, regardless of the last
725    /// input modality used.
726    ///
727    /// See [`HitboxId::is_hovered`] for more details.
728    pub(crate) fn is_hovered_ignoring_last_input(self, window: &Window) -> bool {
729        // If this hitbox has captured the pointer, it's always considered hovered
730        if window.captured_hitbox == Some(self) {
731            return true;
732        }
733        self.hit_test(window)
734    }
735
736    fn hit_test(self, window: &Window) -> bool {
737        let hit_test = &window.mouse_hit_test;
738        for id in hit_test.ids.iter().take(hit_test.hover_hitbox_count) {
739            if self == *id {
740                return true;
741            }
742        }
743        false
744    }
745
746    /// Checks if the hitbox with this ID contains the mouse and should handle scroll events.
747    /// Typically this should only be used when handling `ScrollWheelEvent`, and otherwise
748    /// `is_hovered` should be used. See the documentation of `Hitbox::is_hovered` for details about
749    /// this distinction.
750    pub fn should_handle_scroll(self, window: &Window) -> bool {
751        window.mouse_hit_test.ids.contains(&self)
752    }
753
754    fn next(mut self) -> HitboxId {
755        HitboxId(self.0.wrapping_add(1))
756    }
757}
758
759/// A rectangular region that potentially blocks hitboxes inserted prior.
760/// See [Window::insert_hitbox] for more details.
761#[derive(Clone, Debug, Deref)]
762pub struct Hitbox {
763    /// A unique identifier for the hitbox.
764    pub id: HitboxId,
765    /// The bounds of the hitbox.
766    #[deref]
767    pub bounds: Bounds<Pixels>,
768    /// The content mask when the hitbox was inserted.
769    pub content_mask: ContentMask<Pixels>,
770    /// Flags that specify hitbox behavior.
771    pub behavior: HitboxBehavior,
772}
773
774impl Hitbox {
775    /// Checks if the hitbox is currently hovered. Returns `false` during keyboard input modality
776    /// so that keyboard navigation suppresses hover highlights. Except when handling
777    /// `ScrollWheelEvent`, this is typically what you want when determining whether to handle mouse
778    /// events or paint hover styles.
779    ///
780    /// This can return `false` even when the hitbox contains the mouse, if a hitbox in front of
781    /// this sets `HitboxBehavior::BlockMouse` (`InteractiveElement::occlude`) or
782    /// `HitboxBehavior::BlockMouseExceptScroll` (`InteractiveElement::block_mouse_except_scroll`),
783    /// or if the current input modality is keyboard (see [`Window::last_input_was_keyboard`]).
784    ///
785    /// Handling of `ScrollWheelEvent` should typically use `should_handle_scroll` instead.
786    /// Concretely, this is due to use-cases like overlays that cause the elements under to be
787    /// non-interactive while still allowing scrolling. More abstractly, this is because
788    /// `is_hovered` is about element interactions directly under the mouse - mouse moves, clicks,
789    /// hover styling, etc. In contrast, scrolling is about finding the current outer scrollable
790    /// container.
791    pub fn is_hovered(&self, window: &Window) -> bool {
792        self.id.is_hovered(window)
793    }
794
795    /// Checks if the hitbox contains the mouse and should handle scroll events. Typically this
796    /// should only be used when handling `ScrollWheelEvent`, and otherwise `is_hovered` should be
797    /// used. See the documentation of `Hitbox::is_hovered` for details about this distinction.
798    ///
799    /// This can return `false` even when the hitbox contains the mouse, if a hitbox in front of
800    /// this sets `HitboxBehavior::BlockMouse` (`InteractiveElement::occlude`).
801    pub fn should_handle_scroll(&self, window: &Window) -> bool {
802        self.id.should_handle_scroll(window)
803    }
804}
805
806/// How the hitbox affects mouse behavior.
807#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
808pub enum HitboxBehavior {
809    /// Normal hitbox mouse behavior, doesn't affect mouse handling for other hitboxes.
810    #[default]
811    Normal,
812
813    /// All hitboxes behind this hitbox will be ignored and so will have `hitbox.is_hovered() ==
814    /// false` and `hitbox.should_handle_scroll() == false`. Typically for elements this causes
815    /// skipping of all mouse events, hover styles, and tooltips. This flag is set by
816    /// [`InteractiveElement::occlude`].
817    ///
818    /// For mouse handlers that check those hitboxes, this behaves the same as registering a
819    /// bubble-phase handler for every mouse event type:
820    ///
821    /// ```ignore
822    /// window.on_mouse_event(move |_: &EveryMouseEventTypeHere, phase, window, cx| {
823    ///     if phase == DispatchPhase::Capture && hitbox.is_hovered(window) {
824    ///         cx.stop_propagation();
825    ///     }
826    /// })
827    /// ```
828    ///
829    /// This has effects beyond event handling - any use of hitbox checking, such as hover
830    /// styles and tooltips. These other behaviors are the main point of this mechanism. An
831    /// alternative might be to not affect mouse event handling - but this would allow
832    /// inconsistent UI where clicks and moves interact with elements that are not considered to
833    /// be hovered.
834    BlockMouse,
835
836    /// All hitboxes behind this hitbox will have `hitbox.is_hovered() == false`, even when
837    /// `hitbox.should_handle_scroll() == true`. Typically for elements this causes all mouse
838    /// interaction except scroll events to be ignored - see the documentation of
839    /// [`Hitbox::is_hovered`] for details. This flag is set by
840    /// [`InteractiveElement::block_mouse_except_scroll`].
841    ///
842    /// For mouse handlers that check those hitboxes, this behaves the same as registering a
843    /// bubble-phase handler for every mouse event type **except** `ScrollWheelEvent`:
844    ///
845    /// ```ignore
846    /// window.on_mouse_event(move |_: &EveryMouseEventTypeExceptScroll, phase, window, cx| {
847    ///     if phase == DispatchPhase::Bubble && hitbox.should_handle_scroll(window) {
848    ///         cx.stop_propagation();
849    ///     }
850    /// })
851    /// ```
852    ///
853    /// See the documentation of [`Hitbox::is_hovered`] for details of why `ScrollWheelEvent` is
854    /// handled differently than other mouse events. If also blocking these scroll events is
855    /// desired, then a `cx.stop_propagation()` handler like the one above can be used.
856    ///
857    /// This has effects beyond event handling - this affects any use of `is_hovered`, such as
858    /// hover styles and tooltips. These other behaviors are the main point of this mechanism.
859    /// An alternative might be to not affect mouse event handling - but this would allow
860    /// inconsistent UI where clicks and moves interact with elements that are not considered to
861    /// be hovered.
862    BlockMouseExceptScroll,
863}
864
865/// An identifier for a tooltip.
866#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
867pub struct TooltipId(usize);
868
869impl TooltipId {
870    /// Checks if the tooltip is currently hovered.
871    pub fn is_hovered(&self, window: &Window) -> bool {
872        window
873            .tooltip_bounds
874            .as_ref()
875            .is_some_and(|tooltip_bounds| {
876                tooltip_bounds.id == *self
877                    && tooltip_bounds.bounds.contains(&window.mouse_position())
878            })
879    }
880}
881
882pub(crate) struct TooltipBounds {
883    id: TooltipId,
884    bounds: Bounds<Pixels>,
885}
886
887#[derive(Clone)]
888pub(crate) struct TooltipRequest {
889    id: TooltipId,
890    tooltip: AnyTooltip,
891}
892
893pub(crate) struct DeferredDraw {
894    current_view: EntityId,
895    priority: usize,
896    parent_node: DispatchNodeId,
897    element_id_stack: SmallVec<[ElementId; 32]>,
898    text_style_stack: Vec<TextStyleRefinement>,
899    content_mask: Option<ContentMask<Pixels>>,
900    rem_size: Pixels,
901    element: Option<AnyElement>,
902    absolute_offset: Point<Pixels>,
903    prepaint_range: Range<PrepaintStateIndex>,
904    paint_range: Range<PaintIndex>,
905}
906
907pub(crate) struct Frame {
908    pub(crate) focus: Option<FocusId>,
909    pub(crate) window_active: bool,
910    pub(crate) element_states: FxHashMap<(GlobalElementId, TypeId), ElementStateBox>,
911    accessed_element_states: Vec<(GlobalElementId, TypeId)>,
912    pub(crate) mouse_listeners: Vec<Option<AnyMouseListener>>,
913    pub(crate) dispatch_tree: DispatchTree,
914    pub(crate) scene: Scene,
915    pub(crate) hitboxes: Vec<Hitbox>,
916    pub(crate) window_control_hitboxes: Vec<(WindowControlArea, Hitbox)>,
917    pub(crate) deferred_draws: Vec<DeferredDraw>,
918    pub(crate) input_handlers: Vec<Option<PlatformInputHandler>>,
919    pub(crate) tooltip_requests: Vec<Option<TooltipRequest>>,
920    pub(crate) cursor_styles: Vec<CursorStyleRequest>,
921    #[cfg(any(test, feature = "test-support"))]
922    pub(crate) debug_bounds: FxHashMap<String, Bounds<Pixels>>,
923    #[cfg(any(feature = "inspector", debug_assertions))]
924    pub(crate) next_inspector_instance_ids: FxHashMap<Rc<crate::InspectorElementPath>, usize>,
925    #[cfg(any(feature = "inspector", debug_assertions))]
926    pub(crate) inspector_hitboxes: FxHashMap<HitboxId, crate::InspectorElementId>,
927    pub(crate) tab_stops: TabStopMap,
928}
929
930#[derive(Clone, Default)]
931pub(crate) struct PrepaintStateIndex {
932    hitboxes_index: usize,
933    tooltips_index: usize,
934    deferred_draws_index: usize,
935    dispatch_tree_index: usize,
936    accessed_element_states_index: usize,
937    line_layout_index: LineLayoutIndex,
938}
939
940#[derive(Clone, Default)]
941pub(crate) struct PaintIndex {
942    scene_index: usize,
943    mouse_listeners_index: usize,
944    input_handlers_index: usize,
945    cursor_styles_index: usize,
946    accessed_element_states_index: usize,
947    tab_handle_index: usize,
948    line_layout_index: LineLayoutIndex,
949}
950
951impl Frame {
952    pub(crate) fn new(dispatch_tree: DispatchTree) -> Self {
953        Frame {
954            focus: None,
955            window_active: false,
956            element_states: FxHashMap::default(),
957            accessed_element_states: Vec::new(),
958            mouse_listeners: Vec::new(),
959            dispatch_tree,
960            scene: Scene::default(),
961            hitboxes: Vec::new(),
962            window_control_hitboxes: Vec::new(),
963            deferred_draws: Vec::new(),
964            input_handlers: Vec::new(),
965            tooltip_requests: Vec::new(),
966            cursor_styles: Vec::new(),
967
968            #[cfg(any(test, feature = "test-support"))]
969            debug_bounds: FxHashMap::default(),
970
971            #[cfg(any(feature = "inspector", debug_assertions))]
972            next_inspector_instance_ids: FxHashMap::default(),
973
974            #[cfg(any(feature = "inspector", debug_assertions))]
975            inspector_hitboxes: FxHashMap::default(),
976            tab_stops: TabStopMap::default(),
977        }
978    }
979
980    pub(crate) fn clear(&mut self) {
981        self.element_states.clear();
982        self.accessed_element_states.clear();
983        self.mouse_listeners.clear();
984        self.dispatch_tree.clear();
985        self.scene.clear();
986        self.input_handlers.clear();
987        self.tooltip_requests.clear();
988        self.cursor_styles.clear();
989        self.hitboxes.clear();
990        self.window_control_hitboxes.clear();
991        self.deferred_draws.clear();
992        self.tab_stops.clear();
993        self.focus = None;
994
995        #[cfg(any(test, feature = "test-support"))]
996        {
997            self.debug_bounds.clear();
998        }
999
1000        #[cfg(any(feature = "inspector", debug_assertions))]
1001        {
1002            self.next_inspector_instance_ids.clear();
1003            self.inspector_hitboxes.clear();
1004        }
1005    }
1006
1007    pub(crate) fn cursor_style(&self, window: &Window) -> Option<CursorStyle> {
1008        self.cursor_styles
1009            .iter()
1010            .rev()
1011            .fold_while(None, |style, request| match request.hitbox_id {
1012                None => Done(Some(request.style)),
1013                Some(hitbox_id) => Continue(style.or_else(|| {
1014                    hitbox_id
1015                        .is_hovered_ignoring_last_input(window)
1016                        .then_some(request.style)
1017                })),
1018            })
1019            .into_inner()
1020    }
1021
1022    pub(crate) fn hit_test(&self, position: Point<Pixels>) -> HitTest {
1023        let mut set_hover_hitbox_count = false;
1024        let mut hit_test = HitTest::default();
1025        for hitbox in self.hitboxes.iter().rev() {
1026            let bounds = hitbox.bounds.intersect(&hitbox.content_mask.bounds);
1027            if bounds.contains(&position) {
1028                hit_test.ids.push(hitbox.id);
1029                if !set_hover_hitbox_count
1030                    && hitbox.behavior == HitboxBehavior::BlockMouseExceptScroll
1031                {
1032                    hit_test.hover_hitbox_count = hit_test.ids.len();
1033                    set_hover_hitbox_count = true;
1034                }
1035                if hitbox.behavior == HitboxBehavior::BlockMouse {
1036                    break;
1037                }
1038            }
1039        }
1040        if !set_hover_hitbox_count {
1041            hit_test.hover_hitbox_count = hit_test.ids.len();
1042        }
1043        hit_test
1044    }
1045
1046    pub(crate) fn focus_path(&self) -> SmallVec<[FocusId; 8]> {
1047        self.focus
1048            .map(|focus_id| self.dispatch_tree.focus_path(focus_id))
1049            .unwrap_or_default()
1050    }
1051
1052    pub(crate) fn finish(&mut self, prev_frame: &mut Self) {
1053        for element_state_key in &self.accessed_element_states {
1054            if let Some((element_state_key, element_state)) =
1055                prev_frame.element_states.remove_entry(element_state_key)
1056            {
1057                self.element_states.insert(element_state_key, element_state);
1058            }
1059        }
1060
1061        self.scene.finish();
1062    }
1063}
1064
1065#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
1066enum InputModality {
1067    Mouse,
1068    Keyboard,
1069    Touch,
1070}
1071
1072/// Holds the state for a specific window.
1073pub struct Window {
1074    pub(crate) handle: AnyWindowHandle,
1075    pub(crate) invalidator: WindowInvalidator,
1076    pub(crate) removed: bool,
1077    pub(crate) platform_window: Box<dyn PlatformWindow>,
1078    display_id: Option<DisplayId>,
1079    sprite_atlas: Arc<dyn PlatformAtlas>,
1080    text_system: Arc<WindowTextSystem>,
1081    text_rendering_mode: Rc<Cell<TextRenderingMode>>,
1082    rem_size: Pixels,
1083    /// The stack of override values for the window's rem size.
1084    ///
1085    /// This is used by `with_rem_size` to allow rendering an element tree with
1086    /// a given rem size.
1087    rem_size_override_stack: SmallVec<[Pixels; 8]>,
1088    pub(crate) viewport_size: Size<Pixels>,
1089    layout_engine: Option<TaffyLayoutEngine>,
1090    pub(crate) root: Option<AnyView>,
1091    pub(crate) element_id_stack: SmallVec<[ElementId; 32]>,
1092    pub(crate) text_style_stack: Vec<TextStyleRefinement>,
1093    pub(crate) rendered_entity_stack: Vec<EntityId>,
1094    pub(crate) element_offset_stack: Vec<Point<Pixels>>,
1095    pub(crate) element_opacity: f32,
1096    pub(crate) content_mask_stack: Vec<ContentMask<Pixels>>,
1097    pub(crate) requested_autoscroll: Option<Bounds<Pixels>>,
1098    pub(crate) image_cache_stack: Vec<AnyImageCache>,
1099    pub(crate) rendered_frame: Frame,
1100    pub(crate) next_frame: Frame,
1101    next_hitbox_id: HitboxId,
1102    pub(crate) next_tooltip_id: TooltipId,
1103    pub(crate) tooltip_bounds: Option<TooltipBounds>,
1104    next_frame_callbacks: Rc<RefCell<Vec<FrameCallback>>>,
1105    pub(crate) dirty_views: FxHashSet<EntityId>,
1106    focus_listeners: SubscriberSet<(), AnyWindowFocusListener>,
1107    pub(crate) focus_lost_listeners: SubscriberSet<(), AnyObserver>,
1108    default_prevented: bool,
1109    mouse_position: Point<Pixels>,
1110    mouse_hit_test: HitTest,
1111    modifiers: Modifiers,
1112    capslock: Capslock,
1113    scale_factor: f32,
1114    pub(crate) bounds_observers: SubscriberSet<(), AnyObserver>,
1115    appearance: WindowAppearance,
1116    pub(crate) appearance_observers: SubscriberSet<(), AnyObserver>,
1117    pub(crate) button_layout_observers: SubscriberSet<(), AnyObserver>,
1118    active: Rc<Cell<bool>>,
1119    hovered: Rc<Cell<bool>>,
1120    pub(crate) needs_present: Rc<Cell<bool>>,
1121    /// Tracks recent input event timestamps to determine if input is arriving at a high rate.
1122    /// Used to selectively enable VRR optimization only when input rate exceeds 60fps.
1123    pub(crate) input_rate_tracker: Rc<RefCell<InputRateTracker>>,
1124    #[cfg(feature = "input-latency-histogram")]
1125    input_latency_tracker: InputLatencyTracker,
1126    last_input_modality: InputModality,
1127    pub(crate) refreshing: bool,
1128    pub(crate) activation_observers: SubscriberSet<(), AnyObserver>,
1129    pub(crate) focus: Option<FocusId>,
1130    focus_enabled: bool,
1131    /// Incremented every time focus moves. Used to invalidate a
1132    /// pending keyboard activation state when focus changes.
1133    pub(crate) focus_generation: u64,
1134    pending_input: Option<PendingInput>,
1135    pending_modifier: ModifierState,
1136    pub(crate) pending_input_observers: SubscriberSet<(), AnyObserver>,
1137    prompt: Option<RenderablePromptHandle>,
1138    pub(crate) client_inset: Option<Pixels>,
1139    /// The hitbox that has captured the pointer, if any.
1140    /// While captured, mouse events route to this hitbox regardless of hit testing.
1141    captured_hitbox: Option<HitboxId>,
1142    #[cfg(any(feature = "inspector", debug_assertions))]
1143    inspector: Option<Entity<Inspector>>,
1144    pub(crate) a11y: A11y,
1145}
1146
1147#[derive(Clone, Debug, Default)]
1148struct ModifierState {
1149    modifiers: Modifiers,
1150    saw_keystroke: bool,
1151}
1152
1153/// Tracks input event timestamps to determine if input is arriving at a high rate.
1154/// Used for selective VRR (Variable Refresh Rate) optimization.
1155#[derive(Clone, Debug)]
1156pub(crate) struct InputRateTracker {
1157    timestamps: Vec<Instant>,
1158    window: Duration,
1159    inputs_per_second: u32,
1160    sustain_until: Instant,
1161    sustain_duration: Duration,
1162}
1163
1164impl Default for InputRateTracker {
1165    fn default() -> Self {
1166        Self {
1167            timestamps: Vec::new(),
1168            window: Duration::from_millis(100),
1169            inputs_per_second: 60,
1170            sustain_until: Instant::now(),
1171            sustain_duration: Duration::from_secs(1),
1172        }
1173    }
1174}
1175
1176impl InputRateTracker {
1177    pub fn record_input(&mut self) {
1178        let now = Instant::now();
1179        self.timestamps.push(now);
1180        self.prune_old_timestamps(now);
1181
1182        let min_events = self.inputs_per_second as u128 * self.window.as_millis() / 1000;
1183        if self.timestamps.len() as u128 >= min_events {
1184            self.sustain_until = now + self.sustain_duration;
1185        }
1186    }
1187
1188    pub fn is_high_rate(&self) -> bool {
1189        Instant::now() < self.sustain_until
1190    }
1191
1192    fn prune_old_timestamps(&mut self, now: Instant) {
1193        self.timestamps
1194            .retain(|&t| now.duration_since(t) <= self.window);
1195    }
1196}
1197
1198/// A point-in-time snapshot of the input-latency histograms for a window,
1199/// suitable for external formatting.
1200#[cfg(feature = "input-latency-histogram")]
1201pub struct InputLatencySnapshot {
1202    /// Histogram of input-to-frame latency samples, in nanoseconds.
1203    pub latency_histogram: Histogram<u64>,
1204    /// Histogram of input events coalesced per rendered frame.
1205    pub events_per_frame_histogram: Histogram<u64>,
1206    /// Count of input events that arrived mid-draw and were excluded from
1207    /// latency recording.
1208    pub mid_draw_events_dropped: u64,
1209}
1210
1211/// Records the time between when the first input event in a frame is dispatched
1212/// and when the resulting frame is presented, capturing worst-case latency when
1213/// multiple events are coalesced into a single frame.
1214#[cfg(feature = "input-latency-histogram")]
1215struct InputLatencyTracker {
1216    /// Timestamp of the first unrendered input event in the current frame;
1217    /// cleared when a frame is presented.
1218    first_input_at: Option<Instant>,
1219    /// Count of input events received since the last frame was presented.
1220    pending_input_count: u64,
1221    /// Histogram of input-to-frame latency samples, in nanoseconds.
1222    latency_histogram: Histogram<u64>,
1223    /// Histogram of input events coalesced per rendered frame.
1224    events_per_frame_histogram: Histogram<u64>,
1225    /// Count of input events that arrived mid-draw and were excluded from
1226    /// latency recording because their effects won't appear until the next frame.
1227    mid_draw_events_dropped: u64,
1228}
1229
1230#[cfg(feature = "input-latency-histogram")]
1231impl InputLatencyTracker {
1232    fn new() -> Result<Self> {
1233        Ok(Self {
1234            first_input_at: None,
1235            pending_input_count: 0,
1236            latency_histogram: Histogram::new(3)
1237                .map_err(|e| anyhow!("Failed to create input latency histogram: {e}"))?,
1238            events_per_frame_histogram: Histogram::new(3)
1239                .map_err(|e| anyhow!("Failed to create events per frame histogram: {e}"))?,
1240            mid_draw_events_dropped: 0,
1241        })
1242    }
1243
1244    /// Record that an input event was dispatched at the given time.
1245    /// Only the first event's timestamp per frame is retained (worst-case latency).
1246    fn record_input(&mut self, dispatch_time: Instant) {
1247        self.first_input_at.get_or_insert(dispatch_time);
1248        self.pending_input_count += 1;
1249    }
1250
1251    /// Record that an input event arrived during a draw phase and was excluded
1252    /// from latency tracking.
1253    fn record_mid_draw_input(&mut self) {
1254        self.mid_draw_events_dropped += 1;
1255    }
1256
1257    /// Record that a frame was presented, flushing pending latency and coalescing samples.
1258    fn record_frame_presented(&mut self) {
1259        if let Some(first_input_at) = self.first_input_at.take() {
1260            let latency_nanos = first_input_at.elapsed().as_nanos() as u64;
1261            self.latency_histogram.record(latency_nanos).ok();
1262        }
1263        if self.pending_input_count > 0 {
1264            self.events_per_frame_histogram
1265                .record(self.pending_input_count)
1266                .ok();
1267            self.pending_input_count = 0;
1268        }
1269    }
1270
1271    fn snapshot(&self) -> InputLatencySnapshot {
1272        InputLatencySnapshot {
1273            latency_histogram: self.latency_histogram.clone(),
1274            events_per_frame_histogram: self.events_per_frame_histogram.clone(),
1275            mid_draw_events_dropped: self.mid_draw_events_dropped,
1276        }
1277    }
1278}
1279
1280#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1281pub(crate) enum DrawPhase {
1282    None,
1283    Prepaint,
1284    Paint,
1285    Focus,
1286}
1287
1288#[derive(Default, Debug)]
1289struct PendingInput {
1290    keystrokes: SmallVec<[Keystroke; 1]>,
1291    focus: Option<FocusId>,
1292    timer: Option<Task<()>>,
1293    needs_timeout: bool,
1294}
1295
1296pub(crate) struct ElementStateBox {
1297    pub(crate) inner: Box<dyn Any>,
1298    #[cfg(debug_assertions)]
1299    pub(crate) type_name: &'static str,
1300}
1301
1302fn default_bounds(display_id: Option<DisplayId>, cx: &mut App) -> WindowBounds {
1303    // TODO, BUG: if you open a window with the currently active window
1304    // on the stack, this will erroneously fallback to `None`
1305    //
1306    // TODO these should be the initial window bounds not considering maximized/fullscreen
1307    let active_window_bounds = cx
1308        .active_window()
1309        .and_then(|w| w.update(cx, |_, window, _| window.window_bounds()).ok());
1310
1311    const CASCADE_OFFSET: f32 = 25.0;
1312
1313    let display = display_id
1314        .map(|id| cx.find_display(id))
1315        .unwrap_or_else(|| cx.primary_display());
1316
1317    let default_placement = || Bounds::new(point(px(0.), px(0.)), DEFAULT_WINDOW_SIZE);
1318
1319    // Use visible_bounds to exclude taskbar/dock areas
1320    let display_bounds = display
1321        .as_ref()
1322        .map(|d| d.visible_bounds())
1323        .unwrap_or_else(default_placement);
1324
1325    let (
1326        Bounds {
1327            origin: base_origin,
1328            size: base_size,
1329        },
1330        window_bounds_ctor,
1331    ): (_, fn(Bounds<Pixels>) -> WindowBounds) = match active_window_bounds {
1332        Some(bounds) => match bounds {
1333            WindowBounds::Windowed(bounds) => (bounds, WindowBounds::Windowed),
1334            WindowBounds::Maximized(bounds) => (bounds, WindowBounds::Maximized),
1335            WindowBounds::Fullscreen(bounds) => (bounds, WindowBounds::Fullscreen),
1336        },
1337        None => (
1338            display
1339                .as_ref()
1340                .map(|d| d.default_bounds())
1341                .unwrap_or_else(default_placement),
1342            WindowBounds::Windowed,
1343        ),
1344    };
1345
1346    let cascade_offset = point(px(CASCADE_OFFSET), px(CASCADE_OFFSET));
1347    let proposed_origin = base_origin + cascade_offset;
1348    let proposed_bounds = Bounds::new(proposed_origin, base_size);
1349
1350    let display_right = display_bounds.origin.x + display_bounds.size.width;
1351    let display_bottom = display_bounds.origin.y + display_bounds.size.height;
1352    let window_right = proposed_bounds.origin.x + proposed_bounds.size.width;
1353    let window_bottom = proposed_bounds.origin.y + proposed_bounds.size.height;
1354
1355    let fits_horizontally = window_right <= display_right;
1356    let fits_vertically = window_bottom <= display_bottom;
1357
1358    let final_origin = match (fits_horizontally, fits_vertically) {
1359        (true, true) => proposed_origin,
1360        (false, true) => point(display_bounds.origin.x, base_origin.y),
1361        (true, false) => point(base_origin.x, display_bounds.origin.y),
1362        (false, false) => display_bounds.origin,
1363    };
1364    window_bounds_ctor(Bounds::new(final_origin, base_size))
1365}
1366
1367impl Window {
1368    pub(crate) fn new(
1369        handle: AnyWindowHandle,
1370        options: WindowOptions,
1371        cx: &mut App,
1372    ) -> Result<Self> {
1373        let WindowOptions {
1374            window_bounds,
1375            titlebar,
1376            focus,
1377            show,
1378            kind,
1379            is_movable,
1380            app_owns_titlebar_drag,
1381            is_resizable,
1382            is_minimizable,
1383            display_id,
1384            window_background,
1385            app_id,
1386            window_min_size,
1387            window_decorations,
1388            #[cfg_attr(
1389                not(any(target_os = "linux", target_os = "freebsd")),
1390                allow(unused_variables)
1391            )]
1392            icon,
1393            #[cfg_attr(not(target_os = "macos"), allow(unused_variables))]
1394            tabbing_identifier,
1395        } = options;
1396
1397        let initial_window_title = titlebar
1398            .as_ref()
1399            .and_then(|titlebar| titlebar.title.clone());
1400
1401        let window_bounds = window_bounds.unwrap_or_else(|| default_bounds(display_id, cx));
1402        let mut platform_window = cx.platform.open_window(
1403            handle,
1404            WindowParams {
1405                bounds: window_bounds.get_bounds(),
1406                titlebar,
1407                kind,
1408                is_movable,
1409                app_owns_titlebar_drag,
1410                is_resizable,
1411                is_minimizable,
1412                focus,
1413                show,
1414                display_id,
1415                window_min_size,
1416                app_id: app_id.clone(),
1417                icon,
1418                #[cfg(target_os = "macos")]
1419                tabbing_identifier,
1420            },
1421        )?;
1422
1423        let tab_bar_visible = platform_window.tab_bar_visible();
1424        SystemWindowTabController::init_visible(cx, tab_bar_visible);
1425        if let Some(tabs) = platform_window.tabbed_windows() {
1426            SystemWindowTabController::add_tab(cx, handle.window_id(), tabs);
1427        }
1428
1429        let display_id = platform_window.display().map(|display| display.id());
1430        let sprite_atlas = platform_window.sprite_atlas();
1431        let mouse_position = platform_window.mouse_position();
1432        let modifiers = platform_window.modifiers();
1433        let capslock = platform_window.capslock();
1434        let content_size = platform_window.content_size();
1435        let scale_factor = platform_window.scale_factor();
1436        let appearance = platform_window.appearance();
1437        let text_system = Arc::new(WindowTextSystem::new(cx.text_system().clone()));
1438        let invalidator = WindowInvalidator::new();
1439        let active = Rc::new(Cell::new(platform_window.is_active()));
1440        let hovered = Rc::new(Cell::new(platform_window.is_hovered()));
1441        let needs_present = Rc::new(Cell::new(false));
1442        let next_frame_callbacks: Rc<RefCell<Vec<FrameCallback>>> = Default::default();
1443        let input_rate_tracker = Rc::new(RefCell::new(InputRateTracker::default()));
1444        let last_frame_time = Rc::new(Cell::new(None));
1445
1446        platform_window
1447            .request_decorations(window_decorations.unwrap_or(WindowDecorations::Server));
1448        platform_window.set_background_appearance(window_background);
1449
1450        match window_bounds {
1451            WindowBounds::Fullscreen(_) => platform_window.toggle_fullscreen(),
1452            WindowBounds::Maximized(_) => platform_window.zoom(),
1453            WindowBounds::Windowed(_) => {}
1454        }
1455
1456        let accessibility_force_disabled = cx.accessibility_force_disabled;
1457        let a11y_active_flag = Arc::new(AtomicBool::new(false));
1458
1459        #[cfg(not(target_family = "wasm"))]
1460        if !accessibility_force_disabled {
1461            let mut initial_root_node = accesskit::Node::new(accesskit::Role::Window);
1462            if let Some(title) = &initial_window_title {
1463                initial_root_node.set_label(title.to_string());
1464            }
1465            let initial_tree = accesskit::TreeUpdate {
1466                nodes: vec![(ROOT_NODE_ID, initial_root_node)],
1467                tree: Some(accesskit::Tree::new(ROOT_NODE_ID)),
1468                tree_id: accesskit::TreeId::ROOT,
1469                focus: ROOT_NODE_ID,
1470            };
1471            let (activation_sender, activation_receiver) = async_channel::unbounded::<()>();
1472            let (deactivation_sender, deactivation_receiver) = async_channel::unbounded::<()>();
1473            let (action_sender, action_receiver) =
1474                async_channel::unbounded::<accesskit::ActionRequest>();
1475
1476            platform_window.a11y_init(crate::A11yCallbacks {
1477                activation: {
1478                    let active_flag = a11y_active_flag.clone();
1479                    Box::new(move || {
1480                        log::info!("Accessibility activated");
1481                        active_flag.store(true, SeqCst);
1482                        activation_sender.send_blocking(()).log_err();
1483                        Some(initial_tree.clone())
1484                    })
1485                },
1486                action: Box::new(move |request| {
1487                    action_sender.send_blocking(request).log_err();
1488                }),
1489                deactivation: {
1490                    let active_flag = a11y_active_flag.clone();
1491                    Box::new(move || {
1492                        log::info!("Accessibility deactivated");
1493                        active_flag.store(false, SeqCst);
1494                        deactivation_sender.send_blocking(()).log_err();
1495                    })
1496                },
1497            });
1498
1499            // A11y can be activated at any time, and so we cannot compute a
1500            // correct `TreeUpdate` on-demand. When this happens, we return a
1501            // default empty `TreeUpdate`.
1502            //
1503            // So we force a new frame, which will then send a correct `TreeUpdate`.
1504            let mut async_cx = cx.to_async();
1505            cx.foreground_executor()
1506                .spawn(async move {
1507                    while activation_receiver.recv().await.is_ok() {
1508                        handle
1509                            .update(&mut async_cx, |_, window, _| window.refresh())
1510                            .log_err();
1511                    }
1512                })
1513                .detach();
1514
1515            let mut async_cx = cx.to_async();
1516            cx.foreground_executor()
1517                .spawn(async move {
1518                    while deactivation_receiver.recv().await.is_ok() {
1519                        handle
1520                            .update(&mut async_cx, |_, window, _| window.refresh())
1521                            .log_err();
1522                    }
1523                })
1524                .detach();
1525
1526            let mut async_cx = cx.to_async();
1527            cx.foreground_executor()
1528                .spawn(async move {
1529                    while let Ok(request) = action_receiver.recv().await {
1530                        handle
1531                            .update(&mut async_cx, |_, window, cx| {
1532                                window.handle_a11y_action(request, cx);
1533                            })
1534                            .log_err();
1535                    }
1536                })
1537                .detach();
1538        }
1539
1540        platform_window.on_close(Box::new({
1541            let window_id = handle.window_id();
1542            let mut cx = cx.to_async();
1543            move || {
1544                let _ = handle.update(&mut cx, |_, window, _| window.remove_window());
1545                let _ = cx.update(|cx| {
1546                    SystemWindowTabController::remove_tab(cx, window_id);
1547                });
1548            }
1549        }));
1550        platform_window.on_request_frame(Box::new({
1551            let mut cx = cx.to_async();
1552            let invalidator = invalidator.clone();
1553            let active = active.clone();
1554            let needs_present = needs_present.clone();
1555            let next_frame_callbacks = next_frame_callbacks.clone();
1556            let input_rate_tracker = input_rate_tracker.clone();
1557            let mut deferred_force_render = false;
1558            move |request_frame_options| {
1559                // This must be checked before anything else: if this request
1560                // arrived re-entrantly while a draw is on this thread's stack
1561                // (e.g. via a nested message pump in the Windows window
1562                // procedure), drawing would nest draws, and even touching the
1563                // App would panic on its already-mutable borrow. Skip instead;
1564                // the platform leaves the window invalidated (or re-invalidates
1565                // it), so a fresh request arrives once the in-progress draw
1566                // unwinds. Remember force_render so the deferred frame still
1567                // bypasses the view cache.
1568                //
1569                // Returning here skips `complete_frame`, which on Wayland would
1570                // stall the window's frame callbacks (no `surface.commit()`) —
1571                // but calling it would hit the App borrow panic above, and this
1572                // branch is unreachable there in practice: only Windows pumps
1573                // platform events (and thus requests frames) mid-draw.
1574                if draw_in_progress() {
1575                    log::debug!("deferring re-entrant window draw request");
1576                    deferred_force_render |= request_frame_options.force_render;
1577                    return;
1578                }
1579                // Take the deferred flag first: `||` short-circuits, and leaving
1580                // the flag set when this request already forces a render would
1581                // force a second, redundant render on the next frame.
1582                let force_render =
1583                    mem::take(&mut deferred_force_render) || request_frame_options.force_render;
1584
1585                let thermal_state = handle
1586                    .update(&mut cx, |_, _, cx| cx.thermal_state())
1587                    .log_err();
1588
1589                // Throttle frame rate based on conditions:
1590                // - Thermal pressure (Serious/Critical): cap to ~60fps
1591                // - Inactive window (not focused): cap to ~30fps to save energy
1592                let min_frame_interval = if !force_render
1593                    && !request_frame_options.require_presentation
1594                    && next_frame_callbacks.borrow().is_empty()
1595                {
1596                    None
1597                } else if !active.get() {
1598                    Some(Duration::from_micros(33333))
1599                } else if let Some(ThermalState::Critical | ThermalState::Serious) = thermal_state {
1600                    Some(Duration::from_micros(16667))
1601                } else {
1602                    None
1603                };
1604
1605                let now = Instant::now();
1606                if let Some(min_interval) = min_frame_interval {
1607                    if let Some(last_frame) = last_frame_time.get()
1608                        && now.duration_since(last_frame) < min_interval
1609                    {
1610                        // Don't lose a pending forced render to throttling.
1611                        deferred_force_render |= force_render;
1612                        // Must still complete the frame on platforms that require it.
1613                        // On Wayland, `surface.frame()` was already called to request the
1614                        // next frame callback, so we must call `surface.commit()` (via
1615                        // `complete_frame`) or the compositor won't send another callback.
1616                        handle
1617                            .update(&mut cx, |_, window, _| window.complete_frame())
1618                            .log_err();
1619                        return;
1620                    }
1621                }
1622                last_frame_time.set(Some(now));
1623
1624                let next_frame_callbacks = next_frame_callbacks.take();
1625                if !next_frame_callbacks.is_empty() {
1626                    handle
1627                        .update(&mut cx, |_, window, cx| {
1628                            for callback in next_frame_callbacks {
1629                                callback(window, cx);
1630                            }
1631                        })
1632                        .log_err();
1633                }
1634
1635                // Keep presenting if input was recently arriving at a high rate (>= 60fps).
1636                // Once high-rate input is detected, we sustain presentation for 1 second
1637                // to prevent display underclocking during active input.
1638                let needs_present = request_frame_options.require_presentation
1639                    || needs_present.get()
1640                    || (active.get() && input_rate_tracker.borrow_mut().is_high_rate());
1641
1642                if invalidator.is_dirty() || force_render {
1643                    measure("frame duration", || {
1644                        handle
1645                            .update(&mut cx, |_, window, cx| {
1646                                if force_render {
1647                                    // Bypass cached view reuse so we don't replay stale
1648                                    // atlas tile references after a GPU device recovery.
1649                                    window.refresh();
1650                                }
1651                                let arena_clear_needed = window.draw(cx);
1652                                window.present();
1653                                arena_clear_needed.clear(cx);
1654                            })
1655                            .log_err();
1656                    })
1657                } else if needs_present {
1658                    handle
1659                        .update(&mut cx, |_, window, _| window.present())
1660                        .log_err();
1661                }
1662
1663                handle
1664                    .update(&mut cx, |_, window, _| {
1665                        window.complete_frame();
1666                    })
1667                    .log_err();
1668            }
1669        }));
1670        platform_window.on_resize(Box::new({
1671            let mut cx = cx.to_async();
1672            move |_, _| {
1673                handle
1674                    .update(&mut cx, |_, window, cx| window.bounds_changed(cx))
1675                    .log_err();
1676            }
1677        }));
1678        platform_window.on_moved(Box::new({
1679            let mut cx = cx.to_async();
1680            move || {
1681                handle
1682                    .update(&mut cx, |_, window, cx| window.bounds_changed(cx))
1683                    .log_err();
1684            }
1685        }));
1686        platform_window.on_appearance_changed(Box::new({
1687            let mut cx = cx.to_async();
1688            move || {
1689                handle
1690                    .update(&mut cx, |_, window, cx| window.appearance_changed(cx))
1691                    .log_err();
1692            }
1693        }));
1694        platform_window.on_button_layout_changed(Box::new({
1695            let mut cx = cx.to_async();
1696            move || {
1697                handle
1698                    .update(&mut cx, |_, window, cx| window.button_layout_changed(cx))
1699                    .log_err();
1700            }
1701        }));
1702        platform_window.on_active_status_change(Box::new({
1703            let mut cx = cx.to_async();
1704            move |active| {
1705                handle
1706                    .update(&mut cx, |_, window, cx| {
1707                        window.active.set(active);
1708                        window.modifiers = window.platform_window.modifiers();
1709                        window.capslock = window.platform_window.capslock();
1710                        window
1711                            .activation_observers
1712                            .clone()
1713                            .retain(&(), |callback| callback(window, cx));
1714
1715                        window.bounds_changed(cx);
1716                        window.refresh();
1717
1718                        SystemWindowTabController::update_last_active(cx, window.handle.id);
1719                    })
1720                    .log_err();
1721            }
1722        }));
1723        platform_window.on_hover_status_change(Box::new({
1724            let mut cx = cx.to_async();
1725            move |active| {
1726                handle
1727                    .update(&mut cx, |_, window, _| {
1728                        window.hovered.set(active);
1729                        window.refresh();
1730                    })
1731                    .log_err();
1732            }
1733        }));
1734        platform_window.on_input({
1735            let mut cx = cx.to_async();
1736            Box::new(move |event| {
1737                handle
1738                    .update(&mut cx, |_, window, cx| window.dispatch_event(event, cx))
1739                    .log_err()
1740                    .unwrap_or(DispatchEventResult::default())
1741            })
1742        });
1743        platform_window.on_hit_test_window_control({
1744            let mut cx = cx.to_async();
1745            Box::new(move || {
1746                handle
1747                    .update(&mut cx, |_, window, _cx| {
1748                        for (area, hitbox) in &window.rendered_frame.window_control_hitboxes {
1749                            if window.mouse_hit_test.ids.contains(&hitbox.id) {
1750                                return Some(*area);
1751                            }
1752                        }
1753                        None
1754                    })
1755                    .log_err()
1756                    .unwrap_or(None)
1757            })
1758        });
1759        platform_window.on_move_tab_to_new_window({
1760            let mut cx = cx.to_async();
1761            Box::new(move || {
1762                handle
1763                    .update(&mut cx, |_, _window, cx| {
1764                        SystemWindowTabController::move_tab_to_new_window(cx, handle.window_id());
1765                    })
1766                    .log_err();
1767            })
1768        });
1769        platform_window.on_merge_all_windows({
1770            let mut cx = cx.to_async();
1771            Box::new(move || {
1772                handle
1773                    .update(&mut cx, |_, _window, cx| {
1774                        SystemWindowTabController::merge_all_windows(cx, handle.window_id());
1775                    })
1776                    .log_err();
1777            })
1778        });
1779        platform_window.on_select_next_tab({
1780            let mut cx = cx.to_async();
1781            Box::new(move || {
1782                handle
1783                    .update(&mut cx, |_, _window, cx| {
1784                        SystemWindowTabController::select_next_tab(cx, handle.window_id());
1785                    })
1786                    .log_err();
1787            })
1788        });
1789        platform_window.on_select_previous_tab({
1790            let mut cx = cx.to_async();
1791            Box::new(move || {
1792                handle
1793                    .update(&mut cx, |_, _window, cx| {
1794                        SystemWindowTabController::select_previous_tab(cx, handle.window_id())
1795                    })
1796                    .log_err();
1797            })
1798        });
1799        platform_window.on_toggle_tab_bar({
1800            let mut cx = cx.to_async();
1801            Box::new(move || {
1802                handle
1803                    .update(&mut cx, |_, window, cx| {
1804                        let tab_bar_visible = window.platform_window.tab_bar_visible();
1805                        SystemWindowTabController::set_visible(cx, tab_bar_visible);
1806                    })
1807                    .log_err();
1808            })
1809        });
1810
1811        if let Some(app_id) = app_id {
1812            platform_window.set_app_id(&app_id);
1813        }
1814
1815        platform_window.map_window().unwrap();
1816
1817        Ok(Window {
1818            handle,
1819            invalidator,
1820            removed: false,
1821            platform_window,
1822            display_id,
1823            sprite_atlas,
1824            text_system,
1825            text_rendering_mode: cx.text_rendering_mode.clone(),
1826            rem_size: px(16.),
1827            rem_size_override_stack: SmallVec::new(),
1828            viewport_size: content_size,
1829            layout_engine: Some(TaffyLayoutEngine::new()),
1830            root: None,
1831            element_id_stack: SmallVec::default(),
1832            text_style_stack: Vec::new(),
1833            rendered_entity_stack: Vec::new(),
1834            element_offset_stack: Vec::new(),
1835            content_mask_stack: Vec::new(),
1836            element_opacity: 1.0,
1837            requested_autoscroll: None,
1838            rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
1839            next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
1840            next_frame_callbacks,
1841            next_hitbox_id: HitboxId(0),
1842            next_tooltip_id: TooltipId::default(),
1843            tooltip_bounds: None,
1844            dirty_views: FxHashSet::default(),
1845            focus_listeners: SubscriberSet::new(),
1846            focus_lost_listeners: SubscriberSet::new(),
1847            default_prevented: true,
1848            mouse_position,
1849            mouse_hit_test: HitTest::default(),
1850            modifiers,
1851            capslock,
1852            scale_factor,
1853            bounds_observers: SubscriberSet::new(),
1854            appearance,
1855            appearance_observers: SubscriberSet::new(),
1856            button_layout_observers: SubscriberSet::new(),
1857            active,
1858            hovered,
1859            needs_present,
1860            input_rate_tracker,
1861            #[cfg(feature = "input-latency-histogram")]
1862            input_latency_tracker: InputLatencyTracker::new()?,
1863            last_input_modality: InputModality::Mouse,
1864            refreshing: false,
1865            activation_observers: SubscriberSet::new(),
1866            focus: None,
1867            focus_enabled: true,
1868            focus_generation: 0,
1869            pending_input: None,
1870            pending_modifier: ModifierState::default(),
1871            pending_input_observers: SubscriberSet::new(),
1872            prompt: None,
1873            client_inset: None,
1874            image_cache_stack: Vec::new(),
1875            captured_hitbox: None,
1876            #[cfg(any(feature = "inspector", debug_assertions))]
1877            inspector: None,
1878            a11y: A11y::new(
1879                a11y_active_flag,
1880                accessibility_force_disabled,
1881                initial_window_title,
1882            ),
1883        })
1884    }
1885
1886    pub(crate) fn new_focus_listener(
1887        &self,
1888        value: AnyWindowFocusListener,
1889    ) -> (Subscription, impl FnOnce() + use<>) {
1890        self.focus_listeners.insert((), value)
1891    }
1892}
1893
1894#[derive(Clone, Debug, Default, PartialEq, Eq)]
1895#[expect(missing_docs)]
1896pub struct DispatchEventResult {
1897    pub propagate: bool,
1898    pub default_prevented: bool,
1899}
1900
1901/// Indicates which region of the window is visible. Content falling outside of this mask will not be
1902/// rendered. Currently, only rectangular content masks are supported, but we give the mask its own type
1903/// to leave room to support more complex shapes in the future.
1904#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
1905#[repr(C)]
1906pub struct ContentMask<P: Clone + Debug + Default + PartialEq> {
1907    /// The bounds
1908    pub bounds: Bounds<P>,
1909}
1910
1911impl ContentMask<Pixels> {
1912    /// Scale the content mask's pixel units by the given scaling factor.
1913    pub fn scale(&self, factor: f32) -> ContentMask<ScaledPixels> {
1914        ContentMask {
1915            bounds: self.bounds.scale(factor),
1916        }
1917    }
1918
1919    /// Intersect the content mask with the given content mask.
1920    pub fn intersect(&self, other: &Self) -> Self {
1921        let bounds = self.bounds.intersect(&other.bounds);
1922        ContentMask { bounds }
1923    }
1924}
1925
1926impl Window {
1927    fn mark_view_dirty(&mut self, view_id: EntityId) {
1928        // Mark ancestor views as dirty. If already in the `dirty_views` set, then all its ancestors
1929        // should already be dirty.
1930        for view_id in self
1931            .rendered_frame
1932            .dispatch_tree
1933            .view_path_reversed(view_id)
1934        {
1935            if !self.dirty_views.insert(view_id) {
1936                break;
1937            }
1938        }
1939    }
1940
1941    /// Registers a callback to be invoked when the window appearance changes.
1942    pub fn observe_window_appearance(
1943        &self,
1944        mut callback: impl FnMut(&mut Window, &mut App) + 'static,
1945    ) -> Subscription {
1946        let (subscription, activate) = self.appearance_observers.insert(
1947            (),
1948            Box::new(move |window, cx| {
1949                callback(window, cx);
1950                true
1951            }),
1952        );
1953        activate();
1954        subscription
1955    }
1956
1957    /// Registers a callback to be invoked when the window button layout changes.
1958    pub fn observe_button_layout_changed(
1959        &self,
1960        mut callback: impl FnMut(&mut Window, &mut App) + 'static,
1961    ) -> Subscription {
1962        let (subscription, activate) = self.button_layout_observers.insert(
1963            (),
1964            Box::new(move |window, cx| {
1965                callback(window, cx);
1966                true
1967            }),
1968        );
1969        activate();
1970        subscription
1971    }
1972
1973    /// Replaces the root entity of the window with a new one.
1974    pub fn replace_root<E>(
1975        &mut self,
1976        cx: &mut App,
1977        build_view: impl FnOnce(&mut Window, &mut Context<E>) -> E,
1978    ) -> Entity<E>
1979    where
1980        E: 'static + Render,
1981    {
1982        let view = cx.new(|cx| build_view(self, cx));
1983        self.root = Some(view.clone().into());
1984        self.refresh();
1985        view
1986    }
1987
1988    /// Returns the root entity of the window, if it has one.
1989    pub fn root<E>(&self) -> Option<Option<Entity<E>>>
1990    where
1991        E: 'static + Render,
1992    {
1993        self.root
1994            .as_ref()
1995            .map(|view| view.clone().downcast::<E>().ok())
1996    }
1997
1998    /// Obtain a handle to the window that belongs to this context.
1999    pub fn window_handle(&self) -> AnyWindowHandle {
2000        self.handle
2001    }
2002
2003    /// Mark the window as dirty, scheduling it to be redrawn on the next frame.
2004    pub fn refresh(&mut self) {
2005        if self.invalidator.not_drawing() {
2006            self.refreshing = true;
2007            self.invalidator.set_dirty(true);
2008        }
2009    }
2010
2011    /// Close this window.
2012    pub fn remove_window(&mut self) {
2013        self.removed = true;
2014    }
2015
2016    /// Obtain the currently focused [`FocusHandle`]. If no elements are focused, returns `None`.
2017    pub fn focused(&self, cx: &App) -> Option<FocusHandle> {
2018        self.focus
2019            .and_then(|id| FocusHandle::for_id(id, &cx.focus_handles))
2020    }
2021
2022    /// Move focus to the element associated with the given [`FocusHandle`].
2023    pub fn focus(&mut self, handle: &FocusHandle, cx: &mut App) {
2024        if !self.focus_enabled || self.focus == Some(handle.id) {
2025            return;
2026        }
2027
2028        self.focus = Some(handle.id);
2029        self.focus_generation = self.focus_generation.wrapping_add(1);
2030        self.clear_pending_keystrokes();
2031
2032        // Avoid re-entrant entity updates by deferring observer notifications to the end of the
2033        // current effect cycle, and only for this window.
2034        let window_handle = self.handle;
2035        cx.defer(move |cx| {
2036            window_handle
2037                .update(cx, |_, window, cx| {
2038                    window.pending_input_changed(cx);
2039                })
2040                .ok();
2041        });
2042
2043        self.refresh();
2044    }
2045
2046    /// Remove focus from all elements within this context's window.
2047    pub fn blur(&mut self) {
2048        if !self.focus_enabled {
2049            return;
2050        }
2051
2052        if self.focus.is_some() {
2053            self.focus_generation = self.focus_generation.wrapping_add(1);
2054        }
2055        self.focus = None;
2056        self.refresh();
2057    }
2058
2059    /// Blur the window and don't allow anything in it to be focused again.
2060    pub fn disable_focus(&mut self) {
2061        self.blur();
2062        self.focus_enabled = false;
2063    }
2064
2065    /// Move focus to next tab stop.
2066    pub fn focus_next(&mut self, cx: &mut App) {
2067        if !self.focus_enabled {
2068            return;
2069        }
2070
2071        if let Some(handle) = self.rendered_frame.tab_stops.next(self.focus.as_ref()) {
2072            self.focus(&handle, cx)
2073        }
2074    }
2075
2076    /// Move focus to previous tab stop.
2077    pub fn focus_prev(&mut self, cx: &mut App) {
2078        if !self.focus_enabled {
2079            return;
2080        }
2081
2082        if let Some(handle) = self.rendered_frame.tab_stops.prev(self.focus.as_ref()) {
2083            self.focus(&handle, cx)
2084        }
2085    }
2086
2087    /// Accessor for the text system.
2088    pub fn text_system(&self) -> &Arc<WindowTextSystem> {
2089        &self.text_system
2090    }
2091
2092    /// The current text style. Which is composed of all the style refinements provided to `with_text_style`.
2093    pub fn text_style(&self) -> TextStyle {
2094        let mut style = TextStyle::default();
2095        for refinement in &self.text_style_stack {
2096            style.refine(refinement);
2097        }
2098        style
2099    }
2100
2101    /// Check if the platform window is maximized.
2102    ///
2103    /// On some platforms (namely Windows) this is different than the bounds being the size of the display
2104    pub fn is_maximized(&self) -> bool {
2105        self.platform_window.is_maximized()
2106    }
2107
2108    /// request a certain window decoration (Wayland)
2109    pub fn request_decorations(&self, decorations: WindowDecorations) {
2110        self.platform_window.request_decorations(decorations);
2111    }
2112
2113    /// Set the exclusive zone for a layer-shell surface: how much screen space it
2114    /// reserves so other surfaces avoid occluding it (e.g. a panel reserving space).
2115    /// Positive values reserve that distance from the anchored edge, 0 lets the
2116    /// surface be moved out of others' exclusive zones, and -1 ignores reserved
2117    /// space and may extend under other surfaces. (Wayland layer-shell windows only)
2118    pub fn set_exclusive_zone(&self, zone: Pixels) {
2119        self.platform_window.set_exclusive_zone(zone);
2120    }
2121
2122    /// Set which anchored edge a layer-shell surface's exclusive zone applies to.
2123    /// This is only needed to disambiguate a corner-anchored surface; otherwise the
2124    /// edge is deduced from the anchor. The edge must be a single edge the surface
2125    /// is anchored to, or it is ignored. (Wayland layer-shell windows only)
2126    #[cfg(all(target_os = "linux", feature = "wayland"))]
2127    pub fn set_exclusive_edge(&self, edge: crate::layer_shell::Anchor) {
2128        self.platform_window.set_exclusive_edge(edge);
2129    }
2130
2131    /// Start a window resize operation (Wayland)
2132    pub fn start_window_resize(&self, edge: ResizeEdge) {
2133        self.platform_window.start_window_resize(edge);
2134    }
2135
2136    /// Linux (wayland) only: Set the window's input region, the area that receives pointer
2137    /// and touch input. Events outside it pass through to whatever is below the window.
2138    ///
2139    /// - `Some(rects)` restricts input to the union of `rects`, in window coordinates.
2140    /// - `Some(&[])` is an empty region, so the window receives no pointer or touch input.
2141    /// - `None` resets the region to the default, so the whole window receives input again.
2142    pub fn set_input_region(&self, region: Option<&[Bounds<Pixels>]>) {
2143        self.platform_window.set_input_region(region);
2144    }
2145
2146    /// Return the `WindowBounds` to indicate that how a window should be opened
2147    /// after it has been closed
2148    pub fn window_bounds(&self) -> WindowBounds {
2149        self.platform_window.window_bounds()
2150    }
2151
2152    /// Return the `WindowBounds` excluding insets (Wayland and X11)
2153    pub fn inner_window_bounds(&self) -> WindowBounds {
2154        self.platform_window.inner_window_bounds()
2155    }
2156
2157    /// Dispatch the given action on the currently focused element.
2158    pub fn dispatch_action(&mut self, action: Box<dyn Action>, cx: &mut App) {
2159        let focus_id = self.focused(cx).map(|handle| handle.id);
2160
2161        let window = self.handle;
2162        cx.defer(move |cx| {
2163            window
2164                .update(cx, |_, window, cx| {
2165                    let node_id = window.focus_node_id_in_rendered_frame(focus_id);
2166                    window.dispatch_action_on_node(node_id, action.as_ref(), cx);
2167                })
2168                .log_err();
2169        })
2170    }
2171
2172    pub(crate) fn dispatch_keystroke_observers(
2173        &mut self,
2174        event: &dyn Any,
2175        action: Option<Box<dyn Action>>,
2176        context_stack: Vec<KeyContext>,
2177        cx: &mut App,
2178    ) {
2179        let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() else {
2180            return;
2181        };
2182
2183        cx.keystroke_observers.clone().retain(&(), move |callback| {
2184            (callback)(
2185                &KeystrokeEvent {
2186                    keystroke: key_down_event.keystroke.clone(),
2187                    action: action.as_ref().map(|action| action.boxed_clone()),
2188                    context_stack: context_stack.clone(),
2189                },
2190                self,
2191                cx,
2192            )
2193        });
2194    }
2195
2196    pub(crate) fn dispatch_keystroke_interceptors(
2197        &mut self,
2198        event: &dyn Any,
2199        context_stack: Vec<KeyContext>,
2200        cx: &mut App,
2201    ) {
2202        let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() else {
2203            return;
2204        };
2205
2206        cx.keystroke_interceptors
2207            .clone()
2208            .retain(&(), move |callback| {
2209                (callback)(
2210                    &KeystrokeEvent {
2211                        keystroke: key_down_event.keystroke.clone(),
2212                        action: None,
2213                        context_stack: context_stack.clone(),
2214                    },
2215                    self,
2216                    cx,
2217                )
2218            });
2219    }
2220
2221    /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
2222    /// that are currently on the stack to be returned to the app.
2223    pub fn defer(&self, cx: &mut App, f: impl FnOnce(&mut Window, &mut App) + 'static) {
2224        let handle = self.handle;
2225        cx.defer(move |cx| {
2226            handle.update(cx, |_, window, cx| f(window, cx)).ok();
2227        });
2228    }
2229
2230    /// Subscribe to events emitted by a entity.
2231    /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
2232    /// The callback will be invoked a handle to the emitting entity, the event, and a window context for the current window.
2233    pub fn observe<T: 'static>(
2234        &mut self,
2235        observed: &Entity<T>,
2236        cx: &mut App,
2237        mut on_notify: impl FnMut(Entity<T>, &mut Window, &mut App) + 'static,
2238    ) -> Subscription {
2239        let entity_id = observed.entity_id();
2240        let observed = observed.downgrade();
2241        let window_handle = self.handle;
2242        cx.new_observer(
2243            entity_id,
2244            Box::new(move |cx| {
2245                window_handle
2246                    .update(cx, |_, window, cx| {
2247                        if let Some(handle) = observed.upgrade() {
2248                            on_notify(handle, window, cx);
2249                            true
2250                        } else {
2251                            false
2252                        }
2253                    })
2254                    .unwrap_or(false)
2255            }),
2256        )
2257    }
2258
2259    /// Subscribe to events emitted by a entity.
2260    /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
2261    /// The callback will be invoked a handle to the emitting entity, the event, and a window context for the current window.
2262    pub fn subscribe<Emitter, Evt>(
2263        &mut self,
2264        entity: &Entity<Emitter>,
2265        cx: &mut App,
2266        mut on_event: impl FnMut(Entity<Emitter>, &Evt, &mut Window, &mut App) + 'static,
2267    ) -> Subscription
2268    where
2269        Emitter: EventEmitter<Evt>,
2270        Evt: 'static,
2271    {
2272        let entity_id = entity.entity_id();
2273        let handle = entity.downgrade();
2274        let window_handle = self.handle;
2275        cx.new_subscription(
2276            entity_id,
2277            (
2278                TypeId::of::<Evt>(),
2279                Box::new(move |event, cx| {
2280                    window_handle
2281                        .update(cx, |_, window, cx| {
2282                            if let Some(entity) = handle.upgrade() {
2283                                let event = event.downcast_ref().expect("invalid event type");
2284                                on_event(entity, event, window, cx);
2285                                true
2286                            } else {
2287                                false
2288                            }
2289                        })
2290                        .unwrap_or(false)
2291                }),
2292            ),
2293        )
2294    }
2295
2296    /// Register a callback to be invoked when the given `Entity` is released.
2297    pub fn observe_release<T>(
2298        &self,
2299        entity: &Entity<T>,
2300        cx: &mut App,
2301        mut on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static,
2302    ) -> Subscription
2303    where
2304        T: 'static,
2305    {
2306        let entity_id = entity.entity_id();
2307        let window_handle = self.handle;
2308        let (subscription, activate) = cx.release_listeners.insert(
2309            entity_id,
2310            Box::new(move |entity, cx| {
2311                let entity = entity.downcast_mut().expect("invalid entity type");
2312                let _ = window_handle.update(cx, |_, window, cx| on_release(entity, window, cx));
2313            }),
2314        );
2315        activate();
2316        subscription
2317    }
2318
2319    /// Creates an [`AsyncWindowContext`], which has a static lifetime and can be held across
2320    /// await points in async code.
2321    pub fn to_async(&self, cx: &App) -> AsyncWindowContext {
2322        AsyncWindowContext::new_context(cx.to_async(), self.handle)
2323    }
2324
2325    /// Schedule the given closure to be run directly after the current frame is rendered.
2326    pub fn on_next_frame(&self, callback: impl FnOnce(&mut Window, &mut App) + 'static) {
2327        RefCell::borrow_mut(&self.next_frame_callbacks).push(Box::new(callback));
2328    }
2329
2330    /// Schedule a frame to be drawn on the next animation frame.
2331    ///
2332    /// This is useful for elements that need to animate continuously, such as a video player or an animated GIF.
2333    /// It will cause the window to redraw on the next frame, even if no other changes have occurred.
2334    ///
2335    /// If called from within a view, it will notify that view on the next frame. Otherwise, it will refresh the entire window.
2336    ///
2337    /// Callers driving purely decorative animations (spinners, pulses, and the
2338    /// like) should prefer [`AnimationExt::with_animation`](crate::AnimationExt::with_animation),
2339    /// which automatically respects [`App::reduce_motion`]. When using this
2340    /// method directly for decorative motion, check [`App::reduce_motion`]
2341    /// and skip the frame request when it is set.
2342    pub fn request_animation_frame(&self) {
2343        let entity = self.current_view();
2344        self.on_next_frame(move |_, cx| cx.notify(entity));
2345    }
2346
2347    /// Runs all callbacks scheduled via [`Self::on_next_frame`], returning how many ran.
2348    ///
2349    /// Tests have no platform frame loop, so this simulates the delivery of the
2350    /// next frame.
2351    #[cfg(any(test, feature = "test-support"))]
2352    pub fn simulate_next_frame(&mut self, cx: &mut App) -> usize {
2353        let callbacks = self.next_frame_callbacks.take();
2354        let count = callbacks.len();
2355        for callback in callbacks {
2356            callback(self, cx);
2357        }
2358        count
2359    }
2360
2361    /// Spawn the future returned by the given closure on the application thread pool.
2362    /// The closure is provided a handle to the current window and an `AsyncWindowContext` for
2363    /// use within your future.
2364    #[track_caller]
2365    pub fn spawn<AsyncFn, R>(&self, cx: &App, f: AsyncFn) -> Task<R>
2366    where
2367        R: 'static,
2368        AsyncFn: AsyncFnOnce(&mut AsyncWindowContext) -> R + 'static,
2369    {
2370        let handle = self.handle;
2371        cx.spawn(async move |app| {
2372            let mut async_window_cx = AsyncWindowContext::new_context(app.clone(), handle);
2373            f(&mut async_window_cx).await
2374        })
2375    }
2376
2377    /// Spawn the future returned by the given closure on the application thread
2378    /// pool, with the given priority. The closure is provided a handle to the
2379    /// current window and an `AsyncWindowContext` for use within your future.
2380    #[track_caller]
2381    pub fn spawn_with_priority<AsyncFn, R>(
2382        &self,
2383        priority: Priority,
2384        cx: &App,
2385        f: AsyncFn,
2386    ) -> Task<R>
2387    where
2388        R: 'static,
2389        AsyncFn: AsyncFnOnce(&mut AsyncWindowContext) -> R + 'static,
2390    {
2391        let handle = self.handle;
2392        cx.spawn_with_priority(priority, async move |app| {
2393            let mut async_window_cx = AsyncWindowContext::new_context(app.clone(), handle);
2394            f(&mut async_window_cx).await
2395        })
2396    }
2397
2398    /// Notify the window that its bounds have changed.
2399    ///
2400    /// This updates internal state like `viewport_size` and `scale_factor` from
2401    /// the platform window, then notifies observers. Normally called automatically
2402    /// by the platform's resize callback, but exposed publicly for test infrastructure.
2403    pub fn bounds_changed(&mut self, cx: &mut App) {
2404        self.scale_factor = self.platform_window.scale_factor();
2405        self.viewport_size = self.platform_window.content_size();
2406        self.display_id = self.platform_window.display().map(|display| display.id());
2407        self.mouse_position = self.platform_window.mouse_position();
2408
2409        self.refresh();
2410
2411        self.bounds_observers
2412            .clone()
2413            .retain(&(), |callback| callback(self, cx));
2414    }
2415
2416    /// Returns the bounds of the current window in the global coordinate space, which could span across multiple displays.
2417    pub fn bounds(&self) -> Bounds<Pixels> {
2418        self.platform_window.bounds()
2419    }
2420
2421    /// Renders the current frame's scene to a texture and returns the pixel data as an RGBA image.
2422    /// This does not present the frame to screen - useful for visual testing where we want
2423    /// to capture what would be rendered without displaying it or requiring the window to be visible.
2424    #[cfg(any(test, feature = "test-support"))]
2425    pub fn render_to_image(&self) -> anyhow::Result<image::RgbaImage> {
2426        self.platform_window
2427            .render_to_image(&self.rendered_frame.scene)
2428    }
2429
2430    /// Set the content size of the window.
2431    pub fn resize(&mut self, size: Size<Pixels>) {
2432        self.platform_window.resize(size);
2433    }
2434
2435    /// Returns whether or not the window is currently fullscreen
2436    pub fn is_fullscreen(&self) -> bool {
2437        self.platform_window.is_fullscreen()
2438    }
2439
2440    pub(crate) fn appearance_changed(&mut self, cx: &mut App) {
2441        self.appearance = self.platform_window.appearance();
2442
2443        self.appearance_observers
2444            .clone()
2445            .retain(&(), |callback| callback(self, cx));
2446    }
2447
2448    pub(crate) fn button_layout_changed(&mut self, cx: &mut App) {
2449        self.button_layout_observers
2450            .clone()
2451            .retain(&(), |callback| callback(self, cx));
2452    }
2453
2454    /// Returns the appearance of the current window.
2455    pub fn appearance(&self) -> WindowAppearance {
2456        self.appearance
2457    }
2458
2459    /// Returns the size of the drawable area within the window.
2460    pub fn viewport_size(&self) -> Size<Pixels> {
2461        self.viewport_size
2462    }
2463
2464    /// Returns whether this window is focused by the operating system (receiving key events).
2465    pub fn is_window_active(&self) -> bool {
2466        self.active.get()
2467    }
2468
2469    /// Returns whether this window is considered to be the window
2470    /// that currently owns the mouse cursor.
2471    /// On mac, this is equivalent to `is_window_active`.
2472    pub fn is_window_hovered(&self) -> bool {
2473        if cfg!(any(
2474            target_os = "windows",
2475            target_os = "linux",
2476            target_os = "freebsd"
2477        )) {
2478            self.hovered.get()
2479        } else {
2480            self.is_window_active()
2481        }
2482    }
2483
2484    /// Toggle zoom on the window.
2485    pub fn zoom_window(&self) {
2486        self.platform_window.zoom();
2487    }
2488
2489    /// Opens the native title bar context menu, useful when implementing client side decorations (Wayland and X11)
2490    pub fn show_window_menu(&self, position: Point<Pixels>) {
2491        self.platform_window.show_window_menu(position)
2492    }
2493
2494    /// Handle window movement for Linux and macOS.
2495    /// Tells the compositor to take control of window movement (Wayland and X11)
2496    ///
2497    /// Events may not be received during a move operation.
2498    pub fn start_window_move(&self) {
2499        self.platform_window.start_window_move()
2500    }
2501
2502    /// When using client side decorations, set this to the width of the invisible decorations (Wayland and X11)
2503    pub fn set_client_inset(&mut self, inset: Pixels) {
2504        self.client_inset = Some(inset);
2505        self.platform_window.set_client_inset(inset);
2506    }
2507
2508    /// Returns the client_inset value by [`Self::set_client_inset`].
2509    pub fn client_inset(&self) -> Option<Pixels> {
2510        self.client_inset
2511    }
2512
2513    /// Returns whether the title bar window controls need to be rendered by the application (Wayland and X11)
2514    pub fn window_decorations(&self) -> Decorations {
2515        self.platform_window.window_decorations()
2516    }
2517
2518    /// Returns which window controls are currently visible (Wayland)
2519    pub fn window_controls(&self) -> WindowControls {
2520        self.platform_window.window_controls()
2521    }
2522
2523    /// Updates the window's title at the platform level.
2524    pub fn set_window_title(&mut self, title: &str) {
2525        self.platform_window.set_title(title);
2526        self.a11y.set_window_title(title.to_string());
2527    }
2528
2529    /// Sets the position of the macOS traffic light buttons.
2530    #[cfg(target_os = "macos")]
2531    pub fn set_traffic_light_position(&self, position: Point<Pixels>) {
2532        self.platform_window.set_traffic_light_position(position);
2533    }
2534
2535    /// Sets the application identifier.
2536    pub fn set_app_id(&mut self, app_id: &str) {
2537        self.platform_window.set_app_id(app_id);
2538    }
2539
2540    /// Sets the window background appearance.
2541    pub fn set_background_appearance(&self, background_appearance: WindowBackgroundAppearance) {
2542        self.platform_window
2543            .set_background_appearance(background_appearance);
2544    }
2545
2546    /// Mark the window as dirty at the platform level.
2547    pub fn set_window_edited(&mut self, edited: bool) {
2548        self.platform_window.set_edited(edited);
2549    }
2550
2551    /// Set the path of the file this window represents.
2552    /// On macOS, this sets the window's accessibility document property (AXDocument).
2553    pub fn set_document_path(&self, path: Option<&std::path::Path>) {
2554        self.platform_window.set_document_path(path);
2555    }
2556
2557    /// Determine the display on which the window is visible.
2558    pub fn display(&self, cx: &App) -> Option<Rc<dyn PlatformDisplay>> {
2559        cx.platform
2560            .displays()
2561            .into_iter()
2562            .find(|display| Some(display.id()) == self.display_id)
2563    }
2564
2565    /// Show the platform character palette.
2566    pub fn show_character_palette(&self) {
2567        self.platform_window.show_character_palette();
2568    }
2569
2570    /// The scale factor of the display associated with the window. For example, it could
2571    /// return 2.0 for a "retina" display, indicating that each logical pixel should actually
2572    /// be rendered as two pixels on screen.
2573    pub fn scale_factor(&self) -> f32 {
2574        self.scale_factor
2575    }
2576
2577    /// Overrides the display scale factor for tests.
2578    #[cfg(any(test, feature = "test-support"))]
2579    pub fn set_scale_factor(&mut self, scale_factor: f32) {
2580        self.scale_factor = scale_factor;
2581        self.refresh();
2582    }
2583
2584    /// The size of an em for the base font of the application. Adjusting this value allows the
2585    /// UI to scale, just like zooming a web page.
2586    pub fn rem_size(&self) -> Pixels {
2587        self.rem_size_override_stack
2588            .last()
2589            .copied()
2590            .unwrap_or(self.rem_size)
2591    }
2592
2593    /// Sets the size of an em for the base font of the application. Adjusting this value allows the
2594    /// UI to scale, just like zooming a web page.
2595    pub fn set_rem_size(&mut self, rem_size: impl Into<Pixels>) {
2596        self.rem_size = rem_size.into();
2597    }
2598
2599    /// Acquire a globally unique identifier for the given ElementId.
2600    /// Only valid for the duration of the provided closure.
2601    pub fn with_global_id<R>(
2602        &mut self,
2603        element_id: ElementId,
2604        f: impl FnOnce(&GlobalElementId, &mut Self) -> R,
2605    ) -> R {
2606        self.with_id(element_id, |this| {
2607            let global_id = GlobalElementId(Arc::from(&*this.element_id_stack));
2608
2609            f(&global_id, this)
2610        })
2611    }
2612
2613    /// Calls the provided closure with the element ID pushed on the stack.
2614    #[inline]
2615    pub fn with_id<R>(
2616        &mut self,
2617        element_id: impl Into<ElementId>,
2618        f: impl FnOnce(&mut Self) -> R,
2619    ) -> R {
2620        self.element_id_stack.push(element_id.into());
2621        let result = f(self);
2622        self.element_id_stack.pop();
2623        result
2624    }
2625
2626    /// Executes the provided function with the specified rem size.
2627    ///
2628    /// This method must only be called as part of element drawing.
2629    // This function is called in a highly recursive manner in editor
2630    // prepainting, make sure its inlined to reduce the stack burden
2631    #[inline]
2632    pub fn with_rem_size<F, R>(&mut self, rem_size: Option<impl Into<Pixels>>, f: F) -> R
2633    where
2634        F: FnOnce(&mut Self) -> R,
2635    {
2636        self.invalidator.debug_assert_paint_or_prepaint();
2637
2638        if let Some(rem_size) = rem_size {
2639            self.rem_size_override_stack.push(rem_size.into());
2640            let result = f(self);
2641            self.rem_size_override_stack.pop();
2642            result
2643        } else {
2644            f(self)
2645        }
2646    }
2647
2648    /// The line height associated with the current text style.
2649    pub fn line_height(&self) -> Pixels {
2650        self.text_style().line_height_in_pixels(self.rem_size())
2651    }
2652
2653    /// Rounds a logical value to the nearest device pixel.
2654    #[inline]
2655    pub fn pixel_snap(&self, value: Pixels) -> Pixels {
2656        px(round_to_device_pixel(value.0, self.scale_factor()) / self.scale_factor())
2657    }
2658
2659    /// f64 variant of [`Self::pixel_snap`].
2660    #[inline]
2661    pub fn pixel_snap_f64(&self, value: f64) -> f64 {
2662        let scale_factor = f64::from(self.scale_factor());
2663        round_half_toward_zero_f64(value * scale_factor) / scale_factor
2664    }
2665
2666    /// Snaps a bounds' origin and size to the nearest device pixel.
2667    #[inline]
2668    pub fn pixel_snap_bounds(&self, bounds: Bounds<Pixels>) -> Bounds<Pixels> {
2669        bounds.map(|c| self.pixel_snap(c))
2670    }
2671
2672    /// Snaps a point's coordinates to the nearest device pixel.
2673    #[inline]
2674    pub fn pixel_snap_point(&self, position: Point<Pixels>) -> Point<Pixels> {
2675        position.map(|c| self.pixel_snap(c))
2676    }
2677
2678    #[inline]
2679    fn snap_bounds(&self, bounds: Bounds<Pixels>) -> Bounds<ScaledPixels> {
2680        let scale_factor = self.scale_factor();
2681        let left = round_to_device_pixel(bounds.left().0, scale_factor);
2682        let top = round_to_device_pixel(bounds.top().0, scale_factor);
2683        let right = round_to_device_pixel(bounds.right().0, scale_factor).max(left);
2684        let bottom = round_to_device_pixel(bounds.bottom().0, scale_factor).max(top);
2685        Bounds::from_corners(
2686            point(ScaledPixels(left), ScaledPixels(top)),
2687            point(ScaledPixels(right), ScaledPixels(bottom)),
2688        )
2689    }
2690
2691    /// Rounds half-to-zero but clamps any non-zero input up to 1 dp so thin strokes do not disappear.
2692    #[inline]
2693    fn snap_stroke(&self, value: Pixels) -> ScaledPixels {
2694        ScaledPixels(round_stroke_to_device_pixel(value.0, self.scale_factor()))
2695    }
2696
2697    #[inline]
2698    fn snap_border_widths(&self, edges: Edges<Pixels>) -> Edges<ScaledPixels> {
2699        edges.map(|e| self.snap_stroke(*e))
2700    }
2701
2702    /// Floors the near edge and ceils the far edge, producing a strict superset of the raw region.
2703    #[inline]
2704    fn cover_bounds(&self, bounds: Bounds<Pixels>) -> Bounds<ScaledPixels> {
2705        let scale_factor = self.scale_factor();
2706        let left = floor_to_device_pixel(bounds.left().0, scale_factor);
2707        let top = floor_to_device_pixel(bounds.top().0, scale_factor);
2708        let right = ceil_to_device_pixel(bounds.right().0, scale_factor).max(left);
2709        let bottom = ceil_to_device_pixel(bounds.bottom().0, scale_factor).max(top);
2710        Bounds::from_corners(
2711            point(ScaledPixels(left), ScaledPixels(top)),
2712            point(ScaledPixels(right), ScaledPixels(bottom)),
2713        )
2714    }
2715
2716    #[inline]
2717    fn snapped_content_mask(&self) -> ContentMask<ScaledPixels> {
2718        ContentMask {
2719            bounds: self.cover_bounds(self.content_mask().bounds),
2720        }
2721    }
2722
2723    /// Call to prevent the default action of an event. Currently only used to prevent
2724    /// parent elements from becoming focused on mouse down.
2725    pub fn prevent_default(&mut self) {
2726        self.default_prevented = true;
2727    }
2728
2729    /// Obtain whether default has been prevented for the event currently being dispatched.
2730    pub fn default_prevented(&self) -> bool {
2731        self.default_prevented
2732    }
2733
2734    /// Determine whether the given action is available along the dispatch path to the currently focused element.
2735    pub fn is_action_available(&self, action: &dyn Action, cx: &App) -> bool {
2736        let node_id =
2737            self.focus_node_id_in_rendered_frame(self.focused(cx).map(|handle| handle.id));
2738        self.rendered_frame
2739            .dispatch_tree
2740            .is_action_available(action, node_id)
2741    }
2742
2743    /// Determine whether the given action is available along the dispatch path to the given focus_handle.
2744    pub fn is_action_available_in(&self, action: &dyn Action, focus_handle: &FocusHandle) -> bool {
2745        let node_id = self.focus_node_id_in_rendered_frame(Some(focus_handle.id));
2746        self.rendered_frame
2747            .dispatch_tree
2748            .is_action_available(action, node_id)
2749    }
2750
2751    /// The position of the mouse relative to the window.
2752    pub fn mouse_position(&self) -> Point<Pixels> {
2753        self.mouse_position
2754    }
2755
2756    /// Captures the pointer for the given hitbox. While captured, all mouse move and mouse up
2757    /// events will be routed to listeners that check this hitbox's `is_hovered` status,
2758    /// regardless of actual hit testing. This enables drag operations that continue
2759    /// even when the pointer moves outside the element's bounds.
2760    ///
2761    /// The capture is automatically released on mouse up.
2762    pub fn capture_pointer(&mut self, hitbox_id: HitboxId) {
2763        self.captured_hitbox = Some(hitbox_id);
2764    }
2765
2766    /// Releases any active pointer capture.
2767    pub fn release_pointer(&mut self) {
2768        self.captured_hitbox = None;
2769    }
2770
2771    /// Returns the hitbox that has captured the pointer, if any.
2772    pub fn captured_hitbox(&self) -> Option<HitboxId> {
2773        self.captured_hitbox
2774    }
2775
2776    /// The current state of the keyboard's modifiers
2777    pub fn modifiers(&self) -> Modifiers {
2778        self.modifiers
2779    }
2780
2781    /// Returns true if the last input event was keyboard-based (key press, tab navigation, etc.)
2782    /// This is used for focus-visible styling to show focus indicators only for keyboard navigation.
2783    pub fn last_input_was_keyboard(&self) -> bool {
2784        self.last_input_modality == InputModality::Keyboard
2785    }
2786
2787    /// The current state of the keyboard's capslock
2788    pub fn capslock(&self) -> Capslock {
2789        self.capslock
2790    }
2791
2792    fn complete_frame(&self) {
2793        self.platform_window.completed_frame();
2794    }
2795
2796    /// Produces a new frame and assigns it to `rendered_frame`. To actually show
2797    /// the contents of the new [`Scene`], use [`Self::present`].
2798    #[profiling::function]
2799    pub fn draw(&mut self, cx: &mut App) -> ArenaClearNeeded {
2800        // Drain unconditionally so a stale first-invalidation timestamp can't
2801        // leak into a later frame across enable/disable of frame tracing.
2802        let frame_dirty = self.invalidator.take_frame_dirty();
2803        let draw_started_at = profiler::frame_trace_enabled().then(Instant::now);
2804
2805        // Set up the per-App arena for element allocation during this draw.
2806        // This ensures that multiple test Apps have isolated arenas.
2807        let arena_scope = ElementArenaScope::enter(&cx.element_arena);
2808
2809        self.invalidate_entities();
2810        cx.entities.clear_accessed();
2811        debug_assert!(self.rendered_entity_stack.is_empty());
2812        self.invalidator.set_dirty(false);
2813        self.requested_autoscroll = None;
2814
2815        // Restore the previously-used input handler.
2816        // Place it back into a None slot (left by a previous .take()) so that
2817        // cached paint_range indices in reuse_paint find the handler at the
2818        // expected position.
2819        if let Some(input_handler) = self.platform_window.take_input_handler() {
2820            if let Some(slot) = self
2821                .rendered_frame
2822                .input_handlers
2823                .iter_mut()
2824                .rev()
2825                .find(|h| h.is_none())
2826            {
2827                *slot = Some(input_handler);
2828            } else {
2829                self.rendered_frame.input_handlers.push(Some(input_handler));
2830            }
2831        }
2832        if !cx.mode.skip_drawing() {
2833            self.draw_roots(cx);
2834        }
2835        self.dirty_views.clear();
2836        self.next_frame.window_active = self.active.get();
2837
2838        // Register requested input handler with the platform window.
2839        // Use .take() instead of .pop() to preserve Vec length, so that cached
2840        // paint_range indices remain valid for reuse_paint on the next frame.
2841        // Search backwards to find the last Some entry, since reuse_paint may
2842        // have copied None slots from the previous frame. (Fixes #50456)
2843        if let Some(input_handler) = self
2844            .next_frame
2845            .input_handlers
2846            .iter_mut()
2847            .rev()
2848            .find_map(|h| h.take())
2849        {
2850            self.platform_window.set_input_handler(input_handler);
2851        }
2852
2853        self.layout_engine.as_mut().unwrap().clear();
2854        self.text_system().finish_frame();
2855        self.next_frame.finish(&mut self.rendered_frame);
2856
2857        self.invalidator.set_phase(DrawPhase::Focus);
2858        let previous_focus_path = self.rendered_frame.focus_path();
2859        let previous_window_active = self.rendered_frame.window_active;
2860        mem::swap(&mut self.rendered_frame, &mut self.next_frame);
2861        self.next_frame.clear();
2862        let current_focus_path = self.rendered_frame.focus_path();
2863        let current_window_active = self.rendered_frame.window_active;
2864        let mut focus_before_listeners = self.focus;
2865
2866        if previous_focus_path != current_focus_path
2867            || previous_window_active != current_window_active
2868        {
2869            if !previous_focus_path.is_empty() && current_focus_path.is_empty() {
2870                self.focus_lost_listeners
2871                    .clone()
2872                    .retain(&(), |listener| listener(self, cx));
2873                // The focus-lost fallback (e.g. a workspace refocusing itself) may target
2874                // an element that isn't part of the element tree, in which case scheduling
2875                // a redraw below would dispatch focus-lost again, looping forever. Only
2876                // track focus movement caused by the focus listeners.
2877                focus_before_listeners = self.focus;
2878            }
2879
2880            let event = WindowFocusEvent {
2881                previous_focus_path: if previous_window_active {
2882                    previous_focus_path
2883                } else {
2884                    Default::default()
2885                },
2886                current_focus_path: if current_window_active {
2887                    current_focus_path
2888                } else {
2889                    Default::default()
2890                },
2891            };
2892            self.focus_listeners
2893                .clone()
2894                .retain(&(), |listener| listener(&event, self, cx));
2895        }
2896
2897        debug_assert!(self.rendered_entity_stack.is_empty());
2898        self.record_entities_accessed(cx);
2899        self.reset_cursor_style(cx);
2900        self.refreshing = false;
2901        self.invalidator.set_phase(DrawPhase::None);
2902        // Focus listeners may move focus (e.g. a dock forwarding focus to its active
2903        // panel). `Window::focus` suppresses `refresh` while a draw is in progress, so
2904        // schedule another frame here to render the new focus state and dispatch the
2905        // resulting focus events.
2906        if self.focus != focus_before_listeners {
2907            self.refresh();
2908        }
2909        self.needs_present.set(true);
2910
2911        if let Some(draw_start) = draw_started_at {
2912            profiler::record_frame_timing(profiler::FrameTiming {
2913                window_id: self.handle.window_id(),
2914                dirty_at: frame_dirty.dirty_at,
2915                invalidations: frame_dirty.invalidations,
2916                draw_start,
2917                draw_end: Instant::now(),
2918            });
2919        }
2920
2921        // Exit the scope to obtain the arena-clear token this draw owes; the
2922        // scope's teardown itself happens in `ElementArenaScope::drop`.
2923        arena_scope.exit(&cx.element_arena)
2924    }
2925
2926    fn record_entities_accessed(&mut self, cx: &mut App) {
2927        let mut entities_ref = cx.entities.accessed_entities.get_mut();
2928        let mut entities = mem::take(entities_ref.deref_mut());
2929        let handle = self.handle;
2930        cx.record_entities_accessed(
2931            handle,
2932            // Try moving window invalidator into the Window
2933            self.invalidator.clone(),
2934            &entities,
2935        );
2936        let mut entities_ref = cx.entities.accessed_entities.get_mut();
2937        mem::swap(&mut entities, entities_ref.deref_mut());
2938    }
2939
2940    fn invalidate_entities(&mut self) {
2941        let mut views = self.invalidator.take_views();
2942        for entity in views.drain() {
2943            self.mark_view_dirty(entity);
2944        }
2945        self.invalidator.replace_views(views);
2946    }
2947
2948    #[profiling::function]
2949    fn present(&mut self) {
2950        self.platform_window.draw(&self.rendered_frame.scene);
2951        #[cfg(feature = "input-latency-histogram")]
2952        self.input_latency_tracker.record_frame_presented();
2953        self.needs_present.set(false);
2954        profiling::finish_frame!();
2955    }
2956
2957    /// Presents the most recently drawn frame if it hasn't been presented yet.
2958    ///
2959    /// Benchmarks drive drawing synchronously rather than through a platform
2960    /// frame-request loop, so they call this after each measured update to
2961    /// submit the frame like production presentation would.
2962    #[cfg(feature = "bench")]
2963    pub fn present_if_needed(&mut self) {
2964        if self.needs_present.get() {
2965            self.present();
2966        }
2967    }
2968
2969    /// Returns a snapshot of the current input-latency histograms.
2970    #[cfg(feature = "input-latency-histogram")]
2971    pub fn input_latency_snapshot(&self) -> InputLatencySnapshot {
2972        self.input_latency_tracker.snapshot()
2973    }
2974
2975    fn draw_roots(&mut self, cx: &mut App) {
2976        self.invalidator.set_phase(DrawPhase::Prepaint);
2977        self.tooltip_bounds.take();
2978
2979        self.a11y.sync_active_flag();
2980        if self.a11y.is_active() {
2981            self.a11y.begin_frame();
2982        }
2983
2984        let _inspector_width: Pixels = rems(30.0).to_pixels(self.rem_size());
2985        let root_size = {
2986            #[cfg(any(feature = "inspector", debug_assertions))]
2987            {
2988                if self.inspector.is_some() {
2989                    let mut size = self.viewport_size;
2990                    size.width = (size.width - _inspector_width).max(px(0.0));
2991                    size
2992                } else {
2993                    self.viewport_size
2994                }
2995            }
2996            #[cfg(not(any(feature = "inspector", debug_assertions)))]
2997            {
2998                self.viewport_size
2999            }
3000        };
3001
3002        // Layout all root elements. Like the root element on the web, which
3003        // stretches to fill the viewport unless explicitly sized, window roots
3004        // fill the window when their size is `auto`.
3005        let scale_factor = self.scale_factor();
3006        let mut root_element = self.root.as_ref().unwrap().clone().into_any_element();
3007        let root_layout_id = root_element.request_layout(self, cx);
3008        self.layout_engine
3009            .as_mut()
3010            .unwrap()
3011            .stretch_auto_size_to_fill(root_layout_id, root_size, scale_factor);
3012        root_element.prepaint_as_root(Point::default(), root_size.into(), self, cx);
3013
3014        #[cfg(any(feature = "inspector", debug_assertions))]
3015        let inspector_element = self.prepaint_inspector(_inspector_width, cx);
3016
3017        self.prepaint_deferred_draws(cx);
3018
3019        let mut prompt_element = None;
3020        let mut active_drag_element = None;
3021        let mut tooltip_element = None;
3022        if let Some(prompt) = self.prompt.take() {
3023            let mut element = prompt.view.any_view().into_any_element();
3024            let prompt_layout_id = element.request_layout(self, cx);
3025            self.layout_engine
3026                .as_mut()
3027                .unwrap()
3028                .stretch_auto_size_to_fill(prompt_layout_id, root_size, scale_factor);
3029            element.prepaint_as_root(Point::default(), root_size.into(), self, cx);
3030            prompt_element = Some(element);
3031            self.prompt = Some(prompt);
3032        } else if let Some(active_drag) = cx.active_drag.take() {
3033            let mut element = active_drag.view.clone().into_any_element();
3034            let offset = self.mouse_position() - active_drag.cursor_offset;
3035            element.prepaint_as_root(offset, AvailableSpace::min_size(), self, cx);
3036            active_drag_element = Some(element);
3037            cx.active_drag = Some(active_drag);
3038        } else {
3039            tooltip_element = self.prepaint_tooltip(cx);
3040        }
3041
3042        self.mouse_hit_test = self.next_frame.hit_test(self.mouse_position);
3043
3044        // Now actually paint the elements.
3045        self.invalidator.set_phase(DrawPhase::Paint);
3046        root_element.paint(self, cx);
3047
3048        #[cfg(any(feature = "inspector", debug_assertions))]
3049        self.paint_inspector(inspector_element, cx);
3050
3051        self.paint_deferred_draws(cx);
3052
3053        if let Some(mut prompt_element) = prompt_element {
3054            prompt_element.paint(self, cx);
3055        } else if let Some(mut drag_element) = active_drag_element {
3056            drag_element.paint(self, cx);
3057        } else if let Some(mut tooltip_element) = tooltip_element {
3058            tooltip_element.paint(self, cx);
3059        }
3060
3061        #[cfg(any(feature = "inspector", debug_assertions))]
3062        self.paint_inspector_hitbox(cx);
3063
3064        // a11y may have been activated/deactivated halfway through the frame
3065        let a11y_active_start_of_frame = self.a11y.is_active();
3066        self.a11y.sync_active_flag();
3067        let a11y_active_end_of_frame = self.a11y.is_active();
3068
3069        let should_send_a11y_update = a11y_active_start_of_frame && a11y_active_end_of_frame;
3070
3071        if a11y_active_start_of_frame {
3072            // Harvest frame metadata for the debug dump while the live window
3073            // and frame are still in scope.
3074            let frame_info = crate::window::a11y::debug::FrameDebugInfo {
3075                viewport_size: self.viewport_size,
3076                scale_factor: self.scale_factor,
3077                tab_stop_count: self.next_frame.tab_stops.tab_stop_count(),
3078            };
3079            // clear the builder state regardless
3080            let tree_update = self.a11y.end_frame(frame_info);
3081
3082            if should_send_a11y_update {
3083                log::debug!(
3084                    "Sending a11y tree update: {} nodes",
3085                    tree_update.nodes.len()
3086                );
3087                self.platform_window.a11y_tree_update(tree_update);
3088            }
3089        }
3090    }
3091
3092    fn prepaint_tooltip(&mut self, cx: &mut App) -> Option<AnyElement> {
3093        // Use indexing instead of iteration to avoid borrowing self for the duration of the loop.
3094        for tooltip_request_index in (0..self.next_frame.tooltip_requests.len()).rev() {
3095            let Some(Some(tooltip_request)) = self
3096                .next_frame
3097                .tooltip_requests
3098                .get(tooltip_request_index)
3099                .cloned()
3100            else {
3101                log::error!("Unexpectedly absent TooltipRequest");
3102                continue;
3103            };
3104            let mut element = tooltip_request.tooltip.view.clone().into_any_element();
3105            let mouse_position = tooltip_request.tooltip.mouse_position;
3106            let tooltip_size = element.layout_as_root(AvailableSpace::min_size(), self, cx);
3107
3108            let mut tooltip_bounds =
3109                Bounds::new(mouse_position + point(px(1.), px(1.)), tooltip_size);
3110            let window_bounds = Bounds {
3111                origin: Point::default(),
3112                size: self.viewport_size(),
3113            };
3114
3115            if tooltip_bounds.right() > window_bounds.right() {
3116                let new_x = mouse_position.x - tooltip_bounds.size.width - px(1.);
3117                if new_x >= Pixels::ZERO {
3118                    tooltip_bounds.origin.x = new_x;
3119                } else {
3120                    tooltip_bounds.origin.x = cmp::max(
3121                        Pixels::ZERO,
3122                        tooltip_bounds.origin.x - tooltip_bounds.right() - window_bounds.right(),
3123                    );
3124                }
3125            }
3126
3127            if tooltip_bounds.bottom() > window_bounds.bottom() {
3128                let new_y = mouse_position.y - tooltip_bounds.size.height - px(1.);
3129                if new_y >= Pixels::ZERO {
3130                    tooltip_bounds.origin.y = new_y;
3131                } else {
3132                    tooltip_bounds.origin.y = cmp::max(
3133                        Pixels::ZERO,
3134                        tooltip_bounds.origin.y - tooltip_bounds.bottom() - window_bounds.bottom(),
3135                    );
3136                }
3137            }
3138
3139            // It's possible for an element to have an active tooltip while not being painted (e.g.
3140            // via the `visible_on_hover` method). Since mouse listeners are not active in this
3141            // case, instead update the tooltip's visibility here.
3142            let is_visible =
3143                (tooltip_request.tooltip.check_visible_and_update)(tooltip_bounds, self, cx);
3144            if !is_visible {
3145                continue;
3146            }
3147
3148            self.with_absolute_element_offset(tooltip_bounds.origin, |window| {
3149                element.prepaint(window, cx)
3150            });
3151
3152            self.tooltip_bounds = Some(TooltipBounds {
3153                id: tooltip_request.id,
3154                bounds: tooltip_bounds,
3155            });
3156            return Some(element);
3157        }
3158        None
3159    }
3160
3161    fn prepaint_deferred_draws(&mut self, cx: &mut App) {
3162        assert_eq!(self.element_id_stack.len(), 0);
3163
3164        // Process deferred draws in multiple rounds to support nesting.
3165        // Each round processes all current deferred draws, which may push new ones.
3166        //
3167        // The draws are processed in place rather than being moved out of
3168        // `next_frame.deferred_draws`: `prepaint_index` snapshots that vector's
3169        // length, so any prepaint range recorded during a round (view caches,
3170        // nested deferred draws) must index the same vector `reuse_prepaint`
3171        // slices on the next frame. Moving the draws out and re-appending them
3172        // shifts the indices of nested draws, causing reused subtrees to graft
3173        // the wrong deferred draws and panic in the dispatch tree.
3174        let mut round_start = 0;
3175        let mut depth = 0;
3176        loop {
3177            let round_end = self.next_frame.deferred_draws.len();
3178            if round_start == round_end {
3179                break;
3180            }
3181            // Limit maximum nesting depth to prevent infinite loops.
3182            assert!(depth < 10, "Exceeded maximum (10) deferred depth");
3183            depth += 1;
3184
3185            // Sort this round by priority.
3186            let mut traversal_order = (round_start..round_end).collect::<SmallVec<[usize; 8]>>();
3187            traversal_order.sort_by_key(|ix| self.next_frame.deferred_draws[*ix].priority);
3188
3189            for deferred_draw_ix in traversal_order {
3190                let (element, parent_node, current_view, rem_size, absolute_offset, prepaint_range) = {
3191                    let deferred_draw = &mut self.next_frame.deferred_draws[deferred_draw_ix];
3192                    self.element_id_stack
3193                        .clone_from(&deferred_draw.element_id_stack);
3194                    self.text_style_stack
3195                        .clone_from(&deferred_draw.text_style_stack);
3196                    (
3197                        deferred_draw.element.take(),
3198                        deferred_draw.parent_node,
3199                        deferred_draw.current_view,
3200                        deferred_draw.rem_size,
3201                        deferred_draw.absolute_offset,
3202                        deferred_draw.prepaint_range.clone(),
3203                    )
3204                };
3205                self.next_frame.dispatch_tree.set_active_node(parent_node);
3206
3207                let prepaint_start = self.prepaint_index();
3208                if let Some(mut element) = element {
3209                    self.with_rendered_view(current_view, |window| {
3210                        window.with_rem_size(Some(rem_size), |window| {
3211                            window.with_absolute_element_offset(absolute_offset, |window| {
3212                                element.prepaint(window, cx);
3213                            });
3214                        });
3215                    });
3216                    self.next_frame.deferred_draws[deferred_draw_ix].element = Some(element);
3217                } else {
3218                    self.reuse_prepaint(prepaint_range);
3219                }
3220                let prepaint_end = self.prepaint_index();
3221                self.next_frame.deferred_draws[deferred_draw_ix].prepaint_range =
3222                    prepaint_start..prepaint_end;
3223            }
3224
3225            self.element_id_stack.clear();
3226            self.text_style_stack.clear();
3227            round_start = round_end;
3228        }
3229    }
3230
3231    fn paint_deferred_draws(&mut self, cx: &mut App) {
3232        assert_eq!(self.element_id_stack.len(), 0);
3233
3234        // Paint all deferred draws in priority order.
3235        // Since prepaint has already processed nested deferreds, we just paint them all.
3236        if self.next_frame.deferred_draws.len() == 0 {
3237            return;
3238        }
3239
3240        let traversal_order = self.deferred_draw_traversal_order();
3241        let mut deferred_draws = mem::take(&mut self.next_frame.deferred_draws);
3242        for deferred_draw_ix in traversal_order {
3243            let mut deferred_draw = &mut deferred_draws[deferred_draw_ix];
3244            self.element_id_stack
3245                .clone_from(&deferred_draw.element_id_stack);
3246            self.next_frame
3247                .dispatch_tree
3248                .set_active_node(deferred_draw.parent_node);
3249
3250            let paint_start = self.paint_index();
3251            let content_mask = deferred_draw.content_mask;
3252            if let Some(element) = deferred_draw.element.as_mut() {
3253                self.with_rendered_view(deferred_draw.current_view, |window| {
3254                    window.with_content_mask(content_mask, |window| {
3255                        window.with_rem_size(Some(deferred_draw.rem_size), |window| {
3256                            element.paint(window, cx);
3257                        });
3258                    })
3259                })
3260            } else {
3261                self.reuse_paint(deferred_draw.paint_range.clone());
3262            }
3263            let paint_end = self.paint_index();
3264            deferred_draw.paint_range = paint_start..paint_end;
3265        }
3266        self.next_frame.deferred_draws = deferred_draws;
3267        self.element_id_stack.clear();
3268    }
3269
3270    fn deferred_draw_traversal_order(&mut self) -> SmallVec<[usize; 8]> {
3271        let deferred_count = self.next_frame.deferred_draws.len();
3272        let mut sorted_indices = (0..deferred_count).collect::<SmallVec<[_; 8]>>();
3273        sorted_indices.sort_by_key(|ix| self.next_frame.deferred_draws[*ix].priority);
3274        sorted_indices
3275    }
3276
3277    pub(crate) fn prepaint_index(&self) -> PrepaintStateIndex {
3278        PrepaintStateIndex {
3279            hitboxes_index: self.next_frame.hitboxes.len(),
3280            tooltips_index: self.next_frame.tooltip_requests.len(),
3281            deferred_draws_index: self.next_frame.deferred_draws.len(),
3282            dispatch_tree_index: self.next_frame.dispatch_tree.len(),
3283            accessed_element_states_index: self.next_frame.accessed_element_states.len(),
3284            line_layout_index: self.text_system.layout_index(),
3285        }
3286    }
3287
3288    pub(crate) fn reuse_prepaint(&mut self, range: Range<PrepaintStateIndex>) {
3289        self.next_frame.hitboxes.extend(
3290            self.rendered_frame.hitboxes[range.start.hitboxes_index..range.end.hitboxes_index]
3291                .iter()
3292                .cloned(),
3293        );
3294        self.next_frame.tooltip_requests.extend(
3295            self.rendered_frame.tooltip_requests
3296                [range.start.tooltips_index..range.end.tooltips_index]
3297                .iter_mut()
3298                .map(|request| request.take()),
3299        );
3300        self.next_frame.accessed_element_states.extend(
3301            self.rendered_frame.accessed_element_states[range.start.accessed_element_states_index
3302                ..range.end.accessed_element_states_index]
3303                .iter()
3304                .map(|(id, type_id)| (id.clone(), *type_id)),
3305        );
3306        self.text_system
3307            .reuse_layouts(range.start.line_layout_index..range.end.line_layout_index);
3308
3309        let reused_subtree = self.next_frame.dispatch_tree.reuse_subtree(
3310            range.start.dispatch_tree_index..range.end.dispatch_tree_index,
3311            &mut self.rendered_frame.dispatch_tree,
3312            self.focus,
3313        );
3314
3315        if reused_subtree.contains_focus() {
3316            self.next_frame.focus = self.focus;
3317        }
3318
3319        self.next_frame.deferred_draws.extend(
3320            self.rendered_frame.deferred_draws
3321                [range.start.deferred_draws_index..range.end.deferred_draws_index]
3322                .iter()
3323                .map(|deferred_draw| DeferredDraw {
3324                    current_view: deferred_draw.current_view,
3325                    parent_node: reused_subtree.refresh_node_id(deferred_draw.parent_node),
3326                    element_id_stack: deferred_draw.element_id_stack.clone(),
3327                    text_style_stack: deferred_draw.text_style_stack.clone(),
3328                    content_mask: deferred_draw.content_mask,
3329                    rem_size: deferred_draw.rem_size,
3330                    priority: deferred_draw.priority,
3331                    element: None,
3332                    absolute_offset: deferred_draw.absolute_offset,
3333                    prepaint_range: deferred_draw.prepaint_range.clone(),
3334                    paint_range: deferred_draw.paint_range.clone(),
3335                }),
3336        );
3337    }
3338
3339    pub(crate) fn paint_index(&self) -> PaintIndex {
3340        PaintIndex {
3341            scene_index: self.next_frame.scene.len(),
3342            mouse_listeners_index: self.next_frame.mouse_listeners.len(),
3343            input_handlers_index: self.next_frame.input_handlers.len(),
3344            cursor_styles_index: self.next_frame.cursor_styles.len(),
3345            accessed_element_states_index: self.next_frame.accessed_element_states.len(),
3346            tab_handle_index: self.next_frame.tab_stops.paint_index(),
3347            line_layout_index: self.text_system.layout_index(),
3348        }
3349    }
3350
3351    pub(crate) fn reuse_paint(&mut self, range: Range<PaintIndex>) {
3352        self.next_frame.cursor_styles.extend(
3353            self.rendered_frame.cursor_styles
3354                [range.start.cursor_styles_index..range.end.cursor_styles_index]
3355                .iter()
3356                .cloned(),
3357        );
3358        self.next_frame.input_handlers.extend(
3359            self.rendered_frame.input_handlers
3360                [range.start.input_handlers_index..range.end.input_handlers_index]
3361                .iter_mut()
3362                .map(|handler| handler.take()),
3363        );
3364        self.next_frame.mouse_listeners.extend(
3365            self.rendered_frame.mouse_listeners
3366                [range.start.mouse_listeners_index..range.end.mouse_listeners_index]
3367                .iter_mut()
3368                .map(|listener| listener.take()),
3369        );
3370        self.next_frame.accessed_element_states.extend(
3371            self.rendered_frame.accessed_element_states[range.start.accessed_element_states_index
3372                ..range.end.accessed_element_states_index]
3373                .iter()
3374                .map(|(id, type_id)| (id.clone(), *type_id)),
3375        );
3376        self.next_frame.tab_stops.replay(
3377            &self.rendered_frame.tab_stops.insertion_history
3378                [range.start.tab_handle_index..range.end.tab_handle_index],
3379        );
3380
3381        self.text_system
3382            .reuse_layouts(range.start.line_layout_index..range.end.line_layout_index);
3383        self.next_frame.scene.replay(
3384            range.start.scene_index..range.end.scene_index,
3385            &self.rendered_frame.scene,
3386        );
3387    }
3388
3389    /// Push a text style onto the stack, and call a function with that style active.
3390    /// Use [`Window::text_style`] to get the current, combined text style. This method
3391    /// should only be called as part of element drawing.
3392    pub fn with_text_style<F, R>(&mut self, style: Option<TextStyleRefinement>, f: F) -> R
3393    where
3394        F: FnOnce(&mut Self) -> R,
3395    {
3396        self.invalidator.debug_assert_paint_or_prepaint();
3397        if let Some(style) = style {
3398            self.text_style_stack.push(style);
3399            let result = f(self);
3400            self.text_style_stack.pop();
3401            result
3402        } else {
3403            f(self)
3404        }
3405    }
3406
3407    /// Updates the cursor style at the platform level. This method should only be called
3408    /// during the paint phase of element drawing.
3409    pub fn set_cursor_style(&mut self, style: CursorStyle, hitbox: &Hitbox) {
3410        self.invalidator.debug_assert_paint();
3411        self.next_frame.cursor_styles.push(CursorStyleRequest {
3412            hitbox_id: Some(hitbox.id),
3413            style,
3414        });
3415    }
3416
3417    /// Updates the cursor style for the entire window at the platform level. A cursor
3418    /// style using this method will have precedence over any cursor style set using
3419    /// `set_cursor_style`. This method should only be called during the paint
3420    /// phase of element drawing.
3421    pub fn set_window_cursor_style(&mut self, style: CursorStyle) {
3422        self.invalidator.debug_assert_paint();
3423        self.next_frame.cursor_styles.push(CursorStyleRequest {
3424            hitbox_id: None,
3425            style,
3426        })
3427    }
3428
3429    /// Sets a tooltip to be rendered for the upcoming frame. This method should only be called
3430    /// during the paint phase of element drawing.
3431    pub fn set_tooltip(&mut self, tooltip: AnyTooltip) -> TooltipId {
3432        self.invalidator.debug_assert_prepaint();
3433        let id = TooltipId(post_inc(&mut self.next_tooltip_id.0));
3434        self.next_frame
3435            .tooltip_requests
3436            .push(Some(TooltipRequest { id, tooltip }));
3437        id
3438    }
3439
3440    /// Invoke the given function with the given content mask after intersecting it
3441    /// with the current mask. This method should only be called during element drawing.
3442    // This function is called in a highly recursive manner in editor
3443    // prepainting, make sure its inlined to reduce the stack burden
3444    #[inline]
3445    pub fn with_content_mask<R>(
3446        &mut self,
3447        mask: Option<ContentMask<Pixels>>,
3448        f: impl FnOnce(&mut Self) -> R,
3449    ) -> R {
3450        self.invalidator.debug_assert_paint_or_prepaint();
3451        if let Some(mask) = mask {
3452            let mask = mask.intersect(&self.content_mask());
3453            self.content_mask_stack.push(mask);
3454            let result = f(self);
3455            self.content_mask_stack.pop();
3456            result
3457        } else {
3458            f(self)
3459        }
3460    }
3461
3462    /// Updates the global element offset relative to the current offset. This is used to implement
3463    /// scrolling. This method should only be called during the prepaint phase of element drawing.
3464    pub fn with_element_offset<R>(
3465        &mut self,
3466        offset: Point<Pixels>,
3467        f: impl FnOnce(&mut Self) -> R,
3468    ) -> R {
3469        self.invalidator.debug_assert_prepaint();
3470
3471        if offset.is_zero() {
3472            return f(self);
3473        };
3474
3475        let abs_offset = self.element_offset() + offset;
3476        self.with_absolute_element_offset(abs_offset, f)
3477    }
3478
3479    /// Updates the global element offset based on the given offset. This is used to implement
3480    /// drag handles and other manual painting of elements. This method should only be called during
3481    /// the prepaint phase of element drawing.
3482    pub fn with_absolute_element_offset<R>(
3483        &mut self,
3484        offset: Point<Pixels>,
3485        f: impl FnOnce(&mut Self) -> R,
3486    ) -> R {
3487        self.invalidator.debug_assert_prepaint();
3488        self.element_offset_stack.push(offset);
3489        let result = f(self);
3490        self.element_offset_stack.pop();
3491        result
3492    }
3493
3494    pub(crate) fn with_element_opacity<R>(
3495        &mut self,
3496        opacity: Option<f32>,
3497        f: impl FnOnce(&mut Self) -> R,
3498    ) -> R {
3499        self.invalidator.debug_assert_paint_or_prepaint();
3500
3501        let Some(opacity) = opacity else {
3502            return f(self);
3503        };
3504
3505        let previous_opacity = self.element_opacity;
3506        self.element_opacity = previous_opacity * opacity;
3507        let result = f(self);
3508        self.element_opacity = previous_opacity;
3509        result
3510    }
3511
3512    /// Perform prepaint on child elements in a "retryable" manner, so that any side effects
3513    /// of prepaints can be discarded before prepainting again. This is used to support autoscroll
3514    /// where we need to prepaint children to detect the autoscroll bounds, then adjust the
3515    /// element offset and prepaint again. See [`crate::List`] for an example. This method should only be
3516    /// called during the prepaint phase of element drawing.
3517    pub fn transact<T, U>(&mut self, f: impl FnOnce(&mut Self) -> Result<T, U>) -> Result<T, U> {
3518        self.invalidator.debug_assert_prepaint();
3519        let index = self.prepaint_index();
3520        let result = f(self);
3521        if result.is_err() {
3522            self.next_frame.hitboxes.truncate(index.hitboxes_index);
3523            self.next_frame
3524                .tooltip_requests
3525                .truncate(index.tooltips_index);
3526            self.next_frame
3527                .deferred_draws
3528                .truncate(index.deferred_draws_index);
3529            self.next_frame
3530                .dispatch_tree
3531                .truncate(index.dispatch_tree_index);
3532            self.next_frame
3533                .accessed_element_states
3534                .truncate(index.accessed_element_states_index);
3535            self.text_system.truncate_layouts(index.line_layout_index);
3536        }
3537        result
3538    }
3539
3540    /// When you call this method during [`Element::prepaint`], containing elements will attempt to
3541    /// scroll to cause the specified bounds to become visible. When they decide to autoscroll, they will call
3542    /// [`Element::prepaint`] again with a new set of bounds. See [`crate::List`] for an example of an element
3543    /// that supports this method being called on the elements it contains. This method should only be
3544    /// called during the prepaint phase of element drawing.
3545    pub fn request_autoscroll(&mut self, bounds: Bounds<Pixels>) {
3546        self.invalidator.debug_assert_prepaint();
3547        self.requested_autoscroll = Some(bounds);
3548    }
3549
3550    /// This method can be called from a containing element such as [`crate::List`] to support the autoscroll behavior
3551    /// described in [`Self::request_autoscroll`].
3552    pub fn take_autoscroll(&mut self) -> Option<Bounds<Pixels>> {
3553        self.invalidator.debug_assert_prepaint();
3554        self.requested_autoscroll.take()
3555    }
3556
3557    /// Asynchronously load an asset, if the asset hasn't finished loading this will return None.
3558    /// Your view will be re-drawn once the asset has finished loading.
3559    ///
3560    /// Note that the multiple calls to this method will only result in one `Asset::load` call at a
3561    /// time.
3562    pub fn use_asset<A: Asset>(&mut self, source: &A::Source, cx: &mut App) -> Option<A::Output> {
3563        let (task, is_first) = cx.fetch_asset::<A>(source);
3564        task.clone().now_or_never().or_else(|| {
3565            if is_first {
3566                let entity_id = self.current_view();
3567                self.spawn(cx, {
3568                    let task = task.clone();
3569                    async move |cx| {
3570                        task.await;
3571
3572                        cx.on_next_frame(move |_, cx| {
3573                            cx.notify(entity_id);
3574                        });
3575                    }
3576                })
3577                .detach();
3578            }
3579
3580            None
3581        })
3582    }
3583
3584    /// Asynchronously load an asset, if the asset hasn't finished loading or doesn't exist this will return None.
3585    /// Your view will not be re-drawn once the asset has finished loading.
3586    ///
3587    /// Note that the multiple calls to this method will only result in one `Asset::load` call at a
3588    /// time.
3589    pub fn get_asset<A: Asset>(&mut self, source: &A::Source, cx: &mut App) -> Option<A::Output> {
3590        let (task, _) = cx.fetch_asset::<A>(source);
3591        task.now_or_never()
3592    }
3593    /// Obtain the current element offset. This method should only be called during the
3594    /// prepaint phase of element drawing.
3595    pub fn element_offset(&self) -> Point<Pixels> {
3596        self.invalidator.debug_assert_prepaint();
3597        self.element_offset_stack
3598            .last()
3599            .copied()
3600            .unwrap_or_default()
3601    }
3602
3603    /// Obtain the current element opacity. This method should only be called during the
3604    /// prepaint phase of element drawing.
3605    #[inline]
3606    pub(crate) fn element_opacity(&self) -> f32 {
3607        self.invalidator.debug_assert_paint_or_prepaint();
3608        self.element_opacity
3609    }
3610
3611    /// Obtain the current content mask. This method should only be called during element drawing.
3612    pub fn content_mask(&self) -> ContentMask<Pixels> {
3613        self.invalidator.debug_assert_paint_or_prepaint();
3614        self.content_mask_stack
3615            .last()
3616            .cloned()
3617            .unwrap_or_else(|| ContentMask {
3618                bounds: Bounds {
3619                    origin: Point::default(),
3620                    size: self.viewport_size,
3621                },
3622            })
3623    }
3624
3625    /// Provide elements in the called function with a new namespace in which their identifiers must be unique.
3626    /// This can be used within a custom element to distinguish multiple sets of child elements.
3627    pub fn with_element_namespace<R>(
3628        &mut self,
3629        element_id: impl Into<ElementId>,
3630        f: impl FnOnce(&mut Self) -> R,
3631    ) -> R {
3632        self.element_id_stack.push(element_id.into());
3633        let result = f(self);
3634        self.element_id_stack.pop();
3635        result
3636    }
3637
3638    /// Use a piece of state that exists as long this element is being rendered in consecutive frames.
3639    pub fn use_keyed_state<S: 'static>(
3640        &mut self,
3641        key: impl Into<ElementId>,
3642        cx: &mut App,
3643        init: impl FnOnce(&mut Self, &mut Context<S>) -> S,
3644    ) -> Entity<S> {
3645        let current_view = self.current_view();
3646        self.with_global_id(key.into(), |global_id, window| {
3647            window.with_element_state(global_id, |state: Option<Entity<S>>, window| {
3648                if let Some(state) = state {
3649                    (state.clone(), state)
3650                } else {
3651                    let new_state = cx.new(|cx| init(window, cx));
3652                    cx.observe(&new_state, move |_, cx| {
3653                        cx.notify(current_view);
3654                    })
3655                    .detach();
3656                    (new_state.clone(), new_state)
3657                }
3658            })
3659        })
3660    }
3661
3662    /// Use a piece of state that exists as long this element is being rendered in consecutive frames, without needing to specify a key
3663    ///
3664    /// NOTE: This method uses the location of the caller to generate an ID for this state.
3665    ///       If this is not sufficient to identify your state (e.g. you're rendering a list item),
3666    ///       you can provide a custom ElementID using the `use_keyed_state` method.
3667    #[track_caller]
3668    pub fn use_state<S: 'static>(
3669        &mut self,
3670        cx: &mut App,
3671        init: impl FnOnce(&mut Self, &mut Context<S>) -> S,
3672    ) -> Entity<S> {
3673        self.use_keyed_state(
3674            ElementId::CodeLocation(*core::panic::Location::caller()),
3675            cx,
3676            init,
3677        )
3678    }
3679
3680    /// Updates or initializes state for an element with the given id that lives across multiple
3681    /// frames. If an element with this ID existed in the rendered frame, its state will be passed
3682    /// to the given closure. The state returned by the closure will be stored so it can be referenced
3683    /// when drawing the next frame. This method should only be called as part of element drawing.
3684    pub fn with_element_state<S, R>(
3685        &mut self,
3686        global_id: &GlobalElementId,
3687        f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
3688    ) -> R
3689    where
3690        S: 'static,
3691    {
3692        self.invalidator.debug_assert_paint_or_prepaint();
3693
3694        let key = (global_id.clone(), TypeId::of::<S>());
3695        self.next_frame.accessed_element_states.push(key.clone());
3696
3697        if let Some(any) = self
3698            .next_frame
3699            .element_states
3700            .remove(&key)
3701            .or_else(|| self.rendered_frame.element_states.remove(&key))
3702        {
3703            let ElementStateBox {
3704                inner,
3705                #[cfg(debug_assertions)]
3706                type_name,
3707            } = any;
3708            // Using the extra inner option to avoid needing to reallocate a new box.
3709            let mut state_box = inner
3710                .downcast::<Option<S>>()
3711                .map_err(|_| {
3712                    #[cfg(debug_assertions)]
3713                    {
3714                        anyhow::anyhow!(
3715                            "invalid element state type for id, requested {:?}, actual: {:?}",
3716                            std::any::type_name::<S>(),
3717                            type_name
3718                        )
3719                    }
3720
3721                    #[cfg(not(debug_assertions))]
3722                    {
3723                        anyhow::anyhow!(
3724                            "invalid element state type for id, requested {:?}",
3725                            std::any::type_name::<S>(),
3726                        )
3727                    }
3728                })
3729                .unwrap();
3730
3731            let state = state_box.take().expect(
3732                "reentrant call to with_element_state for the same state type and element id",
3733            );
3734            let (result, state) = f(Some(state), self);
3735            state_box.replace(state);
3736            self.next_frame.element_states.insert(
3737                key,
3738                ElementStateBox {
3739                    inner: state_box,
3740                    #[cfg(debug_assertions)]
3741                    type_name,
3742                },
3743            );
3744            result
3745        } else {
3746            let (result, state) = f(None, self);
3747            self.next_frame.element_states.insert(
3748                key,
3749                ElementStateBox {
3750                    inner: Box::new(Some(state)),
3751                    #[cfg(debug_assertions)]
3752                    type_name: std::any::type_name::<S>(),
3753                },
3754            );
3755            result
3756        }
3757    }
3758
3759    /// A variant of `with_element_state` that allows the element's id to be optional. This is a convenience
3760    /// method for elements where the element id may or may not be assigned. Prefer using `with_element_state`
3761    /// when the element is guaranteed to have an id.
3762    ///
3763    /// The first option means 'no ID provided'
3764    /// The second option means 'not yet initialized'
3765    pub fn with_optional_element_state<S, R>(
3766        &mut self,
3767        global_id: Option<&GlobalElementId>,
3768        f: impl FnOnce(Option<Option<S>>, &mut Self) -> (R, Option<S>),
3769    ) -> R
3770    where
3771        S: 'static,
3772    {
3773        self.invalidator.debug_assert_paint_or_prepaint();
3774
3775        if let Some(global_id) = global_id {
3776            self.with_element_state(global_id, |state, cx| {
3777                let (result, state) = f(Some(state), cx);
3778                let state =
3779                    state.expect("you must return some state when you pass some element id");
3780                (result, state)
3781            })
3782        } else {
3783            let (result, state) = f(None, self);
3784            debug_assert!(
3785                state.is_none(),
3786                "you must not return an element state when passing None for the global id"
3787            );
3788            result
3789        }
3790    }
3791
3792    /// Executes the given closure within the context of a tab group.
3793    #[inline]
3794    pub fn with_tab_group<R>(&mut self, index: Option<isize>, f: impl FnOnce(&mut Self) -> R) -> R {
3795        if let Some(index) = index {
3796            self.next_frame.tab_stops.begin_group(index);
3797            let result = f(self);
3798            self.next_frame.tab_stops.end_group();
3799            result
3800        } else {
3801            f(self)
3802        }
3803    }
3804
3805    /// Defers the drawing of the given element, scheduling it to be painted on top of the currently-drawn tree
3806    /// at a later time. The `priority` parameter determines the drawing order relative to other deferred elements,
3807    /// with higher values being drawn on top.
3808    ///
3809    /// When `content_mask` is provided, the deferred element will be clipped to that region during
3810    /// both prepaint and paint. When `None`, no additional clipping is applied.
3811    ///
3812    /// This method should only be called as part of the prepaint phase of element drawing.
3813    pub fn defer_draw(
3814        &mut self,
3815        element: AnyElement,
3816        absolute_offset: Point<Pixels>,
3817        priority: usize,
3818        content_mask: Option<ContentMask<Pixels>>,
3819    ) {
3820        self.invalidator.debug_assert_prepaint();
3821        let parent_node = self.next_frame.dispatch_tree.active_node_id().unwrap();
3822        self.next_frame.deferred_draws.push(DeferredDraw {
3823            current_view: self.current_view(),
3824            parent_node,
3825            element_id_stack: self.element_id_stack.clone(),
3826            text_style_stack: self.text_style_stack.clone(),
3827            content_mask,
3828            rem_size: self.rem_size(),
3829            priority,
3830            element: Some(element),
3831            absolute_offset,
3832            prepaint_range: PrepaintStateIndex::default()..PrepaintStateIndex::default(),
3833            paint_range: PaintIndex::default()..PaintIndex::default(),
3834        });
3835    }
3836
3837    /// Creates a new painting layer for the specified bounds. A "layer" is a batch
3838    /// of geometry that are non-overlapping and have the same draw order. This is typically used
3839    /// for performance reasons.
3840    ///
3841    /// This method should only be called as part of the paint phase of element drawing.
3842    pub fn paint_layer<R>(&mut self, bounds: Bounds<Pixels>, f: impl FnOnce(&mut Self) -> R) -> R {
3843        self.invalidator.debug_assert_paint();
3844
3845        let content_mask = self.content_mask();
3846        let clipped_bounds = bounds.intersect(&content_mask.bounds);
3847        if !clipped_bounds.is_empty() {
3848            self.next_frame
3849                .scene
3850                .push_layer(self.cover_bounds(clipped_bounds));
3851        }
3852
3853        let result = f(self);
3854
3855        if !clipped_bounds.is_empty() {
3856            self.next_frame.scene.pop_layer();
3857        }
3858
3859        result
3860    }
3861
3862    /// Paint the drop (non-inset) shadows from `shadows` into the scene at the current
3863    /// z-index. Inset shadows are skipped; paint those with [`Self::paint_inset_shadows`]
3864    /// after the element's background so they layer on top of the fill.
3865    ///
3866    /// This method should only be called as part of the paint phase of element drawing.
3867    pub fn paint_drop_shadows(
3868        &mut self,
3869        bounds: Bounds<Pixels>,
3870        corner_radii: Corners<Pixels>,
3871        shadows: &[BoxShadow],
3872    ) {
3873        self.invalidator.debug_assert_paint();
3874
3875        let scale_factor = self.scale_factor();
3876        let content_mask = self.snapped_content_mask();
3877        let opacity = self.element_opacity();
3878        let element_bounds = self.cover_bounds(bounds);
3879        let element_corner_radii = corner_radii.scale(scale_factor);
3880        for shadow in shadows {
3881            if shadow.inset {
3882                continue;
3883            }
3884            let shadow_bounds = (bounds + shadow.offset).dilate(shadow.spread_radius);
3885            self.next_frame.scene.insert_primitive(Shadow {
3886                order: 0,
3887                blur_radius: shadow.blur_radius.scale(scale_factor),
3888                bounds: self.cover_bounds(shadow_bounds),
3889                content_mask,
3890                corner_radii: corner_radii.scale(scale_factor),
3891                color: shadow.color.opacity(opacity),
3892                element_bounds,
3893                element_corner_radii,
3894                inset: 0,
3895                pad: 0,
3896            });
3897        }
3898    }
3899
3900    /// Paint the inset shadows from `shadows` into the scene at the current z-index. Should
3901    /// be called after the element's background so the shadow layers on top of the fill.
3902    /// Drop shadows are skipped; paint those with [`Self::paint_drop_shadows`] before the background.
3903    pub fn paint_inset_shadows(
3904        &mut self,
3905        bounds: Bounds<Pixels>,
3906        corner_radii: Corners<Pixels>,
3907        shadows: &[BoxShadow],
3908    ) {
3909        self.invalidator.debug_assert_paint();
3910
3911        let scale_factor = self.scale_factor();
3912        let content_mask = self.snapped_content_mask();
3913        let opacity = self.element_opacity();
3914        let element_bounds = self.cover_bounds(bounds);
3915        let element_corner_radii = corner_radii.scale(scale_factor);
3916        for shadow in shadows {
3917            if !shadow.inset {
3918                continue;
3919            }
3920            let hole = (bounds + shadow.offset).dilate(-shadow.spread_radius);
3921            // Clamp at zero so a large spread can't produce negative radii, which would
3922            // break the SDF in the shader.
3923            let zero = Pixels::ZERO;
3924            let hole_corner_radii = Corners {
3925                top_left: (corner_radii.top_left - shadow.spread_radius).max(zero),
3926                top_right: (corner_radii.top_right - shadow.spread_radius).max(zero),
3927                bottom_right: (corner_radii.bottom_right - shadow.spread_radius).max(zero),
3928                bottom_left: (corner_radii.bottom_left - shadow.spread_radius).max(zero),
3929            };
3930            self.next_frame.scene.insert_primitive(Shadow {
3931                order: 0,
3932                blur_radius: shadow.blur_radius.scale(scale_factor),
3933                bounds: self.cover_bounds(hole),
3934                content_mask,
3935                corner_radii: hole_corner_radii.scale(scale_factor),
3936                color: shadow.color.opacity(opacity),
3937                element_bounds,
3938                element_corner_radii,
3939                inset: 1,
3940                pad: 0,
3941            });
3942        }
3943    }
3944
3945    /// Paint one or more quads into the scene for the next frame at the current stacking context.
3946    /// Quads are colored rectangular regions with an optional background, border, and corner radius.
3947    /// see [`fill`], [`outline`], and [`quad`] to construct this type.
3948    ///
3949    /// This method should only be called as part of the paint phase of element drawing.
3950    ///
3951    /// Note that the `quad.corner_radii` are allowed to exceed the bounds, creating sharp corners
3952    /// where the circular arcs meet. This will not display well when combined with dashed borders.
3953    /// Use `Corners::clamp_radii_for_quad_size` if the radii should fit within the bounds.
3954    pub fn paint_quad(&mut self, quad: PaintQuad) {
3955        self.invalidator.debug_assert_paint();
3956
3957        let opacity = self.element_opacity();
3958        let snapped_bounds = self.snap_bounds(quad.bounds);
3959        let snapped_border_widths = self.snap_border_widths(quad.border_widths);
3960        let quad = Quad {
3961            order: 0,
3962            bounds: snapped_bounds,
3963            content_mask: self.snapped_content_mask(),
3964            background: quad.background.opacity(opacity),
3965            border_color: quad.border_color.opacity(opacity),
3966            corner_radii: quad.corner_radii.scale(self.scale_factor()),
3967            border_widths: snapped_border_widths,
3968            border_style: quad.border_style,
3969        };
3970
3971        if !quad.background.is_transparent() {
3972            self.next_frame.scene.insert_primitive(quad);
3973            return;
3974        }
3975
3976        // We're drawing a quad with a border but no fill color. Painting this quad would run the quad shader for every
3977        // transparent interior pixel, which is especially costly when the quad is large.
3978        // Instead, split it into four non-overlapping strips that cover the regions where borders are painted:
3979        // the side strips own the straight left and right edges, while the top and bottom strips own the horizontal
3980        // edges and the rounded corners.
3981        let radii = &quad.corner_radii;
3982        let widths = &quad.border_widths;
3983
3984        let antialias_slack = point(ScaledPixels(1.0), ScaledPixels(1.0));
3985        let top_left_inset = point(
3986            widths.left,
3987            widths.top.max(radii.top_left).max(radii.top_right),
3988        ) + antialias_slack;
3989        let bottom_right_inset = point(
3990            widths.right,
3991            widths.bottom.max(radii.bottom_left).max(radii.bottom_right),
3992        ) + antialias_slack;
3993
3994        let outer_bounds = quad.bounds;
3995        let inner_bounds = Bounds::from_corners(
3996            outer_bounds.origin + top_left_inset,
3997            outer_bounds.bottom_right() - bottom_right_inset,
3998        );
3999
4000        if inner_bounds.is_empty() {
4001            self.next_frame.scene.insert_primitive(quad);
4002            return;
4003        }
4004
4005        let strips = [
4006            // Top
4007            Bounds::from_corners(
4008                outer_bounds.origin,
4009                point(outer_bounds.right(), inner_bounds.top()),
4010            ),
4011            // Bottom
4012            Bounds::from_corners(
4013                point(outer_bounds.left(), inner_bounds.bottom()),
4014                outer_bounds.bottom_right(),
4015            ),
4016            // Left
4017            Bounds::from_corners(
4018                point(outer_bounds.left(), inner_bounds.top()),
4019                inner_bounds.bottom_left(),
4020            ),
4021            // Right
4022            Bounds::from_corners(
4023                inner_bounds.top_right(),
4024                point(outer_bounds.right(), inner_bounds.bottom()),
4025            ),
4026        ];
4027
4028        for strip in strips {
4029            let content_mask_bounds = quad.content_mask.bounds.intersect(&strip);
4030            if !content_mask_bounds.is_empty() {
4031                self.next_frame.scene.insert_primitive(Quad {
4032                    content_mask: ContentMask {
4033                        bounds: content_mask_bounds,
4034                    },
4035                    ..quad
4036                });
4037            }
4038        }
4039    }
4040
4041    /// Paint the given `Path` into the scene for the next frame at the current z-index.
4042    ///
4043    /// This method should only be called as part of the paint phase of element drawing.
4044    pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Background>) {
4045        self.invalidator.debug_assert_paint();
4046
4047        let scale_factor = self.scale_factor();
4048        let content_mask = self.content_mask();
4049        let opacity = self.element_opacity();
4050        path.content_mask = content_mask;
4051        let color: Background = color.into();
4052        path.color = color.opacity(opacity);
4053        self.next_frame
4054            .scene
4055            .insert_primitive(path.scale(scale_factor));
4056    }
4057
4058    /// Paint an underline into the scene for the next frame at the current z-index.
4059    ///
4060    /// This method should only be called as part of the paint phase of element drawing.
4061    pub fn paint_underline(
4062        &mut self,
4063        origin: Point<Pixels>,
4064        width: Pixels,
4065        style: &UnderlineStyle,
4066    ) {
4067        self.invalidator.debug_assert_paint();
4068
4069        let scale_factor = self.scale_factor();
4070        let thickness = self.snap_stroke(style.thickness);
4071        let height = if style.wavy {
4072            ScaledPixels(thickness.0 * 3.)
4073        } else {
4074            thickness
4075        };
4076        let bounds = Bounds {
4077            origin: origin.map(|c| ScaledPixels(round_to_device_pixel(c.0, scale_factor))),
4078            size: size(self.snap_stroke(width), height),
4079        };
4080        let element_opacity = self.element_opacity();
4081
4082        self.next_frame.scene.insert_primitive(Underline {
4083            order: 0,
4084            pad: 0,
4085            bounds,
4086            content_mask: self.snapped_content_mask(),
4087            color: style.color.unwrap_or_default().opacity(element_opacity),
4088            thickness,
4089            wavy: style.wavy.into(),
4090        });
4091    }
4092
4093    /// Paint a strikethrough into the scene for the next frame at the current z-index.
4094    ///
4095    /// This method should only be called as part of the paint phase of element drawing.
4096    pub fn paint_strikethrough(
4097        &mut self,
4098        origin: Point<Pixels>,
4099        width: Pixels,
4100        style: &StrikethroughStyle,
4101    ) {
4102        self.invalidator.debug_assert_paint();
4103
4104        let scale_factor = self.scale_factor();
4105        let height = style.thickness;
4106        let bounds = Bounds {
4107            origin: origin.map(|c| ScaledPixels(round_to_device_pixel(c.0, scale_factor))),
4108            size: size(self.snap_stroke(width), self.snap_stroke(height)),
4109        };
4110        let opacity = self.element_opacity();
4111
4112        self.next_frame.scene.insert_primitive(Underline {
4113            order: 0,
4114            pad: 0,
4115            bounds,
4116            content_mask: self.snapped_content_mask(),
4117            thickness: self.snap_stroke(style.thickness),
4118            color: style.color.unwrap_or_default().opacity(opacity),
4119            wavy: false.into(),
4120        });
4121    }
4122
4123    /// Paints a monochrome (non-emoji) glyph into the scene for the next frame at the current z-index.
4124    ///
4125    /// The y component of the origin is the baseline of the glyph.
4126    /// You should generally prefer to use the [`ShapedLine::paint`](crate::ShapedLine::paint) or
4127    /// [`WrappedLine::paint`](crate::WrappedLine::paint) methods in the [`TextSystem`](crate::TextSystem).
4128    /// This method is only useful if you need to paint a single glyph that has already been shaped.
4129    ///
4130    /// This method should only be called as part of the paint phase of element drawing.
4131    pub fn paint_glyph(
4132        &mut self,
4133        origin: Point<Pixels>,
4134        font_id: FontId,
4135        glyph_id: GlyphId,
4136        font_size: Pixels,
4137        color: Hsla,
4138    ) -> Result<()> {
4139        self.invalidator.debug_assert_paint();
4140
4141        let element_opacity = self.element_opacity();
4142        let scale_factor = self.scale_factor();
4143        let glyph_origin = origin.scale(scale_factor);
4144
4145        let quantized_origin = Point::new(
4146            round_half_toward_zero(glyph_origin.x.0 * SUBPIXEL_VARIANTS_X as f32)
4147                / SUBPIXEL_VARIANTS_X as f32,
4148            round_half_toward_zero(glyph_origin.y.0 * SUBPIXEL_VARIANTS_Y as f32)
4149                / SUBPIXEL_VARIANTS_Y as f32,
4150        );
4151        let subpixel_variant = Point::new(
4152            (quantized_origin.x.fract() * SUBPIXEL_VARIANTS_X as f32) as u8,
4153            (quantized_origin.y.fract() * SUBPIXEL_VARIANTS_Y as f32) as u8,
4154        );
4155        let integer_origin = quantized_origin.map(|c| ScaledPixels(c.trunc()));
4156        let subpixel_rendering = self.should_use_subpixel_rendering(font_id, font_size);
4157        let dilation = self.text_system().glyph_dilation_for_color(color);
4158        let params = RenderGlyphParams {
4159            font_id,
4160            glyph_id,
4161            font_size,
4162            subpixel_variant,
4163            scale_factor,
4164            is_emoji: false,
4165            subpixel_rendering,
4166            dilation,
4167        };
4168
4169        let raster_bounds = self.text_system().raster_bounds(&params)?;
4170        if !raster_bounds.is_zero() {
4171            let tile = self
4172                .sprite_atlas
4173                .get_or_insert_with(&params.clone().into(), &mut || {
4174                    let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
4175                    Ok(Some((size, Cow::Owned(bytes))))
4176                })?
4177                .expect("Callback above only errors or returns Some");
4178            let bounds = Bounds {
4179                origin: integer_origin + raster_bounds.origin.map(Into::into),
4180                size: tile.bounds.size.map(Into::into),
4181            };
4182            let content_mask = self.snapped_content_mask();
4183
4184            if subpixel_rendering {
4185                self.next_frame.scene.insert_primitive(SubpixelSprite {
4186                    order: 0,
4187                    pad: 0,
4188                    bounds,
4189                    content_mask,
4190                    color: color.opacity(element_opacity),
4191                    tile,
4192                    transformation: TransformationMatrix::unit(),
4193                });
4194            } else {
4195                self.next_frame.scene.insert_primitive(MonochromeSprite {
4196                    order: 0,
4197                    pad: 0,
4198                    bounds,
4199                    content_mask,
4200                    color: color.opacity(element_opacity),
4201                    tile,
4202                    transformation: TransformationMatrix::unit(),
4203                });
4204            }
4205        }
4206        Ok(())
4207    }
4208
4209    fn should_use_subpixel_rendering(&self, font_id: FontId, font_size: Pixels) -> bool {
4210        if self.platform_window.background_appearance() != WindowBackgroundAppearance::Opaque {
4211            return false;
4212        }
4213
4214        if !self.platform_window.is_subpixel_rendering_supported() {
4215            return false;
4216        }
4217
4218        let mode = match self.text_rendering_mode.get() {
4219            TextRenderingMode::PlatformDefault => self
4220                .text_system()
4221                .recommended_rendering_mode(font_id, font_size),
4222            mode => mode,
4223        };
4224
4225        mode == TextRenderingMode::Subpixel
4226    }
4227
4228    /// Paints an emoji glyph into the scene for the next frame at the current z-index.
4229    ///
4230    /// The y component of the origin is the baseline of the glyph.
4231    /// You should generally prefer to use the [`ShapedLine::paint`](crate::ShapedLine::paint) or
4232    /// [`WrappedLine::paint`](crate::WrappedLine::paint) methods in the [`TextSystem`](crate::TextSystem).
4233    /// This method is only useful if you need to paint a single emoji that has already been shaped.
4234    ///
4235    /// This method should only be called as part of the paint phase of element drawing.
4236    pub fn paint_emoji(
4237        &mut self,
4238        origin: Point<Pixels>,
4239        font_id: FontId,
4240        glyph_id: GlyphId,
4241        font_size: Pixels,
4242    ) -> Result<()> {
4243        self.invalidator.debug_assert_paint();
4244
4245        let scale_factor = self.scale_factor();
4246        let glyph_origin = origin.scale(scale_factor);
4247        let integer_origin = glyph_origin.map(|c| ScaledPixels(round_half_toward_zero(c.0)));
4248        let params = RenderGlyphParams {
4249            font_id,
4250            glyph_id,
4251            font_size,
4252            subpixel_variant: Default::default(),
4253            scale_factor,
4254            is_emoji: true,
4255            subpixel_rendering: false,
4256            dilation: 0,
4257        };
4258
4259        let raster_bounds = self.text_system().raster_bounds(&params)?;
4260        if !raster_bounds.is_zero() {
4261            let tile = self
4262                .sprite_atlas
4263                .get_or_insert_with(&params.clone().into(), &mut || {
4264                    let (size, bytes) = self.text_system().rasterize_glyph(&params)?;
4265                    Ok(Some((size, Cow::Owned(bytes))))
4266                })?
4267                .expect("Callback above only errors or returns Some");
4268
4269            let bounds = Bounds {
4270                origin: integer_origin + raster_bounds.origin.map(Into::into),
4271                size: tile.bounds.size.map(Into::into),
4272            };
4273            let content_mask = self.snapped_content_mask();
4274            let opacity = self.element_opacity();
4275
4276            self.next_frame.scene.insert_primitive(PolychromeSprite {
4277                order: 0,
4278                pad: 0,
4279                grayscale: false.into(),
4280                bounds,
4281                corner_radii: Default::default(),
4282                content_mask,
4283                tile,
4284                opacity,
4285            });
4286        }
4287        Ok(())
4288    }
4289
4290    /// Paint a monochrome SVG into the scene for the next frame at the current stacking context.
4291    ///
4292    /// This method should only be called as part of the paint phase of element drawing.
4293    pub fn paint_svg(
4294        &mut self,
4295        bounds: Bounds<Pixels>,
4296        path: SharedString,
4297        mut data: Option<&[u8]>,
4298        transformation: TransformationMatrix,
4299        color: Hsla,
4300        cx: &App,
4301    ) -> Result<()> {
4302        self.invalidator.debug_assert_paint();
4303
4304        let element_opacity = self.element_opacity();
4305        let bounds = self.snap_bounds(bounds);
4306
4307        let params = RenderSvgParams {
4308            path,
4309            size: bounds.size.map(|pixels| {
4310                DevicePixels::from((pixels.0 * SMOOTH_SVG_SCALE_FACTOR).ceil() as i32)
4311            }),
4312        };
4313
4314        let Some(tile) =
4315            self.sprite_atlas
4316                .get_or_insert_with(&params.clone().into(), &mut || {
4317                    let Some((size, bytes)) = cx.svg_renderer.render_alpha_mask(&params, data)?
4318                    else {
4319                        return Ok(None);
4320                    };
4321                    Ok(Some((size, Cow::Owned(bytes))))
4322                })?
4323        else {
4324            return Ok(());
4325        };
4326        let content_mask = self.snapped_content_mask();
4327        let svg_bounds = Bounds {
4328            origin: bounds.center()
4329                - Point::new(
4330                    ScaledPixels(tile.bounds.size.width.0 as f32 / SMOOTH_SVG_SCALE_FACTOR / 2.),
4331                    ScaledPixels(tile.bounds.size.height.0 as f32 / SMOOTH_SVG_SCALE_FACTOR / 2.),
4332                ),
4333            size: tile
4334                .bounds
4335                .size
4336                .map(|value| ScaledPixels(value.0 as f32 / SMOOTH_SVG_SCALE_FACTOR)),
4337        };
4338        let final_bounds = svg_bounds
4339            .map_origin(|value| ScaledPixels(round_half_toward_zero(value.0)))
4340            .map_size(|size| size.ceil());
4341
4342        self.next_frame.scene.insert_primitive(MonochromeSprite {
4343            order: 0,
4344            pad: 0,
4345            bounds: final_bounds,
4346            content_mask,
4347            color: color.opacity(element_opacity),
4348            tile,
4349            transformation,
4350        });
4351
4352        Ok(())
4353    }
4354
4355    /// Paint an image into the scene for the next frame at the current z-index.
4356    /// This method will panic if the frame_index is not valid
4357    ///
4358    /// This method should only be called as part of the paint phase of element drawing.
4359    pub fn paint_image(
4360        &mut self,
4361        bounds: Bounds<Pixels>,
4362        corner_radii: Corners<Pixels>,
4363        data: Arc<RenderImage>,
4364        frame_index: usize,
4365        grayscale: bool,
4366    ) -> Result<()> {
4367        self.invalidator.debug_assert_paint();
4368
4369        let bounds = self.snap_bounds(bounds);
4370        let params = RenderImageParams {
4371            image_id: data.id,
4372            frame_index,
4373        };
4374
4375        let tile = self
4376            .sprite_atlas
4377            .get_or_insert_with(&params.into(), &mut || {
4378                Ok(Some((
4379                    data.size(frame_index),
4380                    Cow::Borrowed(
4381                        data.as_bytes(frame_index)
4382                            .expect("It's the caller's job to pass a valid frame index"),
4383                    ),
4384                )))
4385            })?
4386            .expect("Callback above only returns Some");
4387        let content_mask = self.snapped_content_mask();
4388        let corner_radii = corner_radii.scale(self.scale_factor());
4389        let opacity = self.element_opacity();
4390
4391        self.next_frame.scene.insert_primitive(PolychromeSprite {
4392            order: 0,
4393            pad: 0,
4394            grayscale: grayscale.into(),
4395            bounds,
4396            content_mask,
4397            corner_radii,
4398            tile,
4399            opacity,
4400        });
4401        Ok(())
4402    }
4403
4404    /// Paint a surface into the scene for the next frame at the current z-index.
4405    ///
4406    /// This method should only be called as part of the paint phase of element drawing.
4407    #[cfg(target_os = "macos")]
4408    pub fn paint_surface(&mut self, bounds: Bounds<Pixels>, image_buffer: CVPixelBuffer) {
4409        use crate::PaintSurface;
4410
4411        self.invalidator.debug_assert_paint();
4412
4413        let bounds = self.snap_bounds(bounds);
4414        let content_mask = self.snapped_content_mask();
4415        self.next_frame.scene.insert_primitive(PaintSurface {
4416            order: 0,
4417            bounds,
4418            content_mask,
4419            image_buffer,
4420        });
4421    }
4422
4423    /// Removes an image from the sprite atlas.
4424    pub fn drop_image(&mut self, data: Arc<RenderImage>) -> Result<()> {
4425        for frame_index in 0..data.frame_count() {
4426            let params = RenderImageParams {
4427                image_id: data.id,
4428                frame_index,
4429            };
4430
4431            self.sprite_atlas.remove(&params.clone().into());
4432        }
4433
4434        Ok(())
4435    }
4436
4437    /// Add a node to the layout tree for the current frame. Takes the `Style` of the element for which
4438    /// layout is being requested, along with the layout ids of any children. This method is called during
4439    /// calls to the [`Element::request_layout`] trait method and enables any element to participate in layout.
4440    ///
4441    /// This method should only be called as part of the request_layout or prepaint phase of element drawing.
4442    #[must_use]
4443    pub fn request_layout(
4444        &mut self,
4445        style: Style,
4446        children: impl IntoIterator<Item = LayoutId>,
4447        cx: &mut App,
4448    ) -> LayoutId {
4449        self.invalidator.debug_assert_prepaint();
4450
4451        cx.layout_id_buffer.clear();
4452        cx.layout_id_buffer.extend(children);
4453        let rem_size = self.rem_size();
4454        let scale_factor = self.scale_factor();
4455
4456        self.layout_engine.as_mut().unwrap().request_layout(
4457            style,
4458            rem_size,
4459            scale_factor,
4460            &cx.layout_id_buffer,
4461        )
4462    }
4463
4464    /// Add a node to the layout tree for the current frame. Instead of taking a `Style` and children,
4465    /// this variant takes a function that is invoked during layout so you can use arbitrary logic to
4466    /// determine the element's size. One place this is used internally is when measuring text.
4467    ///
4468    /// The given closure is invoked at layout time with the known dimensions and available space and
4469    /// returns a `Size`.
4470    ///
4471    /// This method should only be called as part of the request_layout or prepaint phase of element drawing.
4472    pub fn request_measured_layout<F>(&mut self, style: Style, measure: F) -> LayoutId
4473    where
4474        F: Fn(Size<Option<Pixels>>, Size<AvailableSpace>, &mut Window, &mut App) -> Size<Pixels>
4475            + 'static,
4476    {
4477        self.invalidator.debug_assert_prepaint();
4478
4479        let rem_size = self.rem_size();
4480        let scale_factor = self.scale_factor();
4481        self.layout_engine
4482            .as_mut()
4483            .unwrap()
4484            .request_measured_layout(style, rem_size, scale_factor, measure)
4485    }
4486
4487    /// Compute the layout for the given id within the given available space.
4488    /// This method is called for its side effect, typically by the framework prior to painting.
4489    /// After calling it, you can request the bounds of the given layout node id or any descendant.
4490    ///
4491    /// This method should only be called as part of the prepaint phase of element drawing.
4492    pub fn compute_layout(
4493        &mut self,
4494        layout_id: LayoutId,
4495        available_space: Size<AvailableSpace>,
4496        cx: &mut App,
4497    ) {
4498        self.invalidator.debug_assert_prepaint();
4499
4500        let mut layout_engine = self.layout_engine.take().unwrap();
4501        layout_engine.compute_layout(layout_id, available_space, self, cx);
4502        self.layout_engine = Some(layout_engine);
4503    }
4504
4505    /// Obtain the bounds computed for the given LayoutId relative to the window. This method will usually be invoked by
4506    /// GPUI itself automatically in order to pass your element its `Bounds` automatically.
4507    ///
4508    /// This method should only be called as part of element drawing.
4509    pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Bounds<Pixels> {
4510        self.invalidator.debug_assert_prepaint();
4511
4512        let scale_factor = self.scale_factor();
4513        let mut bounds = self
4514            .layout_engine
4515            .as_mut()
4516            .unwrap()
4517            .layout_bounds(layout_id, scale_factor)
4518            .map(Into::into);
4519        let snapped_offset = self.pixel_snap_point(self.element_offset());
4520        bounds.origin += snapped_offset;
4521        bounds
4522    }
4523
4524    /// This method should be called during `prepaint`. You can use
4525    /// the returned [Hitbox] during `paint` or in an event handler
4526    /// to determine whether the inserted hitbox was the topmost.
4527    ///
4528    /// This method should only be called as part of the prepaint phase of element drawing.
4529    pub fn insert_hitbox(&mut self, bounds: Bounds<Pixels>, behavior: HitboxBehavior) -> Hitbox {
4530        self.invalidator.debug_assert_prepaint();
4531
4532        let content_mask = self.content_mask();
4533        let mut id = self.next_hitbox_id;
4534        self.next_hitbox_id = self.next_hitbox_id.next();
4535        let hitbox = Hitbox {
4536            id,
4537            bounds,
4538            content_mask,
4539            behavior,
4540        };
4541        self.next_frame.hitboxes.push(hitbox.clone());
4542        hitbox
4543    }
4544
4545    /// Set a hitbox which will act as a control area of the platform window.
4546    ///
4547    /// This method should only be called as part of the paint phase of element drawing.
4548    pub fn insert_window_control_hitbox(&mut self, area: WindowControlArea, hitbox: Hitbox) {
4549        self.invalidator.debug_assert_paint();
4550        self.next_frame.window_control_hitboxes.push((area, hitbox));
4551    }
4552
4553    /// Sets the key context for the current element. This context will be used to translate
4554    /// keybindings into actions.
4555    ///
4556    /// This method should only be called as part of the paint phase of element drawing.
4557    pub fn set_key_context(&mut self, context: KeyContext) {
4558        self.invalidator.debug_assert_paint();
4559        self.next_frame.dispatch_tree.set_key_context(context);
4560    }
4561
4562    /// Sets the focus handle for the current element. This handle will be used to manage focus state
4563    /// and keyboard event dispatch for the element.
4564    ///
4565    /// This method should only be called as part of the prepaint phase of element drawing.
4566    pub fn set_focus_handle(&mut self, focus_handle: &FocusHandle, _: &App) {
4567        self.invalidator.debug_assert_prepaint();
4568        if focus_handle.is_focused(self) {
4569            self.next_frame.focus = Some(focus_handle.id);
4570        }
4571        self.next_frame.dispatch_tree.set_focus_id(focus_handle.id);
4572    }
4573
4574    /// Sets the view id for the current element, which will be used to manage view caching.
4575    ///
4576    /// This method should only be called as part of element prepaint. We plan on removing this
4577    /// method eventually when we solve some issues that require us to construct editor elements
4578    /// directly instead of always using editors via views.
4579    pub fn set_view_id(&mut self, view_id: EntityId) {
4580        self.invalidator.debug_assert_prepaint();
4581        self.next_frame.dispatch_tree.set_view_id(view_id);
4582    }
4583
4584    /// Get the entity ID for the currently rendering view
4585    pub fn current_view(&self) -> EntityId {
4586        self.invalidator.debug_assert_paint_or_prepaint();
4587        self.rendered_entity_stack.last().copied().unwrap()
4588    }
4589
4590    #[inline]
4591    pub(crate) fn with_rendered_view<R>(
4592        &mut self,
4593        id: EntityId,
4594        f: impl FnOnce(&mut Self) -> R,
4595    ) -> R {
4596        self.rendered_entity_stack.push(id);
4597        let result = f(self);
4598        self.rendered_entity_stack.pop();
4599        result
4600    }
4601
4602    /// Executes the provided function with the specified image cache.
4603    pub fn with_image_cache<F, R>(&mut self, image_cache: Option<AnyImageCache>, f: F) -> R
4604    where
4605        F: FnOnce(&mut Self) -> R,
4606    {
4607        if let Some(image_cache) = image_cache {
4608            self.image_cache_stack.push(image_cache);
4609            let result = f(self);
4610            self.image_cache_stack.pop();
4611            result
4612        } else {
4613            f(self)
4614        }
4615    }
4616
4617    /// Sets an input handler, such as [`ElementInputHandler`][element_input_handler], which interfaces with the
4618    /// platform to receive textual input with proper integration with concerns such
4619    /// as IME interactions. This handler will be active for the upcoming frame until the following frame is
4620    /// rendered.
4621    ///
4622    /// This method should only be called as part of the paint phase of element drawing.
4623    ///
4624    /// [element_input_handler]: crate::ElementInputHandler
4625    pub fn handle_input(
4626        &mut self,
4627        focus_handle: &FocusHandle,
4628        input_handler: impl InputHandler,
4629        cx: &App,
4630    ) {
4631        self.invalidator.debug_assert_paint();
4632
4633        if focus_handle.is_focused(self) {
4634            let cx = self.to_async(cx);
4635            self.next_frame
4636                .input_handlers
4637                .push(Some(PlatformInputHandler::new(cx, Box::new(input_handler))));
4638        }
4639    }
4640
4641    /// Register a mouse event listener on the window for the next frame. The type of event
4642    /// is determined by the first parameter of the given listener. When the next frame is rendered
4643    /// the listener will be cleared.
4644    ///
4645    /// This method should only be called as part of the paint phase of element drawing.
4646    pub fn on_mouse_event<Event: MouseEvent>(
4647        &mut self,
4648        mut listener: impl FnMut(&Event, DispatchPhase, &mut Window, &mut App) + 'static,
4649    ) {
4650        self.invalidator.debug_assert_paint();
4651
4652        self.next_frame.mouse_listeners.push(Some(Box::new(
4653            move |event: &dyn Any, phase: DispatchPhase, window: &mut Window, cx: &mut App| {
4654                if let Some(event) = event.downcast_ref() {
4655                    listener(event, phase, window, cx)
4656                }
4657            },
4658        )));
4659    }
4660
4661    /// Register a key event listener on this node for the next frame. The type of event
4662    /// is determined by the first parameter of the given listener. When the next frame is rendered
4663    /// the listener will be cleared.
4664    ///
4665    /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
4666    /// a specific need to register a listener yourself.
4667    ///
4668    /// This method should only be called as part of the paint phase of element drawing.
4669    pub fn on_key_event<Event: KeyEvent>(
4670        &mut self,
4671        listener: impl Fn(&Event, DispatchPhase, &mut Window, &mut App) + 'static,
4672    ) {
4673        self.invalidator.debug_assert_paint();
4674
4675        self.next_frame.dispatch_tree.on_key_event(Rc::new(
4676            move |event: &dyn Any, phase, window: &mut Window, cx: &mut App| {
4677                if let Some(event) = event.downcast_ref::<Event>() {
4678                    listener(event, phase, window, cx)
4679                }
4680            },
4681        ));
4682    }
4683
4684    /// Register a modifiers changed event listener on the window for the next frame.
4685    ///
4686    /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
4687    /// a specific need to register a global listener.
4688    ///
4689    /// This method should only be called as part of the paint phase of element drawing.
4690    pub fn on_modifiers_changed(
4691        &mut self,
4692        listener: impl Fn(&ModifiersChangedEvent, &mut Window, &mut App) + 'static,
4693    ) {
4694        self.invalidator.debug_assert_paint();
4695
4696        self.next_frame.dispatch_tree.on_modifiers_changed(Rc::new(
4697            move |event: &ModifiersChangedEvent, window: &mut Window, cx: &mut App| {
4698                listener(event, window, cx)
4699            },
4700        ));
4701    }
4702
4703    /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
4704    /// This does not fire if the given focus handle - or one of its descendants - was previously focused.
4705    /// Returns a subscription and persists until the subscription is dropped.
4706    pub fn on_focus_in(
4707        &mut self,
4708        handle: &FocusHandle,
4709        cx: &mut App,
4710        mut listener: impl FnMut(&mut Window, &mut App) + 'static,
4711    ) -> Subscription {
4712        let focus_id = handle.id;
4713        let (subscription, activate) =
4714            self.new_focus_listener(Box::new(move |event, window, cx| {
4715                if event.is_focus_in(focus_id) {
4716                    listener(window, cx);
4717                }
4718                true
4719            }));
4720        cx.defer(move |_| activate());
4721        subscription
4722    }
4723
4724    /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
4725    /// Returns a subscription and persists until the subscription is dropped.
4726    pub fn on_focus_out(
4727        &mut self,
4728        handle: &FocusHandle,
4729        cx: &mut App,
4730        mut listener: impl FnMut(FocusOutEvent, &mut Window, &mut App) + 'static,
4731    ) -> Subscription {
4732        let focus_id = handle.id;
4733        let (subscription, activate) =
4734            self.new_focus_listener(Box::new(move |event, window, cx| {
4735                if let Some(blurred_id) = event.previous_focus_path.last().copied()
4736                    && event.is_focus_out(focus_id)
4737                {
4738                    let event = FocusOutEvent {
4739                        blurred: WeakFocusHandle {
4740                            id: blurred_id,
4741                            handles: Arc::downgrade(&cx.focus_handles),
4742                        },
4743                    };
4744                    listener(event, window, cx)
4745                }
4746                true
4747            }));
4748        cx.defer(move |_| activate());
4749        subscription
4750    }
4751
4752    fn reset_cursor_style(&self, cx: &mut App) {
4753        // Set the cursor only if we're the active window.
4754        if self.is_window_hovered() {
4755            let style = self
4756                .rendered_frame
4757                .cursor_style(self)
4758                .unwrap_or(CursorStyle::Arrow);
4759            cx.platform.set_cursor_style(style);
4760        }
4761    }
4762
4763    /// Dispatch a given keystroke as though the user had typed it.
4764    /// You can create a keystroke with Keystroke::parse("").
4765    pub fn dispatch_keystroke(&mut self, keystroke: Keystroke, cx: &mut App) -> bool {
4766        let keystroke = keystroke.with_simulated_ime();
4767        let result = self.dispatch_event(
4768            PlatformInput::KeyDown(KeyDownEvent {
4769                keystroke: keystroke.clone(),
4770                is_held: false,
4771                prefer_character_input: false,
4772            }),
4773            cx,
4774        );
4775        if !result.propagate {
4776            return true;
4777        }
4778
4779        if let Some(input) = keystroke.key_char
4780            && let Some(mut input_handler) = self.platform_window.take_input_handler()
4781        {
4782            input_handler.dispatch_input(&input, self, cx);
4783            self.platform_window.set_input_handler(input_handler);
4784            return true;
4785        }
4786
4787        false
4788    }
4789
4790    /// Return a key binding string for an action, to display in the UI. Uses the highest precedence
4791    /// binding for the action (last binding added to the keymap).
4792    pub fn keystroke_text_for(&self, action: &dyn Action) -> String {
4793        self.highest_precedence_binding_for_action(action)
4794            .map(|binding| {
4795                binding
4796                    .keystrokes()
4797                    .iter()
4798                    .map(ToString::to_string)
4799                    .collect::<Vec<_>>()
4800                    .join(" ")
4801            })
4802            .unwrap_or_else(|| action.name().to_string())
4803    }
4804
4805    /// Dispatch a mouse or keyboard event on the window.
4806    #[profiling::function]
4807    pub fn dispatch_event(&mut self, event: PlatformInput, cx: &mut App) -> DispatchEventResult {
4808        #[cfg(feature = "input-latency-histogram")]
4809        let dispatch_time = Instant::now();
4810        let update_count_before = self.invalidator.update_count();
4811        // Track input modality for focus-visible styling and hover suppression.
4812        // Hover is suppressed during keyboard modality so that keyboard navigation
4813        // doesn't show hover highlights on the item under the mouse cursor.
4814        let old_modality = self.last_input_modality;
4815        self.last_input_modality = match &event {
4816            PlatformInput::KeyDown(_) => InputModality::Keyboard,
4817            PlatformInput::MouseMove(_) | PlatformInput::MouseDown(_) => InputModality::Mouse,
4818            PlatformInput::Touch(_) => InputModality::Touch,
4819            _ => self.last_input_modality,
4820        };
4821        if self.last_input_modality != old_modality {
4822            self.refresh();
4823        }
4824
4825        // Handlers may set this to false by calling `stop_propagation`.
4826        cx.propagate_event = true;
4827        // Handlers may set this to true by calling `prevent_default`.
4828        self.default_prevented = false;
4829
4830        let event = match event {
4831            // Track the mouse position with our own state, since accessing the platform
4832            // API for the mouse position can only occur on the main thread.
4833            PlatformInput::MouseMove(mouse_move) => {
4834                self.mouse_position = mouse_move.position;
4835                self.modifiers = mouse_move.modifiers;
4836                PlatformInput::MouseMove(mouse_move)
4837            }
4838            PlatformInput::MouseDown(mouse_down) => {
4839                self.mouse_position = mouse_down.position;
4840                self.modifiers = mouse_down.modifiers;
4841                PlatformInput::MouseDown(mouse_down)
4842            }
4843            PlatformInput::MouseUp(mouse_up) => {
4844                self.mouse_position = mouse_up.position;
4845                self.modifiers = mouse_up.modifiers;
4846                PlatformInput::MouseUp(mouse_up)
4847            }
4848            PlatformInput::MousePressure(mouse_pressure) => {
4849                PlatformInput::MousePressure(mouse_pressure)
4850            }
4851            PlatformInput::MouseExited(mouse_exited) => {
4852                self.modifiers = mouse_exited.modifiers;
4853                PlatformInput::MouseExited(mouse_exited)
4854            }
4855            PlatformInput::ModifiersChanged(modifiers_changed) => {
4856                self.modifiers = modifiers_changed.modifiers;
4857                self.capslock = modifiers_changed.capslock;
4858                PlatformInput::ModifiersChanged(modifiers_changed)
4859            }
4860            PlatformInput::ScrollWheel(scroll_wheel) => {
4861                self.mouse_position = scroll_wheel.position;
4862                self.modifiers = scroll_wheel.modifiers;
4863                PlatformInput::ScrollWheel(scroll_wheel)
4864            }
4865            PlatformInput::Pinch(pinch) => {
4866                self.mouse_position = pinch.position;
4867                self.modifiers = pinch.modifiers;
4868                PlatformInput::Pinch(pinch)
4869            }
4870            // Translate dragging and dropping of external files from the operating system
4871            // to internal drag and drop events.
4872            PlatformInput::FileDrop(file_drop) => match file_drop {
4873                FileDropEvent::Entered { position, paths } => {
4874                    self.mouse_position = position;
4875                    if cx.active_drag.is_none() {
4876                        cx.active_drag = Some(AnyDrag {
4877                            value: Arc::new(paths.clone()),
4878                            view: cx.new(|_| paths).into(),
4879                            cursor_offset: position,
4880                            cursor_style: None,
4881                        });
4882                    }
4883                    PlatformInput::MouseMove(MouseMoveEvent {
4884                        position,
4885                        pressed_button: Some(MouseButton::Left),
4886                        modifiers: Modifiers::default(),
4887                    })
4888                }
4889                FileDropEvent::Pending { position } => {
4890                    self.mouse_position = position;
4891                    PlatformInput::MouseMove(MouseMoveEvent {
4892                        position,
4893                        pressed_button: Some(MouseButton::Left),
4894                        modifiers: Modifiers::default(),
4895                    })
4896                }
4897                FileDropEvent::Submit { position } => {
4898                    cx.activate(true);
4899                    self.mouse_position = position;
4900                    PlatformInput::MouseUp(MouseUpEvent {
4901                        button: MouseButton::Left,
4902                        position,
4903                        modifiers: Modifiers::default(),
4904                        click_count: 1,
4905                    })
4906                }
4907                FileDropEvent::Exited => {
4908                    cx.active_drag.take();
4909                    PlatformInput::FileDrop(FileDropEvent::Exited)
4910                }
4911            },
4912            PlatformInput::Touch(touch) => PlatformInput::Touch(touch),
4913            PlatformInput::KeyDown(_) | PlatformInput::KeyUp(_) => event,
4914        };
4915
4916        if let Some(any_mouse_event) = event.mouse_event() {
4917            self.dispatch_mouse_event(any_mouse_event, cx);
4918        } else if let Some(any_key_event) = event.keyboard_event() {
4919            self.dispatch_key_event(any_key_event, cx);
4920        }
4921
4922        if self.invalidator.update_count() > update_count_before {
4923            self.input_rate_tracker.borrow_mut().record_input();
4924            #[cfg(feature = "input-latency-histogram")]
4925            if self.invalidator.not_drawing() {
4926                self.input_latency_tracker.record_input(dispatch_time);
4927            } else {
4928                self.input_latency_tracker.record_mid_draw_input();
4929            }
4930        }
4931
4932        DispatchEventResult {
4933            propagate: cx.propagate_event,
4934            default_prevented: self.default_prevented,
4935        }
4936    }
4937
4938    fn dispatch_mouse_event(&mut self, event: &dyn Any, cx: &mut App) {
4939        let hit_test = self.rendered_frame.hit_test(self.mouse_position());
4940        if hit_test != self.mouse_hit_test {
4941            self.mouse_hit_test = hit_test;
4942            self.reset_cursor_style(cx);
4943        }
4944
4945        #[cfg(any(feature = "inspector", debug_assertions))]
4946        if self.is_inspector_picking(cx) {
4947            self.handle_inspector_mouse_event(event, cx);
4948            // When inspector is picking, all other mouse handling is skipped.
4949            return;
4950        }
4951
4952        let mut mouse_listeners = mem::take(&mut self.rendered_frame.mouse_listeners);
4953
4954        // Capture phase, events bubble from back to front. Handlers for this phase are used for
4955        // special purposes, such as detecting events outside of a given Bounds.
4956        for listener in &mut mouse_listeners {
4957            let listener = listener.as_mut().unwrap();
4958            listener(event, DispatchPhase::Capture, self, cx);
4959            if !cx.propagate_event {
4960                break;
4961            }
4962        }
4963
4964        // Bubble phase, where most normal handlers do their work.
4965        if cx.propagate_event {
4966            for listener in mouse_listeners.iter_mut().rev() {
4967                let listener = listener.as_mut().unwrap();
4968                listener(event, DispatchPhase::Bubble, self, cx);
4969                if !cx.propagate_event {
4970                    break;
4971                }
4972            }
4973        }
4974
4975        self.rendered_frame.mouse_listeners = mouse_listeners;
4976
4977        if cx.has_active_drag() {
4978            if event.is::<MouseMoveEvent>() {
4979                // If this was a mouse move event, redraw the window so that the
4980                // active drag can follow the mouse cursor.
4981                self.refresh();
4982            } else if event.is::<MouseUpEvent>() {
4983                // If this was a mouse up event, cancel the active drag and redraw
4984                // the window.
4985                cx.active_drag = None;
4986                self.refresh();
4987            }
4988        }
4989
4990        // Auto-release pointer capture on mouse up
4991        if event.is::<MouseUpEvent>() && self.captured_hitbox.is_some() {
4992            self.captured_hitbox = None;
4993        }
4994    }
4995
4996    fn dispatch_key_event(&mut self, event: &dyn Any, cx: &mut App) {
4997        if self.invalidator.is_dirty() {
4998            self.draw(cx).clear(cx);
4999        }
5000
5001        let node_id = self.focus_node_id_in_rendered_frame(self.focus);
5002        let dispatch_path = self.rendered_frame.dispatch_tree.dispatch_path(node_id);
5003
5004        let mut keystroke: Option<Keystroke> = None;
5005
5006        if let Some(event) = event.downcast_ref::<ModifiersChangedEvent>() {
5007            if event.modifiers.number_of_modifiers() == 0
5008                && self.pending_modifier.modifiers.number_of_modifiers() == 1
5009                && !self.pending_modifier.saw_keystroke
5010            {
5011                let key = match self.pending_modifier.modifiers {
5012                    modifiers if modifiers.shift => Some("shift"),
5013                    modifiers if modifiers.control => Some("control"),
5014                    modifiers if modifiers.alt => Some("alt"),
5015                    modifiers if modifiers.platform => Some("platform"),
5016                    modifiers if modifiers.function => Some("function"),
5017                    _ => None,
5018                };
5019                if let Some(key) = key {
5020                    keystroke = Some(Keystroke {
5021                        key: key.to_string(),
5022                        key_char: None,
5023                        modifiers: Modifiers::default(),
5024                    });
5025                }
5026            }
5027
5028            if self.pending_modifier.modifiers.number_of_modifiers() == 0
5029                && event.modifiers.number_of_modifiers() == 1
5030            {
5031                self.pending_modifier.saw_keystroke = false
5032            }
5033            self.pending_modifier.modifiers = event.modifiers
5034        } else if let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() {
5035            self.pending_modifier.saw_keystroke = true;
5036            keystroke = Some(key_down_event.keystroke.clone());
5037            if key_down_event.keystroke.key_char.is_some()
5038                && matches!(
5039                    cx.cursor_hide_mode,
5040                    CursorHideMode::OnTyping | CursorHideMode::OnTypingAndAction
5041                )
5042            {
5043                cx.platform.hide_cursor_until_mouse_moves();
5044            }
5045        }
5046
5047        let Some(keystroke) = keystroke else {
5048            self.finish_dispatch_key_event(event, dispatch_path, self.context_stack(), cx);
5049            return;
5050        };
5051
5052        cx.propagate_event = true;
5053        self.dispatch_keystroke_interceptors(event, self.context_stack(), cx);
5054        if !cx.propagate_event {
5055            self.finish_dispatch_key_event(event, dispatch_path, self.context_stack(), cx);
5056            return;
5057        }
5058
5059        let mut currently_pending = self.pending_input.take().unwrap_or_default();
5060        if currently_pending.focus.is_some() && currently_pending.focus != self.focus {
5061            currently_pending = PendingInput::default();
5062        }
5063
5064        let match_result = self.rendered_frame.dispatch_tree.dispatch_key(
5065            currently_pending.keystrokes,
5066            keystroke,
5067            &dispatch_path,
5068        );
5069
5070        if !match_result.to_replay.is_empty() {
5071            self.replay_pending_input(match_result.to_replay, cx);
5072            cx.propagate_event = true;
5073        }
5074
5075        if !match_result.pending.is_empty() {
5076            currently_pending.timer.take();
5077            currently_pending.keystrokes = match_result.pending;
5078            currently_pending.focus = self.focus;
5079
5080            let text_input_requires_timeout = event
5081                .downcast_ref::<KeyDownEvent>()
5082                .filter(|key_down| key_down.keystroke.key_char.is_some())
5083                .and_then(|_| self.platform_window.take_input_handler())
5084                .map_or(false, |mut input_handler| {
5085                    let accepts = input_handler.accepts_text_input(self, cx);
5086                    self.platform_window.set_input_handler(input_handler);
5087                    accepts
5088                });
5089
5090            currently_pending.needs_timeout |=
5091                match_result.pending_has_binding || text_input_requires_timeout;
5092
5093            if currently_pending.needs_timeout {
5094                currently_pending.timer = Some(self.spawn(cx, async move |cx| {
5095                    cx.background_executor.timer(Duration::from_secs(1)).await;
5096                    cx.update(move |window, cx| {
5097                        let Some(currently_pending) = window
5098                            .pending_input
5099                            .take()
5100                            .filter(|pending| pending.focus == window.focus)
5101                        else {
5102                            return;
5103                        };
5104
5105                        let node_id = window.focus_node_id_in_rendered_frame(window.focus);
5106                        let dispatch_path =
5107                            window.rendered_frame.dispatch_tree.dispatch_path(node_id);
5108
5109                        let to_replay = window
5110                            .rendered_frame
5111                            .dispatch_tree
5112                            .flush_dispatch(currently_pending.keystrokes, &dispatch_path);
5113
5114                        window.pending_input_changed(cx);
5115                        window.replay_pending_input(to_replay, cx)
5116                    })
5117                    .log_err();
5118                }));
5119            } else {
5120                currently_pending.timer = None;
5121            }
5122            self.pending_input = Some(currently_pending);
5123            self.pending_input_changed(cx);
5124            cx.propagate_event = false;
5125            return;
5126        }
5127
5128        let skip_bindings = event
5129            .downcast_ref::<KeyDownEvent>()
5130            .filter(|key_down_event| key_down_event.prefer_character_input)
5131            .map(|_| {
5132                self.platform_window
5133                    .take_input_handler()
5134                    .map_or(false, |mut input_handler| {
5135                        let accepts = input_handler.accepts_text_input(self, cx);
5136                        self.platform_window.set_input_handler(input_handler);
5137                        // If modifiers are not excessive (e.g. AltGr), and the input handler is accepting text input,
5138                        // we prefer the text input over bindings.
5139                        accepts
5140                    })
5141            })
5142            .unwrap_or(false);
5143
5144        if !skip_bindings {
5145            for binding in match_result.bindings {
5146                self.dispatch_action_on_node(node_id, binding.action.as_ref(), cx);
5147                if !cx.propagate_event {
5148                    self.dispatch_keystroke_observers(
5149                        event,
5150                        Some(binding.action),
5151                        match_result.context_stack,
5152                        cx,
5153                    );
5154                    self.pending_input_changed(cx);
5155                    return;
5156                }
5157            }
5158        }
5159
5160        self.finish_dispatch_key_event(event, dispatch_path, match_result.context_stack, cx);
5161        self.pending_input_changed(cx);
5162    }
5163
5164    fn finish_dispatch_key_event(
5165        &mut self,
5166        event: &dyn Any,
5167        dispatch_path: SmallVec<[DispatchNodeId; 32]>,
5168        context_stack: Vec<KeyContext>,
5169        cx: &mut App,
5170    ) {
5171        self.dispatch_key_down_up_event(event, &dispatch_path, cx);
5172        if !cx.propagate_event {
5173            return;
5174        }
5175
5176        self.dispatch_modifiers_changed_event(event, &dispatch_path, cx);
5177        if !cx.propagate_event {
5178            return;
5179        }
5180
5181        self.dispatch_keystroke_observers(event, None, context_stack, cx);
5182    }
5183
5184    pub(crate) fn pending_input_changed(&mut self, cx: &mut App) {
5185        self.pending_input_observers
5186            .clone()
5187            .retain(&(), |callback| callback(self, cx));
5188    }
5189
5190    fn dispatch_key_down_up_event(
5191        &mut self,
5192        event: &dyn Any,
5193        dispatch_path: &SmallVec<[DispatchNodeId; 32]>,
5194        cx: &mut App,
5195    ) {
5196        // Capture phase
5197        for node_id in dispatch_path {
5198            let node = self.rendered_frame.dispatch_tree.node(*node_id);
5199
5200            for key_listener in node.key_listeners.clone() {
5201                key_listener(event, DispatchPhase::Capture, self, cx);
5202                if !cx.propagate_event {
5203                    return;
5204                }
5205            }
5206        }
5207
5208        // Bubble phase
5209        for node_id in dispatch_path.iter().rev() {
5210            // Handle low level key events
5211            let node = self.rendered_frame.dispatch_tree.node(*node_id);
5212            for key_listener in node.key_listeners.clone() {
5213                key_listener(event, DispatchPhase::Bubble, self, cx);
5214                if !cx.propagate_event {
5215                    return;
5216                }
5217            }
5218        }
5219    }
5220
5221    fn dispatch_modifiers_changed_event(
5222        &mut self,
5223        event: &dyn Any,
5224        dispatch_path: &SmallVec<[DispatchNodeId; 32]>,
5225        cx: &mut App,
5226    ) {
5227        let Some(event) = event.downcast_ref::<ModifiersChangedEvent>() else {
5228            return;
5229        };
5230        for node_id in dispatch_path.iter().rev() {
5231            let node = self.rendered_frame.dispatch_tree.node(*node_id);
5232            for listener in node.modifiers_changed_listeners.clone() {
5233                listener(event, self, cx);
5234                if !cx.propagate_event {
5235                    return;
5236                }
5237            }
5238        }
5239    }
5240
5241    /// Determine whether a potential multi-stroke key binding is in progress on this window.
5242    pub fn has_pending_keystrokes(&self) -> bool {
5243        self.pending_input.is_some()
5244    }
5245
5246    pub(crate) fn clear_pending_keystrokes(&mut self) {
5247        self.pending_input.take();
5248    }
5249
5250    /// Returns the currently pending input keystrokes that might result in a multi-stroke key binding.
5251    pub fn pending_input_keystrokes(&self) -> Option<&[Keystroke]> {
5252        self.pending_input
5253            .as_ref()
5254            .map(|pending_input| pending_input.keystrokes.as_slice())
5255    }
5256
5257    fn replay_pending_input(&mut self, replays: SmallVec<[Replay; 1]>, cx: &mut App) {
5258        let node_id = self.focus_node_id_in_rendered_frame(self.focus);
5259        let dispatch_path = self.rendered_frame.dispatch_tree.dispatch_path(node_id);
5260
5261        'replay: for replay in replays {
5262            let event = KeyDownEvent {
5263                keystroke: replay.keystroke.clone(),
5264                is_held: false,
5265                prefer_character_input: true,
5266            };
5267
5268            cx.propagate_event = true;
5269            for binding in replay.bindings {
5270                self.dispatch_action_on_node(node_id, binding.action.as_ref(), cx);
5271                if !cx.propagate_event {
5272                    self.dispatch_keystroke_observers(
5273                        &event,
5274                        Some(binding.action),
5275                        Vec::default(),
5276                        cx,
5277                    );
5278                    continue 'replay;
5279                }
5280            }
5281
5282            self.dispatch_key_down_up_event(&event, &dispatch_path, cx);
5283            if !cx.propagate_event {
5284                continue 'replay;
5285            }
5286            if let Some(input) = replay.keystroke.key_char.as_ref().cloned()
5287                && let Some(mut input_handler) = self.platform_window.take_input_handler()
5288            {
5289                input_handler.dispatch_input(&input, self, cx);
5290                self.platform_window.set_input_handler(input_handler)
5291            }
5292        }
5293    }
5294
5295    fn focus_node_id_in_rendered_frame(&self, focus_id: Option<FocusId>) -> DispatchNodeId {
5296        focus_id
5297            .and_then(|focus_id| {
5298                self.rendered_frame
5299                    .dispatch_tree
5300                    .focusable_node_id(focus_id)
5301            })
5302            .unwrap_or_else(|| self.rendered_frame.dispatch_tree.root_node_id())
5303    }
5304
5305    fn dispatch_action_on_node(
5306        &mut self,
5307        node_id: DispatchNodeId,
5308        action: &dyn Action,
5309        cx: &mut App,
5310    ) {
5311        self.dispatch_action_on_node_inner(node_id, action, cx);
5312
5313        if !cx.propagate_event
5314            && cx.cursor_hide_mode == CursorHideMode::OnTypingAndAction
5315            && self.last_input_was_keyboard()
5316        {
5317            cx.platform.hide_cursor_until_mouse_moves();
5318        }
5319    }
5320
5321    fn dispatch_action_on_node_inner(
5322        &mut self,
5323        node_id: DispatchNodeId,
5324        action: &dyn Action,
5325        cx: &mut App,
5326    ) {
5327        let dispatch_path = self.rendered_frame.dispatch_tree.dispatch_path(node_id);
5328
5329        // Capture phase for global actions.
5330        cx.propagate_event = true;
5331        if let Some(mut global_listeners) = cx
5332            .global_action_listeners
5333            .remove(&action.as_any().type_id())
5334        {
5335            for listener in &global_listeners {
5336                profiler::update_running_action(action, cx);
5337                listener(action.as_any(), DispatchPhase::Capture, cx);
5338                profiler::save_action_timing();
5339                if !cx.propagate_event {
5340                    break;
5341                }
5342            }
5343
5344            global_listeners.extend(
5345                cx.global_action_listeners
5346                    .remove(&action.as_any().type_id())
5347                    .unwrap_or_default(),
5348            );
5349
5350            cx.global_action_listeners
5351                .insert(action.as_any().type_id(), global_listeners);
5352        }
5353
5354        if !cx.propagate_event {
5355            return;
5356        }
5357
5358        // Capture phase for window actions.
5359        for node_id in &dispatch_path {
5360            let node = self.rendered_frame.dispatch_tree.node(*node_id);
5361            for DispatchActionListener {
5362                action_type,
5363                listener,
5364            } in node.action_listeners.clone()
5365            {
5366                let any_action = action.as_any();
5367                if action_type == any_action.type_id() {
5368                    profiler::update_running_action(action, cx);
5369                    listener(any_action, DispatchPhase::Capture, self, cx);
5370                    profiler::save_action_timing();
5371
5372                    if !cx.propagate_event {
5373                        return;
5374                    }
5375                }
5376            }
5377        }
5378
5379        // Bubble phase for window actions.
5380        for node_id in dispatch_path.iter().rev() {
5381            let node = self.rendered_frame.dispatch_tree.node(*node_id);
5382            for DispatchActionListener {
5383                action_type,
5384                listener,
5385            } in node.action_listeners.clone()
5386            {
5387                let any_action = action.as_any();
5388                if action_type == any_action.type_id() {
5389                    cx.propagate_event = false; // Actions stop propagation by default during the bubble phase
5390                    profiler::update_running_action(action, cx);
5391                    listener(any_action, DispatchPhase::Bubble, self, cx);
5392                    profiler::save_action_timing();
5393
5394                    if !cx.propagate_event {
5395                        return;
5396                    }
5397                }
5398            }
5399        }
5400
5401        // Bubble phase for global actions.
5402        if let Some(mut global_listeners) = cx
5403            .global_action_listeners
5404            .remove(&action.as_any().type_id())
5405        {
5406            for listener in global_listeners.iter().rev() {
5407                cx.propagate_event = false; // Actions stop propagation by default during the bubble phase
5408
5409                profiler::update_running_action(action, cx);
5410                listener(action.as_any(), DispatchPhase::Bubble, cx);
5411                profiler::save_action_timing();
5412                if !cx.propagate_event {
5413                    break;
5414                }
5415            }
5416
5417            global_listeners.extend(
5418                cx.global_action_listeners
5419                    .remove(&action.as_any().type_id())
5420                    .unwrap_or_default(),
5421            );
5422
5423            cx.global_action_listeners
5424                .insert(action.as_any().type_id(), global_listeners);
5425        }
5426    }
5427
5428    /// Register the given handler to be invoked whenever the global of the given type
5429    /// is updated.
5430    pub fn observe_global<G: Global>(
5431        &mut self,
5432        cx: &mut App,
5433        f: impl Fn(&mut Window, &mut App) + 'static,
5434    ) -> Subscription {
5435        let window_handle = self.handle;
5436        let (subscription, activate) = cx.global_observers.insert(
5437            TypeId::of::<G>(),
5438            Box::new(move |cx| {
5439                window_handle
5440                    .update(cx, |_, window, cx| f(window, cx))
5441                    .is_ok()
5442            }),
5443        );
5444        cx.defer(move |_| activate());
5445        subscription
5446    }
5447
5448    /// Focus the current window and bring it to the foreground at the platform level.
5449    pub fn activate_window(&self) {
5450        self.platform_window.activate();
5451    }
5452
5453    /// Requests that the operating system draw attention to this window.
5454    pub fn request_attention(&self) {
5455        self.platform_window.request_attention();
5456    }
5457
5458    /// Minimize the current window at the platform level.
5459    pub fn minimize_window(&self) {
5460        self.platform_window.minimize();
5461    }
5462
5463    /// Toggle full screen status on the current window at the platform level.
5464    pub fn toggle_fullscreen(&self) {
5465        self.platform_window.toggle_fullscreen();
5466    }
5467
5468    /// Updates the IME panel position suggestions for languages like japanese, chinese.
5469    pub fn invalidate_character_coordinates(&self) {
5470        self.on_next_frame(|window, cx| {
5471            if let Some(mut input_handler) = window.platform_window.take_input_handler() {
5472                if let Some(bounds) = input_handler.selected_bounds(window, cx) {
5473                    window.platform_window.update_ime_position(bounds);
5474                }
5475                window.platform_window.set_input_handler(input_handler);
5476            }
5477        });
5478    }
5479
5480    /// Present a platform dialog.
5481    /// The provided message will be presented, along with buttons for each answer.
5482    /// When a button is clicked, the returned Receiver will receive the index of the clicked button.
5483    pub fn prompt<T>(
5484        &mut self,
5485        level: PromptLevel,
5486        message: &str,
5487        detail: Option<&str>,
5488        answers: &[T],
5489        cx: &mut App,
5490    ) -> oneshot::Receiver<usize>
5491    where
5492        T: Clone + Into<PromptButton>,
5493    {
5494        let prompt_builder = cx.prompt_builder.take();
5495        let Some(prompt_builder) = prompt_builder else {
5496            unreachable!("Re-entrant window prompting is not supported by GPUI");
5497        };
5498
5499        let answers = answers
5500            .iter()
5501            .map(|answer| answer.clone().into())
5502            .collect::<Vec<_>>();
5503
5504        let receiver = match &prompt_builder {
5505            PromptBuilder::Default => self
5506                .platform_window
5507                .prompt(level, message, detail, &answers)
5508                .unwrap_or_else(|| {
5509                    self.build_custom_prompt(&prompt_builder, level, message, detail, &answers, cx)
5510                }),
5511            PromptBuilder::Custom(_) => {
5512                self.build_custom_prompt(&prompt_builder, level, message, detail, &answers, cx)
5513            }
5514        };
5515
5516        cx.prompt_builder = Some(prompt_builder);
5517
5518        receiver
5519    }
5520
5521    fn build_custom_prompt(
5522        &mut self,
5523        prompt_builder: &PromptBuilder,
5524        level: PromptLevel,
5525        message: &str,
5526        detail: Option<&str>,
5527        answers: &[PromptButton],
5528        cx: &mut App,
5529    ) -> oneshot::Receiver<usize> {
5530        let (sender, receiver) = oneshot::channel();
5531        let handle = PromptHandle::new(sender);
5532        let handle = (prompt_builder)(level, message, detail, answers, handle, self, cx);
5533        self.prompt = Some(handle);
5534        receiver
5535    }
5536
5537    /// Returns whether a prompt rendered by GPUI is currently active in this window.
5538    ///
5539    /// This is only true for prompts rendered in the window (see
5540    /// [`App::set_prompt_builder`]), not for platform-native prompt dialogs.
5541    pub fn has_active_prompt(&self) -> bool {
5542        self.prompt.is_some()
5543    }
5544
5545    /// Returns the current context stack.
5546    pub fn context_stack(&self) -> Vec<KeyContext> {
5547        let node_id = self.focus_node_id_in_rendered_frame(self.focus);
5548        let dispatch_tree = &self.rendered_frame.dispatch_tree;
5549        dispatch_tree
5550            .dispatch_path(node_id)
5551            .iter()
5552            .filter_map(move |&node_id| dispatch_tree.node(node_id).context.clone())
5553            .collect()
5554    }
5555
5556    /// Returns all available actions for the focused element.
5557    pub fn available_actions(&self, cx: &App) -> Vec<Box<dyn Action>> {
5558        let node_id = self.focus_node_id_in_rendered_frame(self.focus);
5559        let mut actions = self.rendered_frame.dispatch_tree.available_actions(node_id);
5560        for action_type in cx.global_action_listeners.keys() {
5561            if let Err(ix) = actions.binary_search_by_key(action_type, |a| a.as_any().type_id()) {
5562                let action = cx.actions.build_action_type(action_type).ok();
5563                if let Some(action) = action {
5564                    actions.insert(ix, action);
5565                }
5566            }
5567        }
5568        actions
5569    }
5570
5571    /// Returns key bindings that invoke an action on the currently focused element. Bindings are
5572    /// returned in the order they were added. For display, the last binding should take precedence.
5573    pub fn bindings_for_action(&self, action: &dyn Action) -> Vec<KeyBinding> {
5574        self.rendered_frame
5575            .dispatch_tree
5576            .bindings_for_action(action, &self.rendered_frame.dispatch_tree.context_stack)
5577    }
5578
5579    /// Returns the highest precedence key binding that invokes an action on the currently focused
5580    /// element. This is more efficient than getting the last result of `bindings_for_action`.
5581    pub fn highest_precedence_binding_for_action(&self, action: &dyn Action) -> Option<KeyBinding> {
5582        self.rendered_frame
5583            .dispatch_tree
5584            .highest_precedence_binding_for_action(
5585                action,
5586                &self.rendered_frame.dispatch_tree.context_stack,
5587            )
5588    }
5589
5590    /// Returns the key bindings for an action in a context.
5591    pub fn bindings_for_action_in_context(
5592        &self,
5593        action: &dyn Action,
5594        context: KeyContext,
5595    ) -> Vec<KeyBinding> {
5596        let dispatch_tree = &self.rendered_frame.dispatch_tree;
5597        dispatch_tree.bindings_for_action(action, &[context])
5598    }
5599
5600    /// Returns the highest precedence key binding for an action in a context. This is more
5601    /// efficient than getting the last result of `bindings_for_action_in_context`.
5602    pub fn highest_precedence_binding_for_action_in_context(
5603        &self,
5604        action: &dyn Action,
5605        context: KeyContext,
5606    ) -> Option<KeyBinding> {
5607        let dispatch_tree = &self.rendered_frame.dispatch_tree;
5608        dispatch_tree.highest_precedence_binding_for_action(action, &[context])
5609    }
5610
5611    /// Returns any bindings that would invoke an action on the given focus handle if it were
5612    /// focused. Bindings are returned in the order they were added. For display, the last binding
5613    /// should take precedence.
5614    pub fn bindings_for_action_in(
5615        &self,
5616        action: &dyn Action,
5617        focus_handle: &FocusHandle,
5618    ) -> Vec<KeyBinding> {
5619        let dispatch_tree = &self.rendered_frame.dispatch_tree;
5620        let Some(context_stack) = self.context_stack_for_focus_handle(focus_handle) else {
5621            return vec![];
5622        };
5623        dispatch_tree.bindings_for_action(action, &context_stack)
5624    }
5625
5626    /// Returns the highest precedence key binding that would invoke an action on the given focus
5627    /// handle if it were focused. This is more efficient than getting the last result of
5628    /// `bindings_for_action_in`.
5629    pub fn highest_precedence_binding_for_action_in(
5630        &self,
5631        action: &dyn Action,
5632        focus_handle: &FocusHandle,
5633    ) -> Option<KeyBinding> {
5634        let dispatch_tree = &self.rendered_frame.dispatch_tree;
5635        let context_stack = self.context_stack_for_focus_handle(focus_handle)?;
5636        dispatch_tree.highest_precedence_binding_for_action(action, &context_stack)
5637    }
5638
5639    /// Find the bindings that can follow the current input sequence for the current context stack.
5640    pub fn possible_bindings_for_input(&self, input: &[Keystroke]) -> Vec<KeyBinding> {
5641        self.rendered_frame
5642            .dispatch_tree
5643            .possible_next_bindings_for_input(input, &self.context_stack())
5644    }
5645
5646    fn context_stack_for_focus_handle(
5647        &self,
5648        focus_handle: &FocusHandle,
5649    ) -> Option<Vec<KeyContext>> {
5650        let dispatch_tree = &self.rendered_frame.dispatch_tree;
5651        let node_id = dispatch_tree.focusable_node_id(focus_handle.id)?;
5652        let context_stack: Vec<_> = dispatch_tree
5653            .dispatch_path(node_id)
5654            .into_iter()
5655            .filter_map(|node_id| dispatch_tree.node(node_id).context.clone())
5656            .collect();
5657        Some(context_stack)
5658    }
5659
5660    /// Returns a generic event listener that invokes the given listener with the view and context associated with the given view handle.
5661    pub fn listener_for<T: 'static, E>(
5662        &self,
5663        view: &Entity<T>,
5664        f: impl Fn(&mut T, &E, &mut Window, &mut Context<T>) + 'static,
5665    ) -> impl Fn(&E, &mut Window, &mut App) + 'static {
5666        let view = view.downgrade();
5667        move |e: &E, window: &mut Window, cx: &mut App| {
5668            view.update(cx, |view, cx| f(view, e, window, cx)).ok();
5669        }
5670    }
5671
5672    /// Returns a generic handler that invokes the given handler with the view and context associated with the given view handle.
5673    pub fn handler_for<E: 'static, Callback: Fn(&mut E, &mut Window, &mut Context<E>) + 'static>(
5674        &self,
5675        entity: &Entity<E>,
5676        f: Callback,
5677    ) -> impl Fn(&mut Window, &mut App) + 'static {
5678        let entity = entity.downgrade();
5679        move |window: &mut Window, cx: &mut App| {
5680            entity.update(cx, |entity, cx| f(entity, window, cx)).ok();
5681        }
5682    }
5683
5684    /// Register a callback that can interrupt the closing of the current window based the returned boolean.
5685    /// If the callback returns false, the window won't be closed.
5686    pub fn on_window_should_close(
5687        &self,
5688        cx: &App,
5689        f: impl Fn(&mut Window, &mut App) -> bool + 'static,
5690    ) {
5691        let mut cx = self.to_async(cx);
5692        self.platform_window.on_should_close(Box::new(move || {
5693            cx.update(|window, cx| f(window, cx)).unwrap_or(true)
5694        }))
5695    }
5696
5697    /// Register an action listener on this node for the next frame. The type of action
5698    /// is determined by the first parameter of the given listener. When the next frame is rendered
5699    /// the listener will be cleared.
5700    ///
5701    /// This is a fairly low-level method, so prefer using action handlers on elements unless you have
5702    /// a specific need to register a listener yourself.
5703    ///
5704    /// This method should only be called as part of the paint phase of element drawing.
5705    pub fn on_action(
5706        &mut self,
5707        action_type: TypeId,
5708        listener: impl Fn(&dyn Any, DispatchPhase, &mut Window, &mut App) + 'static,
5709    ) {
5710        self.invalidator.debug_assert_paint();
5711
5712        self.next_frame
5713            .dispatch_tree
5714            .on_action(action_type, Rc::new(listener));
5715    }
5716
5717    /// Register a capturing action listener on this node for the next frame if the condition is true.
5718    /// The type of action is determined by the first parameter of the given listener. When the next
5719    /// frame is rendered the listener will be cleared.
5720    ///
5721    /// This is a fairly low-level method, so prefer using action handlers on elements unless you have
5722    /// a specific need to register a listener yourself.
5723    ///
5724    /// This method should only be called as part of the paint phase of element drawing.
5725    pub fn on_action_when(
5726        &mut self,
5727        condition: bool,
5728        action_type: TypeId,
5729        listener: impl Fn(&dyn Any, DispatchPhase, &mut Window, &mut App) + 'static,
5730    ) {
5731        self.invalidator.debug_assert_paint();
5732
5733        if condition {
5734            self.next_frame
5735                .dispatch_tree
5736                .on_action(action_type, Rc::new(listener));
5737        }
5738    }
5739
5740    /// Read information about the GPU backing this window.
5741    /// Currently returns None on Mac and Windows.
5742    pub fn gpu_specs(&self) -> Option<GpuSpecs> {
5743        self.platform_window.gpu_specs()
5744    }
5745
5746    /// Perform titlebar double-click action.
5747    /// This is macOS specific.
5748    pub fn titlebar_double_click(&self) {
5749        self.platform_window.titlebar_double_click();
5750    }
5751
5752    /// Gets the window's title at the platform level.
5753    /// This is macOS specific.
5754    pub fn window_title(&self) -> String {
5755        self.platform_window.get_title()
5756    }
5757
5758    /// Returns a list of all tabbed windows and their titles.
5759    /// This is macOS specific.
5760    pub fn tabbed_windows(&self) -> Option<Vec<SystemWindowTab>> {
5761        self.platform_window.tabbed_windows()
5762    }
5763
5764    /// Returns the tab bar visibility.
5765    /// This is macOS specific.
5766    pub fn tab_bar_visible(&self) -> bool {
5767        self.platform_window.tab_bar_visible()
5768    }
5769
5770    /// Merges all open windows into a single tabbed window.
5771    /// This is macOS specific.
5772    pub fn merge_all_windows(&self) {
5773        self.platform_window.merge_all_windows()
5774    }
5775
5776    /// Moves the tab to a new containing window.
5777    /// This is macOS specific.
5778    pub fn move_tab_to_new_window(&self) {
5779        self.platform_window.move_tab_to_new_window()
5780    }
5781
5782    /// Shows or hides the window tab overview.
5783    /// This is macOS specific.
5784    pub fn toggle_window_tab_overview(&self) {
5785        self.platform_window.toggle_window_tab_overview()
5786    }
5787
5788    /// Sets the tabbing identifier for the window.
5789    /// This is macOS specific.
5790    pub fn set_tabbing_identifier(&self, tabbing_identifier: Option<String>) {
5791        self.platform_window
5792            .set_tabbing_identifier(tabbing_identifier)
5793    }
5794
5795    /// Request the OS to play an alert sound. On some platforms this is associated
5796    /// with the window, for others it's just a simple global function call.
5797    pub fn play_system_bell(&self) {
5798        self.platform_window.play_system_bell()
5799    }
5800
5801    /// Returns whether accessibility features are active for this frame,
5802    /// i.e. whether assistive technology (such as a screen reader) is
5803    /// connected and an accessibility tree is being built.
5804    ///
5805    /// Use this to skip computing data during rendering that is only
5806    /// observable through the accessibility tree. When accessibility is
5807    /// activated, a redraw is forced, so gated work is recomputed before the
5808    /// next tree update is sent to the platform.
5809    ///
5810    /// See the [accessibility guide](crate::_accessibility) for an overview.
5811    pub fn is_a11y_active(&self) -> bool {
5812        self.a11y.is_active()
5813    }
5814
5815    /// Debug representation of the last frame's accessibility information.
5816    pub fn debug_a11y_tree_json(&self) -> Option<String> {
5817        self.a11y.debug_tree_json()
5818    }
5819
5820    /// Register a listener for an accessibility action on a specific node.
5821    /// The listener will be called when a screen reader requests the given
5822    /// action on the node identified by `node_id`.
5823    ///
5824    /// See the [accessibility guide](crate::_accessibility) for an overview.
5825    pub fn on_a11y_action(
5826        &mut self,
5827        node_id: accesskit::NodeId,
5828        action: accesskit::Action,
5829        listener: impl FnMut(Option<&accesskit::ActionData>, &mut Window, &mut App) + 'static,
5830    ) {
5831        self.a11y
5832            .action_listeners
5833            .entry(node_id)
5834            .or_default()
5835            .push((action, Box::new(listener)));
5836    }
5837
5838    #[cfg(not(target_family = "wasm"))]
5839    pub(crate) fn handle_a11y_action(&mut self, request: accesskit::ActionRequest, cx: &mut App) {
5840        // Take listeners out temporarily so the closures can borrow Window
5841        // mutably, then restore them afterward.
5842        if let Some(mut listeners) = self.a11y.action_listeners.remove(&request.target_node) {
5843            let extra_data = request.data.as_ref();
5844            let mut matched = false;
5845            for (action, listener) in &mut listeners {
5846                if *action == request.action {
5847                    listener(extra_data, self, cx);
5848                    matched = true;
5849                }
5850            }
5851            self.a11y
5852                .action_listeners
5853                .insert(request.target_node, listeners);
5854            if matched {
5855                return;
5856            }
5857        }
5858
5859        // Fall back to built-in action handling.
5860        match request.action {
5861            accesskit::Action::Click => {
5862                if let Some(bounds) = self.a11y.node_bounds.get(&request.target_node).copied() {
5863                    let center = bounds.center();
5864                    let mouse_down = PlatformInput::MouseDown(crate::MouseDownEvent {
5865                        button: MouseButton::Left,
5866                        position: center,
5867                        modifiers: Modifiers::default(),
5868                        click_count: 1,
5869                        first_mouse: false,
5870                    });
5871                    let mouse_up = PlatformInput::MouseUp(MouseUpEvent {
5872                        button: MouseButton::Left,
5873                        position: center,
5874                        modifiers: Modifiers::default(),
5875                        click_count: 1,
5876                    });
5877                    self.dispatch_event(mouse_down, cx);
5878                    self.dispatch_event(mouse_up, cx);
5879                }
5880            }
5881            accesskit::Action::Focus => {
5882                if let Some(focus_id) = self.a11y.focus_ids.get(&request.target_node).copied()
5883                    && let Some(handle) = FocusHandle::for_id(focus_id, &cx.focus_handles)
5884                {
5885                    self.focus(&handle, cx);
5886                }
5887            }
5888            accesskit::Action::Blur => {
5889                self.blur();
5890            }
5891            _ => {
5892                log::debug!(
5893                    "Unhandled a11y action: {:?} on {:?}",
5894                    request.action,
5895                    request.target_node
5896                );
5897            }
5898        }
5899    }
5900
5901    /// Toggles the inspector mode on this window.
5902    #[cfg(any(feature = "inspector", debug_assertions))]
5903    pub fn toggle_inspector(&mut self, cx: &mut App) {
5904        self.inspector = match self.inspector {
5905            None => Some(cx.new(|_| Inspector::new())),
5906            Some(_) => None,
5907        };
5908        self.refresh();
5909    }
5910
5911    /// Returns true if the window is in inspector mode.
5912    pub fn is_inspector_picking(&self, _cx: &App) -> bool {
5913        #[cfg(any(feature = "inspector", debug_assertions))]
5914        {
5915            if let Some(inspector) = &self.inspector {
5916                return inspector.read(_cx).is_picking();
5917            }
5918        }
5919        false
5920    }
5921
5922    /// Executes the provided function with mutable access to an inspector state.
5923    #[cfg(any(feature = "inspector", debug_assertions))]
5924    pub fn with_inspector_state<T: 'static, R>(
5925        &mut self,
5926        _inspector_id: Option<&crate::InspectorElementId>,
5927        cx: &mut App,
5928        f: impl FnOnce(&mut Option<T>, &mut Self) -> R,
5929    ) -> R {
5930        if let Some(inspector_id) = _inspector_id
5931            && let Some(inspector) = &self.inspector
5932        {
5933            let inspector = inspector.clone();
5934            let active_element_id = inspector.read(cx).active_element_id();
5935            if Some(inspector_id) == active_element_id {
5936                return inspector.update(cx, |inspector, _cx| {
5937                    inspector.with_active_element_state(self, f)
5938                });
5939            }
5940        }
5941        f(&mut None, self)
5942    }
5943
5944    #[cfg(any(feature = "inspector", debug_assertions))]
5945    pub(crate) fn build_inspector_element_id(
5946        &mut self,
5947        path: crate::InspectorElementPath,
5948    ) -> crate::InspectorElementId {
5949        self.invalidator.debug_assert_paint_or_prepaint();
5950        let path = Rc::new(path);
5951        let next_instance_id = self
5952            .next_frame
5953            .next_inspector_instance_ids
5954            .entry(path.clone())
5955            .or_insert(0);
5956        let instance_id = *next_instance_id;
5957        *next_instance_id += 1;
5958        crate::InspectorElementId { path, instance_id }
5959    }
5960
5961    #[cfg(any(feature = "inspector", debug_assertions))]
5962    fn prepaint_inspector(&mut self, inspector_width: Pixels, cx: &mut App) -> Option<AnyElement> {
5963        if let Some(inspector) = self.inspector.take() {
5964            let mut inspector_element = AnyView::from(inspector.clone()).into_any_element();
5965            inspector_element.prepaint_as_root(
5966                point(self.viewport_size.width - inspector_width, px(0.0)),
5967                size(inspector_width, self.viewport_size.height).into(),
5968                self,
5969                cx,
5970            );
5971            self.inspector = Some(inspector);
5972            Some(inspector_element)
5973        } else {
5974            None
5975        }
5976    }
5977
5978    #[cfg(any(feature = "inspector", debug_assertions))]
5979    fn paint_inspector(&mut self, mut inspector_element: Option<AnyElement>, cx: &mut App) {
5980        if let Some(mut inspector_element) = inspector_element {
5981            inspector_element.paint(self, cx);
5982        };
5983    }
5984
5985    /// Registers a hitbox that can be used for inspector picking mode, allowing users to select and
5986    /// inspect UI elements by clicking on them.
5987    #[cfg(any(feature = "inspector", debug_assertions))]
5988    pub fn insert_inspector_hitbox(
5989        &mut self,
5990        hitbox_id: HitboxId,
5991        inspector_id: Option<&crate::InspectorElementId>,
5992        cx: &App,
5993    ) {
5994        self.invalidator.debug_assert_paint_or_prepaint();
5995        if !self.is_inspector_picking(cx) {
5996            return;
5997        }
5998        if let Some(inspector_id) = inspector_id {
5999            self.next_frame
6000                .inspector_hitboxes
6001                .insert(hitbox_id, inspector_id.clone());
6002        }
6003    }
6004
6005    #[cfg(any(feature = "inspector", debug_assertions))]
6006    fn paint_inspector_hitbox(&mut self, cx: &App) {
6007        if let Some(inspector) = self.inspector.as_ref() {
6008            let inspector = inspector.read(cx);
6009            if let Some((hitbox_id, _)) = self.hovered_inspector_hitbox(inspector, &self.next_frame)
6010                && let Some(hitbox) = self
6011                    .next_frame
6012                    .hitboxes
6013                    .iter()
6014                    .find(|hitbox| hitbox.id == hitbox_id)
6015            {
6016                self.paint_quad(crate::fill(hitbox.bounds, crate::rgba(0x61afef4d)));
6017            }
6018        }
6019    }
6020
6021    #[cfg(any(feature = "inspector", debug_assertions))]
6022    fn handle_inspector_mouse_event(&mut self, event: &dyn Any, cx: &mut App) {
6023        let Some(inspector) = self.inspector.clone() else {
6024            return;
6025        };
6026        if event.downcast_ref::<MouseMoveEvent>().is_some() {
6027            inspector.update(cx, |inspector, _cx| {
6028                if let Some((_, inspector_id)) =
6029                    self.hovered_inspector_hitbox(inspector, &self.rendered_frame)
6030                {
6031                    inspector.hover(inspector_id, self);
6032                }
6033            });
6034        } else if event.downcast_ref::<crate::MouseDownEvent>().is_some() {
6035            inspector.update(cx, |inspector, _cx| {
6036                if let Some((_, inspector_id)) =
6037                    self.hovered_inspector_hitbox(inspector, &self.rendered_frame)
6038                {
6039                    inspector.select(inspector_id, self);
6040                }
6041            });
6042        } else if let Some(event) = event.downcast_ref::<crate::ScrollWheelEvent>() {
6043            // This should be kept in sync with SCROLL_LINES in x11 platform.
6044            const SCROLL_LINES: f32 = 3.0;
6045            const SCROLL_PIXELS_PER_LAYER: f32 = 36.0;
6046            let delta_y = event
6047                .delta
6048                .pixel_delta(px(SCROLL_PIXELS_PER_LAYER / SCROLL_LINES))
6049                .y;
6050            if let Some(inspector) = self.inspector.clone() {
6051                inspector.update(cx, |inspector, _cx| {
6052                    if let Some(depth) = inspector.pick_depth.as_mut() {
6053                        *depth += f32::from(delta_y) / SCROLL_PIXELS_PER_LAYER;
6054                        let max_depth = self.mouse_hit_test.ids.len() as f32 - 0.5;
6055                        if *depth < 0.0 {
6056                            *depth = 0.0;
6057                        } else if *depth > max_depth {
6058                            *depth = max_depth;
6059                        }
6060                        if let Some((_, inspector_id)) =
6061                            self.hovered_inspector_hitbox(inspector, &self.rendered_frame)
6062                        {
6063                            inspector.set_active_element_id(inspector_id, self);
6064                        }
6065                    }
6066                });
6067            }
6068        }
6069    }
6070
6071    #[cfg(any(feature = "inspector", debug_assertions))]
6072    fn hovered_inspector_hitbox(
6073        &self,
6074        inspector: &Inspector,
6075        frame: &Frame,
6076    ) -> Option<(HitboxId, crate::InspectorElementId)> {
6077        if let Some(pick_depth) = inspector.pick_depth {
6078            let depth = (pick_depth as i64).try_into().unwrap_or(0);
6079            let max_skipped = self.mouse_hit_test.ids.len().saturating_sub(1);
6080            let skip_count = (depth as usize).min(max_skipped);
6081            for hitbox_id in self.mouse_hit_test.ids.iter().skip(skip_count) {
6082                if let Some(inspector_id) = frame.inspector_hitboxes.get(hitbox_id) {
6083                    return Some((*hitbox_id, inspector_id.clone()));
6084                }
6085            }
6086        }
6087        None
6088    }
6089
6090    /// For testing: set the current modifier keys state.
6091    /// This does not generate any events.
6092    #[cfg(any(test, feature = "test-support"))]
6093    pub fn set_modifiers(&mut self, modifiers: Modifiers) {
6094        self.modifiers = modifiers;
6095    }
6096
6097    /// For testing: simulate a mouse move event to the given position.
6098    /// This dispatches the event through the normal event handling path,
6099    /// which will trigger hover states and tooltips.
6100    #[cfg(any(test, feature = "test-support"))]
6101    pub fn simulate_mouse_move(&mut self, position: Point<Pixels>, cx: &mut App) {
6102        let event = PlatformInput::MouseMove(MouseMoveEvent {
6103            position,
6104            modifiers: self.modifiers,
6105            pressed_button: None,
6106        });
6107        let _ = self.dispatch_event(event, cx);
6108    }
6109}
6110
6111// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
6112slotmap::new_key_type! {
6113    /// A unique identifier for a window.
6114    pub struct WindowId;
6115}
6116
6117impl WindowId {
6118    /// Converts this window ID to a `u64`.
6119    pub fn as_u64(&self) -> u64 {
6120        self.0.as_ffi()
6121    }
6122}
6123
6124impl From<u64> for WindowId {
6125    fn from(value: u64) -> Self {
6126        WindowId(slotmap::KeyData::from_ffi(value))
6127    }
6128}
6129
6130/// A handle to a window with a specific root view type.
6131/// Note that this does not keep the window alive on its own.
6132#[derive(Deref, DerefMut)]
6133pub struct WindowHandle<V> {
6134    #[deref]
6135    #[deref_mut]
6136    pub(crate) any_handle: AnyWindowHandle,
6137    state_type: PhantomData<fn(V) -> V>,
6138}
6139
6140impl<V> Debug for WindowHandle<V> {
6141    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6142        f.debug_struct("WindowHandle")
6143            .field("any_handle", &self.any_handle.id.as_u64())
6144            .finish()
6145    }
6146}
6147
6148impl<V: 'static + Render> WindowHandle<V> {
6149    /// Creates a new handle from a window ID.
6150    /// This does not check if the root type of the window is `V`.
6151    pub fn new(id: WindowId) -> Self {
6152        WindowHandle {
6153            any_handle: AnyWindowHandle {
6154                id,
6155                state_type: TypeId::of::<V>(),
6156            },
6157            state_type: PhantomData,
6158        }
6159    }
6160
6161    /// Get the root view out of this window.
6162    ///
6163    /// This will fail if the window is closed or if the root view's type does not match `V`.
6164    #[cfg(any(test, feature = "test-support"))]
6165    pub fn root<C>(&self, cx: &mut C) -> Result<Entity<V>>
6166    where
6167        C: AppContext,
6168    {
6169        cx.update_window(self.any_handle, |root_view, _, _| {
6170            root_view
6171                .downcast::<V>()
6172                .map_err(|_| anyhow!("the type of the window's root view has changed"))
6173        })?
6174    }
6175
6176    /// Updates the root view of this window.
6177    ///
6178    /// This will fail if the window has been closed or if the root view's type does not match
6179    pub fn update<C, R>(
6180        &self,
6181        cx: &mut C,
6182        update: impl FnOnce(&mut V, &mut Window, &mut Context<V>) -> R,
6183    ) -> Result<R>
6184    where
6185        C: AppContext,
6186    {
6187        cx.update_window(self.any_handle, |root_view, window, cx| {
6188            let view = root_view
6189                .downcast::<V>()
6190                .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
6191
6192            Ok(view.update(cx, |view, cx| update(view, window, cx)))
6193        })?
6194    }
6195
6196    /// Read the root view out of this window.
6197    ///
6198    /// This will fail if the window is closed or if the root view's type does not match `V`.
6199    pub fn read<'a>(&self, cx: &'a App) -> Result<&'a V> {
6200        let x = cx
6201            .windows
6202            .get(self.id)
6203            .and_then(|window| {
6204                window
6205                    .as_deref()
6206                    .and_then(|window| window.root.clone())
6207                    .map(|root_view| root_view.downcast::<V>())
6208            })
6209            .context("window not found")?
6210            .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
6211
6212        Ok(x.read(cx))
6213    }
6214
6215    /// Read the root view out of this window, with a callback
6216    ///
6217    /// This will fail if the window is closed or if the root view's type does not match `V`.
6218    pub fn read_with<C, R>(&self, cx: &C, read_with: impl FnOnce(&V, &App) -> R) -> Result<R>
6219    where
6220        C: AppContext,
6221    {
6222        cx.read_window(self, |root_view, cx| read_with(root_view.read(cx), cx))
6223    }
6224
6225    /// Read the root view pointer off of this window.
6226    ///
6227    /// This will fail if the window is closed or if the root view's type does not match `V`.
6228    pub fn entity<C>(&self, cx: &C) -> Result<Entity<V>>
6229    where
6230        C: AppContext,
6231    {
6232        cx.read_window(self, |root_view, _cx| root_view)
6233    }
6234
6235    /// Check if this window is 'active'.
6236    ///
6237    /// Will return `None` if the window is closed or currently
6238    /// borrowed.
6239    pub fn is_active(&self, cx: &mut App) -> Option<bool> {
6240        cx.update_window(self.any_handle, |_, window, _| window.is_window_active())
6241            .ok()
6242    }
6243}
6244
6245impl<V> Copy for WindowHandle<V> {}
6246
6247impl<V> Clone for WindowHandle<V> {
6248    fn clone(&self) -> Self {
6249        *self
6250    }
6251}
6252
6253impl<V> PartialEq for WindowHandle<V> {
6254    fn eq(&self, other: &Self) -> bool {
6255        self.any_handle == other.any_handle
6256    }
6257}
6258
6259impl<V> Eq for WindowHandle<V> {}
6260
6261impl<V> Hash for WindowHandle<V> {
6262    fn hash<H: Hasher>(&self, state: &mut H) {
6263        self.any_handle.hash(state);
6264    }
6265}
6266
6267impl<V: 'static> From<WindowHandle<V>> for AnyWindowHandle {
6268    fn from(val: WindowHandle<V>) -> Self {
6269        val.any_handle
6270    }
6271}
6272
6273/// A handle to a window with any root view type, which can be downcast to a window with a specific root view type.
6274#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
6275pub struct AnyWindowHandle {
6276    pub(crate) id: WindowId,
6277    state_type: TypeId,
6278}
6279
6280impl AnyWindowHandle {
6281    /// Get the ID of this window.
6282    pub fn window_id(&self) -> WindowId {
6283        self.id
6284    }
6285
6286    /// Attempt to convert this handle to a window handle with a specific root view type.
6287    /// If the types do not match, this will return `None`.
6288    pub fn downcast<T: 'static>(&self) -> Option<WindowHandle<T>> {
6289        if TypeId::of::<T>() == self.state_type {
6290            Some(WindowHandle {
6291                any_handle: *self,
6292                state_type: PhantomData,
6293            })
6294        } else {
6295            None
6296        }
6297    }
6298
6299    /// Updates the state of the root view of this window.
6300    ///
6301    /// This will fail if the window has been closed.
6302    pub fn update<C, R>(
6303        self,
6304        cx: &mut C,
6305        update: impl FnOnce(AnyView, &mut Window, &mut App) -> R,
6306    ) -> Result<R>
6307    where
6308        C: AppContext,
6309    {
6310        cx.update_window(self, update)
6311    }
6312
6313    /// Read the state of the root view of this window.
6314    ///
6315    /// This will fail if the window has been closed.
6316    pub fn read<T, C, R>(self, cx: &C, read: impl FnOnce(Entity<T>, &App) -> R) -> Result<R>
6317    where
6318        C: AppContext,
6319        T: 'static,
6320    {
6321        let view = self
6322            .downcast::<T>()
6323            .context("the type of the window's root view has changed")?;
6324
6325        cx.read_window(&view, read)
6326    }
6327}
6328
6329impl HasWindowHandle for Window {
6330    fn window_handle(&self) -> Result<raw_window_handle::WindowHandle<'_>, HandleError> {
6331        self.platform_window.window_handle()
6332    }
6333}
6334
6335impl HasDisplayHandle for Window {
6336    fn display_handle(
6337        &self,
6338    ) -> std::result::Result<raw_window_handle::DisplayHandle<'_>, HandleError> {
6339        self.platform_window.display_handle()
6340    }
6341}
6342
6343/// An identifier for an [`Element`].
6344///
6345/// Can be constructed with a string, a number, or both, as well
6346/// as other internal representations.
6347#[derive(Clone, Debug, Eq, PartialEq, Hash)]
6348pub enum ElementId {
6349    /// The ID of a View element
6350    View(EntityId),
6351    /// An integer ID.
6352    Integer(u64),
6353    /// A string based ID.
6354    Name(SharedString),
6355    /// A UUID.
6356    Uuid(Uuid),
6357    /// An ID that's equated with a focus handle.
6358    FocusHandle(FocusId),
6359    /// A combination of a name and an integer.
6360    NamedInteger(SharedString, u64),
6361    /// A path.
6362    Path(Arc<std::path::Path>),
6363    /// A code location.
6364    CodeLocation(core::panic::Location<'static>),
6365    /// A labeled child of an element.
6366    NamedChild(Arc<ElementId>, SharedString),
6367    /// A byte array ID (used for text-anchors)
6368    OpaqueId([u8; 20]),
6369}
6370
6371impl ElementId {
6372    /// Constructs an `ElementId::NamedInteger` from a name and `usize`.
6373    pub fn named_usize(name: impl Into<SharedString>, integer: usize) -> ElementId {
6374        Self::NamedInteger(name.into(), integer as u64)
6375    }
6376}
6377
6378impl Display for ElementId {
6379    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6380        match self {
6381            ElementId::View(entity_id) => write!(f, "view-{}", entity_id)?,
6382            ElementId::Integer(ix) => write!(f, "{}", ix)?,
6383            ElementId::Name(name) => write!(f, "{}", name)?,
6384            ElementId::FocusHandle(_) => write!(f, "FocusHandle")?,
6385            ElementId::NamedInteger(s, i) => write!(f, "{}-{}", s, i)?,
6386            ElementId::Uuid(uuid) => write!(f, "{}", uuid)?,
6387            ElementId::Path(path) => write!(f, "{}", path.display())?,
6388            ElementId::CodeLocation(location) => write!(f, "{}", location)?,
6389            ElementId::NamedChild(id, name) => write!(f, "{}-{}", id, name)?,
6390            ElementId::OpaqueId(opaque_id) => write!(f, "{:x?}", opaque_id)?,
6391        }
6392
6393        Ok(())
6394    }
6395}
6396
6397impl TryInto<SharedString> for ElementId {
6398    type Error = anyhow::Error;
6399
6400    fn try_into(self) -> anyhow::Result<SharedString> {
6401        if let ElementId::Name(name) = self {
6402            Ok(name)
6403        } else {
6404            anyhow::bail!("element id is not string")
6405        }
6406    }
6407}
6408
6409impl From<usize> for ElementId {
6410    fn from(id: usize) -> Self {
6411        ElementId::Integer(id as u64)
6412    }
6413}
6414
6415impl From<i32> for ElementId {
6416    fn from(id: i32) -> Self {
6417        Self::Integer(id as u64)
6418    }
6419}
6420
6421impl From<SharedString> for ElementId {
6422    fn from(name: SharedString) -> Self {
6423        ElementId::Name(name)
6424    }
6425}
6426
6427impl From<String> for ElementId {
6428    fn from(name: String) -> Self {
6429        ElementId::Name(name.into())
6430    }
6431}
6432
6433impl From<Arc<str>> for ElementId {
6434    fn from(name: Arc<str>) -> Self {
6435        ElementId::Name(name.into())
6436    }
6437}
6438
6439impl From<Arc<std::path::Path>> for ElementId {
6440    fn from(path: Arc<std::path::Path>) -> Self {
6441        ElementId::Path(path)
6442    }
6443}
6444
6445impl From<&'static str> for ElementId {
6446    fn from(name: &'static str) -> Self {
6447        ElementId::Name(SharedString::new_static(name))
6448    }
6449}
6450
6451impl<'a> From<&'a FocusHandle> for ElementId {
6452    fn from(handle: &'a FocusHandle) -> Self {
6453        ElementId::FocusHandle(handle.id)
6454    }
6455}
6456
6457impl From<(&'static str, EntityId)> for ElementId {
6458    fn from((name, id): (&'static str, EntityId)) -> Self {
6459        ElementId::NamedInteger(SharedString::new_static(name), id.as_u64())
6460    }
6461}
6462
6463impl From<(&'static str, usize)> for ElementId {
6464    fn from((name, id): (&'static str, usize)) -> Self {
6465        ElementId::NamedInteger(SharedString::new_static(name), id as u64)
6466    }
6467}
6468
6469impl From<(SharedString, usize)> for ElementId {
6470    fn from((name, id): (SharedString, usize)) -> Self {
6471        ElementId::NamedInteger(name, id as u64)
6472    }
6473}
6474
6475impl From<(&'static str, u64)> for ElementId {
6476    fn from((name, id): (&'static str, u64)) -> Self {
6477        ElementId::NamedInteger(SharedString::new_static(name), id)
6478    }
6479}
6480
6481impl From<Uuid> for ElementId {
6482    fn from(value: Uuid) -> Self {
6483        Self::Uuid(value)
6484    }
6485}
6486
6487impl From<(&'static str, u32)> for ElementId {
6488    fn from((name, id): (&'static str, u32)) -> Self {
6489        ElementId::NamedInteger(SharedString::new_static(name), u64::from(id))
6490    }
6491}
6492
6493impl<T: Into<SharedString>> From<(ElementId, T)> for ElementId {
6494    fn from((id, name): (ElementId, T)) -> Self {
6495        ElementId::NamedChild(Arc::new(id), name.into())
6496    }
6497}
6498
6499impl From<&'static core::panic::Location<'static>> for ElementId {
6500    fn from(location: &'static core::panic::Location<'static>) -> Self {
6501        ElementId::CodeLocation(*location)
6502    }
6503}
6504
6505impl From<[u8; 20]> for ElementId {
6506    fn from(opaque_id: [u8; 20]) -> Self {
6507        ElementId::OpaqueId(opaque_id)
6508    }
6509}
6510
6511/// A rectangle to be rendered in the window at the given position and size.
6512/// Passed as an argument [`Window::paint_quad`].
6513#[derive(Clone)]
6514pub struct PaintQuad {
6515    /// The bounds of the quad within the window.
6516    pub bounds: Bounds<Pixels>,
6517    /// The radii of the quad's corners.
6518    pub corner_radii: Corners<Pixels>,
6519    /// The background color of the quad.
6520    pub background: Background,
6521    /// The widths of the quad's borders.
6522    pub border_widths: Edges<Pixels>,
6523    /// The color of the quad's borders.
6524    pub border_color: Hsla,
6525    /// The style of the quad's borders.
6526    pub border_style: BorderStyle,
6527}
6528
6529impl PaintQuad {
6530    /// Sets the corner radii of the quad.
6531    pub fn corner_radii(self, corner_radii: impl Into<Corners<Pixels>>) -> Self {
6532        PaintQuad {
6533            corner_radii: corner_radii.into(),
6534            ..self
6535        }
6536    }
6537
6538    /// Sets the border widths of the quad.
6539    pub fn border_widths(self, border_widths: impl Into<Edges<Pixels>>) -> Self {
6540        PaintQuad {
6541            border_widths: border_widths.into(),
6542            ..self
6543        }
6544    }
6545
6546    /// Sets the border color of the quad.
6547    pub fn border_color(self, border_color: impl Into<Hsla>) -> Self {
6548        PaintQuad {
6549            border_color: border_color.into(),
6550            ..self
6551        }
6552    }
6553
6554    /// Sets the background color of the quad.
6555    pub fn background(self, background: impl Into<Background>) -> Self {
6556        PaintQuad {
6557            background: background.into(),
6558            ..self
6559        }
6560    }
6561}
6562
6563/// Creates a quad with the given parameters.
6564pub fn quad(
6565    bounds: Bounds<Pixels>,
6566    corner_radii: impl Into<Corners<Pixels>>,
6567    background: impl Into<Background>,
6568    border_widths: impl Into<Edges<Pixels>>,
6569    border_color: impl Into<Hsla>,
6570    border_style: BorderStyle,
6571) -> PaintQuad {
6572    PaintQuad {
6573        bounds,
6574        corner_radii: corner_radii.into(),
6575        background: background.into(),
6576        border_widths: border_widths.into(),
6577        border_color: border_color.into(),
6578        border_style,
6579    }
6580}
6581
6582/// Creates a filled quad with the given bounds and background color.
6583pub fn fill(bounds: impl Into<Bounds<Pixels>>, background: impl Into<Background>) -> PaintQuad {
6584    PaintQuad {
6585        bounds: bounds.into(),
6586        corner_radii: (0.).into(),
6587        background: background.into(),
6588        border_widths: (0.).into(),
6589        border_color: transparent_black(),
6590        border_style: BorderStyle::default(),
6591    }
6592}
6593
6594/// Creates a rectangle outline with the given bounds, border color, and a 1px border width
6595pub fn outline(
6596    bounds: impl Into<Bounds<Pixels>>,
6597    border_color: impl Into<Hsla>,
6598    border_style: BorderStyle,
6599) -> PaintQuad {
6600    PaintQuad {
6601        bounds: bounds.into(),
6602        corner_radii: (0.).into(),
6603        background: transparent_black().into(),
6604        border_widths: (1.).into(),
6605        border_color: border_color.into(),
6606        border_style,
6607    }
6608}
6609
6610#[cfg(test)]
6611mod tests {
6612    use std::{cell::Cell, rc::Rc};
6613
6614    use crate::{
6615        AppContext as _, Bounds, Context, FocusHandle, InteractiveElement as _, IntoElement,
6616        ParentElement, Pixels, Render, Styled, TestAppContext, Window, WindowOptions, canvas, div,
6617        px, size,
6618    };
6619
6620    struct EmptyView;
6621
6622    impl Render for EmptyView {
6623        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
6624            div()
6625        }
6626    }
6627
6628    struct OpensWindowOnPaint {
6629        opened: Rc<Cell<bool>>,
6630    }
6631
6632    impl Render for OpensWindowOnPaint {
6633        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
6634            let opened = self.opened.clone();
6635            div()
6636                .size_full()
6637                .child(canvas(
6638                    |_, _, _| {},
6639                    move |_, _, _window, cx| {
6640                        if !opened.replace(true) {
6641                            cx.open_window(WindowOptions::default(), |_, cx| cx.new(|_| EmptyView))
6642                                .unwrap();
6643                        }
6644                    },
6645                ))
6646                // Siblings painted after the canvas: their elements were
6647                // allocated in the arena before the nested draw, so they detect
6648                // a mid-draw arena clear when painted afterwards.
6649                .child(div().child("after"))
6650        }
6651    }
6652
6653    /// Opening a window synchronously draws it and requests an element arena
6654    /// clear. When that happens from within another window's draw (here: from
6655    /// an element's paint), the clear must be deferred until the outer draw
6656    /// finishes, or the outer draw's arena-allocated elements would be freed
6657    /// out from under it.
6658    #[test]
6659    fn test_window_opened_during_draw_defers_arena_clear() {
6660        let mut cx = TestAppContext::single();
6661
6662        let opened = Rc::new(Cell::new(false));
6663        // add_window draws once, which runs the nested open_window mid-draw.
6664        let window = cx.add_window({
6665            let opened = opened.clone();
6666            move |_, _| OpensWindowOnPaint { opened }
6667        });
6668
6669        assert!(opened.get());
6670        assert_eq!(cx.windows().len(), 2);
6671
6672        // The deferred clear must actually run once the outer draw unwinds:
6673        // subsequent draws of both windows work against a fresh arena.
6674        cx.update_window(window.into(), |_, window, cx| window.draw(cx).clear(cx))
6675            .unwrap();
6676    }
6677
6678    struct RootView {
6679        explicit_size: bool,
6680        child_bounds: Rc<Cell<Bounds<Pixels>>>,
6681    }
6682
6683    impl Render for RootView {
6684        fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
6685            let child_bounds = self.child_bounds.clone();
6686            let root = div().flex().flex_col().child(
6687                canvas(
6688                    move |bounds, _, _| child_bounds.set(bounds),
6689                    |_, _, _, _| {},
6690                )
6691                .size_full(),
6692            );
6693            if self.explicit_size {
6694                root.w(px(300.)).h(px(200.))
6695            } else {
6696                root
6697            }
6698        }
6699    }
6700
6701    #[test]
6702    fn auto_sized_window_root_fills_the_window() {
6703        let mut cx = TestAppContext::single();
6704        let child_bounds = Rc::new(Cell::new(Bounds::default()));
6705        let window = cx.add_window({
6706            let child_bounds = child_bounds.clone();
6707            move |_, _| RootView {
6708                explicit_size: false,
6709                child_bounds,
6710            }
6711        });
6712
6713        let viewport_size = cx
6714            .update_window(window.into(), |_, window, cx| {
6715                window.draw(cx).clear(cx);
6716                window.viewport_size()
6717            })
6718            .unwrap();
6719
6720        assert_eq!(child_bounds.get().size, viewport_size);
6721    }
6722
6723    #[test]
6724    fn explicitly_sized_window_root_keeps_its_size() {
6725        let mut cx = TestAppContext::single();
6726        let child_bounds = Rc::new(Cell::new(Bounds::default()));
6727        let window = cx.add_window({
6728            let child_bounds = child_bounds.clone();
6729            move |_, _| RootView {
6730                explicit_size: true,
6731                child_bounds,
6732            }
6733        });
6734
6735        cx.update_window(window.into(), |_, window, cx| {
6736            window.draw(cx).clear(cx);
6737        })
6738        .unwrap();
6739
6740        assert_eq!(child_bounds.get().size, size(px(300.), px(200.)));
6741    }
6742
6743    struct FocusForwarder {
6744        a: FocusHandle,
6745        b: FocusHandle,
6746    }
6747
6748    impl Render for FocusForwarder {
6749        fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
6750            div()
6751                .size_full()
6752                .child(div().w(px(50.)).h(px(50.)).track_focus(&self.a))
6753                .child(div().w(px(50.)).h(px(50.)).track_focus(&self.b))
6754        }
6755    }
6756
6757    /// When a focus listener moves focus again (e.g. a dock forwarding focus to its
6758    /// active panel), the resulting focus events must be dispatched without waiting
6759    /// for an unrelated redraw of the window.
6760    #[gpui::test]
6761    fn test_focus_moved_by_focus_listener_is_dispatched(cx: &mut TestAppContext) {
6762        let b_focus_count = Rc::new(Cell::new(0));
6763        let window = cx.add_window({
6764            let b_focus_count = b_focus_count.clone();
6765            move |window, cx| {
6766                let a = cx.focus_handle();
6767                let b = cx.focus_handle();
6768                cx.on_focus(&a, window, |this: &mut FocusForwarder, window, cx| {
6769                    let b = this.b.clone();
6770                    window.focus(&b, cx);
6771                })
6772                .detach();
6773                cx.on_focus(&b, window, move |_, _, _| {
6774                    b_focus_count.set(b_focus_count.get() + 1);
6775                })
6776                .detach();
6777                FocusForwarder { a, b }
6778            }
6779        });
6780
6781        window
6782            .update(cx, |_, window, _| window.activate_window())
6783            .unwrap();
6784        cx.executor().run_until_parked();
6785
6786        window
6787            .update(cx, |this, window, cx| {
6788                let a = this.a.clone();
6789                window.focus(&a, cx);
6790            })
6791            .unwrap();
6792        cx.executor().run_until_parked();
6793
6794        window
6795            .update(cx, |this, window, _| {
6796                assert!(this.b.is_focused(window));
6797            })
6798            .unwrap();
6799        assert_eq!(b_focus_count.get(), 1);
6800    }
6801}
6802
Served at tenant.openagents/omega Member data and write actions are omitted.