Skip to main content

gpui/
window.rs

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