Skip to main content

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