Skip to main content

gpui/
window.rs

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