1use crate::{
2 hash, point, prelude::*, px, size, transparent_black, Action, AnyDrag, AnyElement, AnyTooltip,
3 AnyView, AppContext, Arena, Asset, AsyncWindowContext, AvailableSpace, Bounds, BoxShadow,
4 Context, Corners, CursorStyle, DevicePixels, DispatchActionListener, DispatchNodeId,
5 DispatchTree, DisplayId, Edges, Effect, Entity, EntityId, EventEmitter, FileDropEvent, Flatten,
6 FontId, Global, GlobalElementId, GlyphId, Hsla, ImageData, InputHandler, IsZero, KeyBinding,
7 KeyContext, KeyDownEvent, KeyEvent, KeyMatch, KeymatchResult, Keystroke, KeystrokeEvent,
8 LayoutId, LineLayoutIndex, Model, ModelContext, Modifiers, ModifiersChangedEvent,
9 MonochromeSprite, MouseButton, MouseEvent, MouseMoveEvent, MouseUpEvent, Path, Pixels,
10 PlatformAtlas, PlatformDisplay, PlatformInput, PlatformInputHandler, PlatformWindow, Point,
11 PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams,
12 RenderSvgParams, ScaledPixels, Scene, Shadow, SharedString, Size, StrikethroughStyle, Style,
13 SubscriberSet, Subscription, TaffyLayoutEngine, Task, TextStyle, TextStyleRefinement,
14 TransformationMatrix, Underline, UnderlineStyle, View, VisualContext, WeakView,
15 WindowAppearance, WindowBackgroundAppearance, WindowBounds, WindowOptions, WindowParams,
16 WindowTextSystem, SUBPIXEL_VARIANTS,
17};
18use anyhow::{anyhow, Context as _, Result};
19use collections::{FxHashMap, FxHashSet};
20use derive_more::{Deref, DerefMut};
21use futures::channel::oneshot;
22use futures::{future::Shared, FutureExt};
23#[cfg(target_os = "macos")]
24use media::core_video::CVImageBuffer;
25use parking_lot::RwLock;
26use refineable::Refineable;
27use slotmap::SlotMap;
28use smallvec::SmallVec;
29use std::{
30 any::{Any, TypeId},
31 borrow::{Borrow, BorrowMut, Cow},
32 cell::{Cell, RefCell},
33 cmp,
34 fmt::{Debug, Display},
35 future::Future,
36 hash::{Hash, Hasher},
37 marker::PhantomData,
38 mem,
39 ops::Range,
40 rc::Rc,
41 sync::{
42 atomic::{AtomicUsize, Ordering::SeqCst},
43 Arc, Weak,
44 },
45 time::{Duration, Instant},
46};
47use util::post_inc;
48use util::{measure, ResultExt};
49use uuid::Uuid;
50
51mod prompts;
52
53pub use prompts::*;
54
55pub(crate) const DEFAULT_WINDOW_SIZE: Size<Pixels> = size(px(1024.), px(700.));
56
57/// Represents the two different phases when dispatching events.
58#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]
59pub enum DispatchPhase {
60 /// After the capture phase comes the bubble phase, in which mouse event listeners are
61 /// invoked front to back and keyboard event listeners are invoked from the focused element
62 /// to the root of the element tree. This is the phase you'll most commonly want to use when
63 /// registering event listeners.
64 #[default]
65 Bubble,
66 /// During the initial capture phase, mouse event listeners are invoked back to front, and keyboard
67 /// listeners are invoked from the root of the tree downward toward the focused element. This phase
68 /// is used for special purposes such as clearing the "pressed" state for click events. If
69 /// you stop event propagation during this phase, you need to know what you're doing. Handlers
70 /// outside of the immediate region may rely on detecting non-local events during this phase.
71 Capture,
72}
73
74impl DispatchPhase {
75 /// Returns true if this represents the "bubble" phase.
76 pub fn bubble(self) -> bool {
77 self == DispatchPhase::Bubble
78 }
79
80 /// Returns true if this represents the "capture" phase.
81 pub fn capture(self) -> bool {
82 self == DispatchPhase::Capture
83 }
84}
85
86type AnyObserver = Box<dyn FnMut(&mut WindowContext) -> bool + 'static>;
87
88type AnyWindowFocusListener =
89 Box<dyn FnMut(&WindowFocusEvent, &mut WindowContext) -> bool + 'static>;
90
91struct WindowFocusEvent {
92 previous_focus_path: SmallVec<[FocusId; 8]>,
93 current_focus_path: SmallVec<[FocusId; 8]>,
94}
95
96/// This is provided when subscribing for `ViewContext::on_focus_out` events.
97pub struct FocusOutEvent {
98 /// A weak focus handle representing what was blurred.
99 pub blurred: WeakFocusHandle,
100}
101
102slotmap::new_key_type! {
103 /// A globally unique identifier for a focusable element.
104 pub struct FocusId;
105}
106
107thread_local! {
108 /// 8MB wasn't quite enough...
109 pub(crate) static ELEMENT_ARENA: RefCell<Arena> = RefCell::new(Arena::new(32 * 1024 * 1024));
110}
111
112impl FocusId {
113 /// Obtains whether the element associated with this handle is currently focused.
114 pub fn is_focused(&self, cx: &WindowContext) -> bool {
115 cx.window.focus == Some(*self)
116 }
117
118 /// Obtains whether the element associated with this handle contains the focused
119 /// element or is itself focused.
120 pub fn contains_focused(&self, cx: &WindowContext) -> bool {
121 cx.focused()
122 .map_or(false, |focused| self.contains(focused.id, cx))
123 }
124
125 /// Obtains whether the element associated with this handle is contained within the
126 /// focused element or is itself focused.
127 pub fn within_focused(&self, cx: &WindowContext) -> bool {
128 let focused = cx.focused();
129 focused.map_or(false, |focused| focused.id.contains(*self, cx))
130 }
131
132 /// Obtains whether this handle contains the given handle in the most recently rendered frame.
133 pub(crate) fn contains(&self, other: Self, cx: &WindowContext) -> bool {
134 cx.window
135 .rendered_frame
136 .dispatch_tree
137 .focus_contains(*self, other)
138 }
139}
140
141/// A handle which can be used to track and manipulate the focused element in a window.
142pub struct FocusHandle {
143 pub(crate) id: FocusId,
144 handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
145}
146
147impl std::fmt::Debug for FocusHandle {
148 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149 f.write_fmt(format_args!("FocusHandle({:?})", self.id))
150 }
151}
152
153impl FocusHandle {
154 pub(crate) fn new(handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>) -> Self {
155 let id = handles.write().insert(AtomicUsize::new(1));
156 Self {
157 id,
158 handles: handles.clone(),
159 }
160 }
161
162 pub(crate) fn for_id(
163 id: FocusId,
164 handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
165 ) -> Option<Self> {
166 let lock = handles.read();
167 let ref_count = lock.get(id)?;
168 if ref_count.load(SeqCst) == 0 {
169 None
170 } else {
171 ref_count.fetch_add(1, SeqCst);
172 Some(Self {
173 id,
174 handles: handles.clone(),
175 })
176 }
177 }
178
179 /// Converts this focus handle into a weak variant, which does not prevent it from being released.
180 pub fn downgrade(&self) -> WeakFocusHandle {
181 WeakFocusHandle {
182 id: self.id,
183 handles: Arc::downgrade(&self.handles),
184 }
185 }
186
187 /// Moves the focus to the element associated with this handle.
188 pub fn focus(&self, cx: &mut WindowContext) {
189 cx.focus(self)
190 }
191
192 /// Obtains whether the element associated with this handle is currently focused.
193 pub fn is_focused(&self, cx: &WindowContext) -> bool {
194 self.id.is_focused(cx)
195 }
196
197 /// Obtains whether the element associated with this handle contains the focused
198 /// element or is itself focused.
199 pub fn contains_focused(&self, cx: &WindowContext) -> bool {
200 self.id.contains_focused(cx)
201 }
202
203 /// Obtains whether the element associated with this handle is contained within the
204 /// focused element or is itself focused.
205 pub fn within_focused(&self, cx: &WindowContext) -> bool {
206 self.id.within_focused(cx)
207 }
208
209 /// Obtains whether this handle contains the given handle in the most recently rendered frame.
210 pub fn contains(&self, other: &Self, cx: &WindowContext) -> bool {
211 self.id.contains(other.id, cx)
212 }
213
214 /// Dispatch an action on the element that rendered this focus handle
215 pub fn dispatch_action(&self, action: &dyn Action, cx: &mut WindowContext) {
216 if let Some(node_id) = cx
217 .window
218 .rendered_frame
219 .dispatch_tree
220 .focusable_node_id(self.id)
221 {
222 cx.dispatch_action_on_node(node_id, action)
223 }
224 }
225}
226
227impl Clone for FocusHandle {
228 fn clone(&self) -> Self {
229 Self::for_id(self.id, &self.handles).unwrap()
230 }
231}
232
233impl PartialEq for FocusHandle {
234 fn eq(&self, other: &Self) -> bool {
235 self.id == other.id
236 }
237}
238
239impl Eq for FocusHandle {}
240
241impl Drop for FocusHandle {
242 fn drop(&mut self) {
243 self.handles
244 .read()
245 .get(self.id)
246 .unwrap()
247 .fetch_sub(1, SeqCst);
248 }
249}
250
251/// A weak reference to a focus handle.
252#[derive(Clone, Debug)]
253pub struct WeakFocusHandle {
254 pub(crate) id: FocusId,
255 handles: Weak<RwLock<SlotMap<FocusId, AtomicUsize>>>,
256}
257
258impl WeakFocusHandle {
259 /// Attempts to upgrade the [WeakFocusHandle] to a [FocusHandle].
260 pub fn upgrade(&self) -> Option<FocusHandle> {
261 let handles = self.handles.upgrade()?;
262 FocusHandle::for_id(self.id, &handles)
263 }
264}
265
266impl PartialEq for WeakFocusHandle {
267 fn eq(&self, other: &WeakFocusHandle) -> bool {
268 self.id == other.id
269 }
270}
271
272impl Eq for WeakFocusHandle {}
273
274impl PartialEq<FocusHandle> for WeakFocusHandle {
275 fn eq(&self, other: &FocusHandle) -> bool {
276 self.id == other.id
277 }
278}
279
280impl PartialEq<WeakFocusHandle> for FocusHandle {
281 fn eq(&self, other: &WeakFocusHandle) -> bool {
282 self.id == other.id
283 }
284}
285
286/// FocusableView allows users of your view to easily
287/// focus it (using cx.focus_view(view))
288pub trait FocusableView: 'static + Render {
289 /// Returns the focus handle associated with this view.
290 fn focus_handle(&self, cx: &AppContext) -> FocusHandle;
291}
292
293/// ManagedView is a view (like a Modal, Popover, Menu, etc.)
294/// where the lifecycle of the view is handled by another view.
295pub trait ManagedView: FocusableView + EventEmitter<DismissEvent> {}
296
297impl<M: FocusableView + EventEmitter<DismissEvent>> ManagedView for M {}
298
299/// Emitted by implementers of [`ManagedView`] to indicate the view should be dismissed, such as when a view is presented as a modal.
300pub struct DismissEvent;
301
302type FrameCallback = Box<dyn FnOnce(&mut WindowContext)>;
303
304pub(crate) type AnyMouseListener =
305 Box<dyn FnMut(&dyn Any, DispatchPhase, &mut WindowContext) + 'static>;
306
307#[derive(Clone)]
308pub(crate) struct CursorStyleRequest {
309 pub(crate) hitbox_id: HitboxId,
310 pub(crate) style: CursorStyle,
311}
312
313/// An identifier for a [Hitbox].
314#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
315pub struct HitboxId(usize);
316
317impl HitboxId {
318 /// Checks if the hitbox with this id is currently hovered.
319 pub fn is_hovered(&self, cx: &WindowContext) -> bool {
320 cx.window.mouse_hit_test.0.contains(self)
321 }
322}
323
324/// A rectangular region that potentially blocks hitboxes inserted prior.
325/// See [WindowContext::insert_hitbox] for more details.
326#[derive(Clone, Debug, Deref)]
327pub struct Hitbox {
328 /// A unique identifier for the hitbox.
329 pub id: HitboxId,
330 /// The bounds of the hitbox.
331 #[deref]
332 pub bounds: Bounds<Pixels>,
333 /// The content mask when the hitbox was inserted.
334 pub content_mask: ContentMask<Pixels>,
335 /// Whether the hitbox occludes other hitboxes inserted prior.
336 pub opaque: bool,
337}
338
339impl Hitbox {
340 /// Checks if the hitbox is currently hovered.
341 pub fn is_hovered(&self, cx: &WindowContext) -> bool {
342 self.id.is_hovered(cx)
343 }
344}
345
346#[derive(Default, Eq, PartialEq)]
347pub(crate) struct HitTest(SmallVec<[HitboxId; 8]>);
348
349/// An identifier for a tooltip.
350#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
351pub struct TooltipId(usize);
352
353impl TooltipId {
354 /// Checks if the tooltip is currently hovered.
355 pub fn is_hovered(&self, cx: &WindowContext) -> bool {
356 cx.window
357 .tooltip_bounds
358 .as_ref()
359 .map_or(false, |tooltip_bounds| {
360 tooltip_bounds.id == *self && tooltip_bounds.bounds.contains(&cx.mouse_position())
361 })
362 }
363}
364
365pub(crate) struct TooltipBounds {
366 id: TooltipId,
367 bounds: Bounds<Pixels>,
368}
369
370#[derive(Clone)]
371pub(crate) struct TooltipRequest {
372 id: TooltipId,
373 tooltip: AnyTooltip,
374}
375
376pub(crate) struct DeferredDraw {
377 priority: usize,
378 parent_node: DispatchNodeId,
379 element_id_stack: SmallVec<[ElementId; 32]>,
380 text_style_stack: Vec<TextStyleRefinement>,
381 element: Option<AnyElement>,
382 absolute_offset: Point<Pixels>,
383 prepaint_range: Range<PrepaintStateIndex>,
384 paint_range: Range<PaintIndex>,
385}
386
387pub(crate) struct Frame {
388 pub(crate) focus: Option<FocusId>,
389 pub(crate) window_active: bool,
390 pub(crate) element_states: FxHashMap<(GlobalElementId, TypeId), ElementStateBox>,
391 accessed_element_states: Vec<(GlobalElementId, TypeId)>,
392 pub(crate) mouse_listeners: Vec<Option<AnyMouseListener>>,
393 pub(crate) dispatch_tree: DispatchTree,
394 pub(crate) scene: Scene,
395 pub(crate) hitboxes: Vec<Hitbox>,
396 pub(crate) deferred_draws: Vec<DeferredDraw>,
397 pub(crate) input_handlers: Vec<Option<PlatformInputHandler>>,
398 pub(crate) tooltip_requests: Vec<Option<TooltipRequest>>,
399 pub(crate) cursor_styles: Vec<CursorStyleRequest>,
400 #[cfg(any(test, feature = "test-support"))]
401 pub(crate) debug_bounds: FxHashMap<String, Bounds<Pixels>>,
402}
403
404#[derive(Clone, Default)]
405pub(crate) struct PrepaintStateIndex {
406 hitboxes_index: usize,
407 tooltips_index: usize,
408 deferred_draws_index: usize,
409 dispatch_tree_index: usize,
410 accessed_element_states_index: usize,
411 line_layout_index: LineLayoutIndex,
412}
413
414#[derive(Clone, Default)]
415pub(crate) struct PaintIndex {
416 scene_index: usize,
417 mouse_listeners_index: usize,
418 input_handlers_index: usize,
419 cursor_styles_index: usize,
420 accessed_element_states_index: usize,
421 line_layout_index: LineLayoutIndex,
422}
423
424impl Frame {
425 pub(crate) fn new(dispatch_tree: DispatchTree) -> Self {
426 Frame {
427 focus: None,
428 window_active: false,
429 element_states: FxHashMap::default(),
430 accessed_element_states: Vec::new(),
431 mouse_listeners: Vec::new(),
432 dispatch_tree,
433 scene: Scene::default(),
434 hitboxes: Vec::new(),
435 deferred_draws: Vec::new(),
436 input_handlers: Vec::new(),
437 tooltip_requests: Vec::new(),
438 cursor_styles: Vec::new(),
439
440 #[cfg(any(test, feature = "test-support"))]
441 debug_bounds: FxHashMap::default(),
442 }
443 }
444
445 pub(crate) fn clear(&mut self) {
446 self.element_states.clear();
447 self.accessed_element_states.clear();
448 self.mouse_listeners.clear();
449 self.dispatch_tree.clear();
450 self.scene.clear();
451 self.input_handlers.clear();
452 self.tooltip_requests.clear();
453 self.cursor_styles.clear();
454 self.hitboxes.clear();
455 self.deferred_draws.clear();
456 }
457
458 pub(crate) fn hit_test(&self, position: Point<Pixels>) -> HitTest {
459 let mut hit_test = HitTest::default();
460 for hitbox in self.hitboxes.iter().rev() {
461 let bounds = hitbox.bounds.intersect(&hitbox.content_mask.bounds);
462 if bounds.contains(&position) {
463 hit_test.0.push(hitbox.id);
464 if hitbox.opaque {
465 break;
466 }
467 }
468 }
469 hit_test
470 }
471
472 pub(crate) fn focus_path(&self) -> SmallVec<[FocusId; 8]> {
473 self.focus
474 .map(|focus_id| self.dispatch_tree.focus_path(focus_id))
475 .unwrap_or_default()
476 }
477
478 pub(crate) fn finish(&mut self, prev_frame: &mut Self) {
479 for element_state_key in &self.accessed_element_states {
480 if let Some((element_state_key, element_state)) =
481 prev_frame.element_states.remove_entry(element_state_key)
482 {
483 self.element_states.insert(element_state_key, element_state);
484 }
485 }
486
487 self.scene.finish();
488 }
489}
490
491// Holds the state for a specific window.
492#[doc(hidden)]
493pub struct Window {
494 pub(crate) handle: AnyWindowHandle,
495 pub(crate) removed: bool,
496 pub(crate) platform_window: Box<dyn PlatformWindow>,
497 display_id: Option<DisplayId>,
498 sprite_atlas: Arc<dyn PlatformAtlas>,
499 text_system: Arc<WindowTextSystem>,
500 rem_size: Pixels,
501 /// The stack of override values for the window's rem size.
502 ///
503 /// This is used by `with_rem_size` to allow rendering an element tree with
504 /// a given rem size.
505 rem_size_override_stack: SmallVec<[Pixels; 8]>,
506 pub(crate) viewport_size: Size<Pixels>,
507 layout_engine: Option<TaffyLayoutEngine>,
508 pub(crate) root_view: Option<AnyView>,
509 pub(crate) element_id_stack: SmallVec<[ElementId; 32]>,
510 pub(crate) text_style_stack: Vec<TextStyleRefinement>,
511 pub(crate) element_offset_stack: Vec<Point<Pixels>>,
512 pub(crate) content_mask_stack: Vec<ContentMask<Pixels>>,
513 pub(crate) requested_autoscroll: Option<Bounds<Pixels>>,
514 pub(crate) rendered_frame: Frame,
515 pub(crate) next_frame: Frame,
516 pub(crate) next_hitbox_id: HitboxId,
517 pub(crate) next_tooltip_id: TooltipId,
518 pub(crate) tooltip_bounds: Option<TooltipBounds>,
519 next_frame_callbacks: Rc<RefCell<Vec<FrameCallback>>>,
520 pub(crate) dirty_views: FxHashSet<EntityId>,
521 pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
522 focus_listeners: SubscriberSet<(), AnyWindowFocusListener>,
523 focus_lost_listeners: SubscriberSet<(), AnyObserver>,
524 default_prevented: bool,
525 mouse_position: Point<Pixels>,
526 mouse_hit_test: HitTest,
527 modifiers: Modifiers,
528 scale_factor: f32,
529 bounds_observers: SubscriberSet<(), AnyObserver>,
530 appearance: WindowAppearance,
531 appearance_observers: SubscriberSet<(), AnyObserver>,
532 active: Rc<Cell<bool>>,
533 pub(crate) dirty: Rc<Cell<bool>>,
534 pub(crate) needs_present: Rc<Cell<bool>>,
535 pub(crate) last_input_timestamp: Rc<Cell<Instant>>,
536 pub(crate) refreshing: bool,
537 pub(crate) draw_phase: DrawPhase,
538 activation_observers: SubscriberSet<(), AnyObserver>,
539 pub(crate) focus: Option<FocusId>,
540 focus_enabled: bool,
541 pending_input: Option<PendingInput>,
542 prompt: Option<RenderablePromptHandle>,
543}
544
545#[derive(Clone, Copy, Debug, Eq, PartialEq)]
546pub(crate) enum DrawPhase {
547 None,
548 Prepaint,
549 Paint,
550 Focus,
551}
552
553#[derive(Default, Debug)]
554struct PendingInput {
555 keystrokes: SmallVec<[Keystroke; 1]>,
556 bindings: SmallVec<[KeyBinding; 1]>,
557 focus: Option<FocusId>,
558 timer: Option<Task<()>>,
559}
560
561impl PendingInput {
562 fn input(&self) -> String {
563 self.keystrokes
564 .iter()
565 .flat_map(|k| k.ime_key.clone())
566 .collect::<Vec<String>>()
567 .join("")
568 }
569
570 fn used_by_binding(&self, binding: &KeyBinding) -> bool {
571 if self.keystrokes.is_empty() {
572 return true;
573 }
574 let keystroke = &self.keystrokes[0];
575 for candidate in keystroke.match_candidates() {
576 if binding.match_keystrokes(&[candidate]) == KeyMatch::Pending {
577 return true;
578 }
579 }
580 false
581 }
582}
583
584pub(crate) struct ElementStateBox {
585 pub(crate) inner: Box<dyn Any>,
586 #[cfg(debug_assertions)]
587 pub(crate) type_name: &'static str,
588}
589
590fn default_bounds(display_id: Option<DisplayId>, cx: &mut AppContext) -> Bounds<Pixels> {
591 const DEFAULT_WINDOW_OFFSET: Point<Pixels> = point(px(0.), px(35.));
592
593 cx.active_window()
594 .and_then(|w| w.update(cx, |_, cx| cx.bounds()).ok())
595 .map(|bounds| bounds.map_origin(|origin| origin + DEFAULT_WINDOW_OFFSET))
596 .unwrap_or_else(|| {
597 let display = display_id
598 .map(|id| cx.find_display(id))
599 .unwrap_or_else(|| cx.primary_display());
600
601 display
602 .map(|display| display.default_bounds())
603 .unwrap_or_else(|| Bounds::new(point(px(0.), px(0.)), DEFAULT_WINDOW_SIZE))
604 })
605}
606
607impl Window {
608 pub(crate) fn new(
609 handle: AnyWindowHandle,
610 options: WindowOptions,
611 cx: &mut AppContext,
612 ) -> Result<Self> {
613 let WindowOptions {
614 window_bounds,
615 titlebar,
616 focus,
617 show,
618 kind,
619 is_movable,
620 display_id,
621 window_background,
622 app_id,
623 } = options;
624
625 let bounds = window_bounds
626 .map(|bounds| bounds.get_bounds())
627 .unwrap_or_else(|| default_bounds(display_id, cx));
628 let mut platform_window = cx.platform.open_window(
629 handle,
630 WindowParams {
631 bounds,
632 titlebar,
633 kind,
634 is_movable,
635 focus,
636 show,
637 display_id,
638 window_background,
639 },
640 )?;
641 let display_id = platform_window.display().map(|display| display.id());
642 let sprite_atlas = platform_window.sprite_atlas();
643 let mouse_position = platform_window.mouse_position();
644 let modifiers = platform_window.modifiers();
645 let content_size = platform_window.content_size();
646 let scale_factor = platform_window.scale_factor();
647 let appearance = platform_window.appearance();
648 let text_system = Arc::new(WindowTextSystem::new(cx.text_system().clone()));
649 let dirty = Rc::new(Cell::new(true));
650 let active = Rc::new(Cell::new(platform_window.is_active()));
651 let needs_present = Rc::new(Cell::new(false));
652 let next_frame_callbacks: Rc<RefCell<Vec<FrameCallback>>> = Default::default();
653 let last_input_timestamp = Rc::new(Cell::new(Instant::now()));
654
655 if let Some(ref window_open_state) = window_bounds {
656 match window_open_state {
657 WindowBounds::Fullscreen(_) => platform_window.toggle_fullscreen(),
658 WindowBounds::Maximized(_) => platform_window.zoom(),
659 WindowBounds::Windowed(_) => {}
660 }
661 }
662
663 platform_window.on_close(Box::new({
664 let mut cx = cx.to_async();
665 move || {
666 let _ = handle.update(&mut cx, |_, cx| cx.remove_window());
667 }
668 }));
669 platform_window.on_request_frame(Box::new({
670 let mut cx = cx.to_async();
671 let dirty = dirty.clone();
672 let active = active.clone();
673 let needs_present = needs_present.clone();
674 let next_frame_callbacks = next_frame_callbacks.clone();
675 let last_input_timestamp = last_input_timestamp.clone();
676 move || {
677 let next_frame_callbacks = next_frame_callbacks.take();
678 if !next_frame_callbacks.is_empty() {
679 handle
680 .update(&mut cx, |_, cx| {
681 for callback in next_frame_callbacks {
682 callback(cx);
683 }
684 })
685 .log_err();
686 }
687
688 // Keep presenting the current scene for 1 extra second since the
689 // last input to prevent the display from underclocking the refresh rate.
690 let needs_present = needs_present.get()
691 || (active.get()
692 && last_input_timestamp.get().elapsed() < Duration::from_secs(1));
693
694 if dirty.get() {
695 measure("frame duration", || {
696 handle
697 .update(&mut cx, |_, cx| {
698 cx.draw();
699 cx.present();
700 })
701 .log_err();
702 })
703 } else if needs_present {
704 handle.update(&mut cx, |_, cx| cx.present()).log_err();
705 }
706
707 handle
708 .update(&mut cx, |_, cx| {
709 cx.complete_frame();
710 })
711 .log_err();
712 }
713 }));
714 platform_window.on_resize(Box::new({
715 let mut cx = cx.to_async();
716 move |_, _| {
717 handle
718 .update(&mut cx, |_, cx| cx.bounds_changed())
719 .log_err();
720 }
721 }));
722 platform_window.on_moved(Box::new({
723 let mut cx = cx.to_async();
724 move || {
725 handle
726 .update(&mut cx, |_, cx| cx.bounds_changed())
727 .log_err();
728 }
729 }));
730 platform_window.on_appearance_changed(Box::new({
731 let mut cx = cx.to_async();
732 move || {
733 handle
734 .update(&mut cx, |_, cx| cx.appearance_changed())
735 .log_err();
736 }
737 }));
738 platform_window.on_active_status_change(Box::new({
739 let mut cx = cx.to_async();
740 move |active| {
741 handle
742 .update(&mut cx, |_, cx| {
743 cx.window.active.set(active);
744 cx.window
745 .activation_observers
746 .clone()
747 .retain(&(), |callback| callback(cx));
748 cx.refresh();
749 })
750 .log_err();
751 }
752 }));
753
754 platform_window.on_input({
755 let mut cx = cx.to_async();
756 Box::new(move |event| {
757 handle
758 .update(&mut cx, |_, cx| cx.dispatch_event(event))
759 .log_err()
760 .unwrap_or(DispatchEventResult::default())
761 })
762 });
763
764 if let Some(app_id) = app_id {
765 platform_window.set_app_id(&app_id);
766 }
767
768 Ok(Window {
769 handle,
770 removed: false,
771 platform_window,
772 display_id,
773 sprite_atlas,
774 text_system,
775 rem_size: px(16.),
776 rem_size_override_stack: SmallVec::new(),
777 viewport_size: content_size,
778 layout_engine: Some(TaffyLayoutEngine::new()),
779 root_view: None,
780 element_id_stack: SmallVec::default(),
781 text_style_stack: Vec::new(),
782 element_offset_stack: Vec::new(),
783 content_mask_stack: Vec::new(),
784 requested_autoscroll: None,
785 rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
786 next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
787 next_frame_callbacks,
788 next_hitbox_id: HitboxId::default(),
789 next_tooltip_id: TooltipId::default(),
790 tooltip_bounds: None,
791 dirty_views: FxHashSet::default(),
792 focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
793 focus_listeners: SubscriberSet::new(),
794 focus_lost_listeners: SubscriberSet::new(),
795 default_prevented: true,
796 mouse_position,
797 mouse_hit_test: HitTest::default(),
798 modifiers,
799 scale_factor,
800 bounds_observers: SubscriberSet::new(),
801 appearance,
802 appearance_observers: SubscriberSet::new(),
803 active,
804 dirty,
805 needs_present,
806 last_input_timestamp,
807 refreshing: false,
808 draw_phase: DrawPhase::None,
809 activation_observers: SubscriberSet::new(),
810 focus: None,
811 focus_enabled: true,
812 pending_input: None,
813 prompt: None,
814 })
815 }
816 fn new_focus_listener(
817 &mut self,
818 value: AnyWindowFocusListener,
819 ) -> (Subscription, impl FnOnce()) {
820 self.focus_listeners.insert((), value)
821 }
822}
823
824#[derive(Clone, Debug, Default, PartialEq, Eq)]
825pub(crate) struct DispatchEventResult {
826 pub propagate: bool,
827 pub default_prevented: bool,
828}
829
830/// Indicates which region of the window is visible. Content falling outside of this mask will not be
831/// rendered. Currently, only rectangular content masks are supported, but we give the mask its own type
832/// to leave room to support more complex shapes in the future.
833#[derive(Clone, Debug, Default, PartialEq, Eq)]
834#[repr(C)]
835pub struct ContentMask<P: Clone + Default + Debug> {
836 /// The bounds
837 pub bounds: Bounds<P>,
838}
839
840impl ContentMask<Pixels> {
841 /// Scale the content mask's pixel units by the given scaling factor.
842 pub fn scale(&self, factor: f32) -> ContentMask<ScaledPixels> {
843 ContentMask {
844 bounds: self.bounds.scale(factor),
845 }
846 }
847
848 /// Intersect the content mask with the given content mask.
849 pub fn intersect(&self, other: &Self) -> Self {
850 let bounds = self.bounds.intersect(&other.bounds);
851 ContentMask { bounds }
852 }
853}
854
855/// Provides access to application state in the context of a single window. Derefs
856/// to an [`AppContext`], so you can also pass a [`WindowContext`] to any method that takes
857/// an [`AppContext`] and call any [`AppContext`] methods.
858pub struct WindowContext<'a> {
859 pub(crate) app: &'a mut AppContext,
860 pub(crate) window: &'a mut Window,
861}
862
863impl<'a> WindowContext<'a> {
864 pub(crate) fn new(app: &'a mut AppContext, window: &'a mut Window) -> Self {
865 Self { app, window }
866 }
867
868 /// Obtain a handle to the window that belongs to this context.
869 pub fn window_handle(&self) -> AnyWindowHandle {
870 self.window.handle
871 }
872
873 /// Mark the window as dirty, scheduling it to be redrawn on the next frame.
874 pub fn refresh(&mut self) {
875 if self.window.draw_phase == DrawPhase::None {
876 self.window.refreshing = true;
877 self.window.dirty.set(true);
878 }
879 }
880
881 /// Indicate that this view has changed, which will invoke any observers and also mark the window as dirty.
882 /// If this view or any of its ancestors are *cached*, notifying it will cause it or its ancestors to be redrawn.
883 pub fn notify(&mut self, view_id: EntityId) {
884 for view_id in self
885 .window
886 .rendered_frame
887 .dispatch_tree
888 .view_path(view_id)
889 .into_iter()
890 .rev()
891 {
892 if !self.window.dirty_views.insert(view_id) {
893 break;
894 }
895 }
896
897 if self.window.draw_phase == DrawPhase::None {
898 self.window.dirty.set(true);
899 self.app.push_effect(Effect::Notify { emitter: view_id });
900 }
901 }
902
903 /// Close this window.
904 pub fn remove_window(&mut self) {
905 self.window.removed = true;
906 }
907
908 /// Obtain a new [`FocusHandle`], which allows you to track and manipulate the keyboard focus
909 /// for elements rendered within this window.
910 pub fn focus_handle(&mut self) -> FocusHandle {
911 FocusHandle::new(&self.window.focus_handles)
912 }
913
914 /// Obtain the currently focused [`FocusHandle`]. If no elements are focused, returns `None`.
915 pub fn focused(&self) -> Option<FocusHandle> {
916 self.window
917 .focus
918 .and_then(|id| FocusHandle::for_id(id, &self.window.focus_handles))
919 }
920
921 /// Move focus to the element associated with the given [`FocusHandle`].
922 pub fn focus(&mut self, handle: &FocusHandle) {
923 if !self.window.focus_enabled || self.window.focus == Some(handle.id) {
924 return;
925 }
926
927 self.window.focus = Some(handle.id);
928 self.window
929 .rendered_frame
930 .dispatch_tree
931 .clear_pending_keystrokes();
932 self.refresh();
933 }
934
935 /// Remove focus from all elements within this context's window.
936 pub fn blur(&mut self) {
937 if !self.window.focus_enabled {
938 return;
939 }
940
941 self.window.focus = None;
942 self.refresh();
943 }
944
945 /// Blur the window and don't allow anything in it to be focused again.
946 pub fn disable_focus(&mut self) {
947 self.blur();
948 self.window.focus_enabled = false;
949 }
950
951 /// Accessor for the text system.
952 pub fn text_system(&self) -> &Arc<WindowTextSystem> {
953 &self.window.text_system
954 }
955
956 /// The current text style. Which is composed of all the style refinements provided to `with_text_style`.
957 pub fn text_style(&self) -> TextStyle {
958 let mut style = TextStyle::default();
959 for refinement in &self.window.text_style_stack {
960 style.refine(refinement);
961 }
962 style
963 }
964
965 /// Check if the platform window is maximized
966 /// On some platforms (namely Windows) this is different than the bounds being the size of the display
967 pub fn is_maximized(&self) -> bool {
968 self.window.platform_window.is_maximized()
969 }
970
971 /// Return the `WindowBounds` to indicate that how a window should be opened
972 /// after it has been closed
973 pub fn window_bounds(&self) -> WindowBounds {
974 self.window.platform_window.window_bounds()
975 }
976
977 /// Dispatch the given action on the currently focused element.
978 pub fn dispatch_action(&mut self, action: Box<dyn Action>) {
979 let focus_handle = self.focused();
980
981 let window = self.window.handle;
982 self.app.defer(move |cx| {
983 window
984 .update(cx, |_, cx| {
985 let node_id = focus_handle
986 .and_then(|handle| {
987 cx.window
988 .rendered_frame
989 .dispatch_tree
990 .focusable_node_id(handle.id)
991 })
992 .unwrap_or_else(|| cx.window.rendered_frame.dispatch_tree.root_node_id());
993
994 cx.dispatch_action_on_node(node_id, action.as_ref());
995 })
996 .log_err();
997 })
998 }
999
1000 pub(crate) fn dispatch_keystroke_observers(
1001 &mut self,
1002 event: &dyn Any,
1003 action: Option<Box<dyn Action>>,
1004 ) {
1005 let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() else {
1006 return;
1007 };
1008
1009 self.keystroke_observers
1010 .clone()
1011 .retain(&(), move |callback| {
1012 (callback)(
1013 &KeystrokeEvent {
1014 keystroke: key_down_event.keystroke.clone(),
1015 action: action.as_ref().map(|action| action.boxed_clone()),
1016 },
1017 self,
1018 );
1019 true
1020 });
1021 }
1022
1023 pub(crate) fn clear_pending_keystrokes(&mut self) {
1024 self.window
1025 .rendered_frame
1026 .dispatch_tree
1027 .clear_pending_keystrokes();
1028 self.window
1029 .next_frame
1030 .dispatch_tree
1031 .clear_pending_keystrokes();
1032 }
1033
1034 /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
1035 /// that are currently on the stack to be returned to the app.
1036 pub fn defer(&mut self, f: impl FnOnce(&mut WindowContext) + 'static) {
1037 let handle = self.window.handle;
1038 self.app.defer(move |cx| {
1039 handle.update(cx, |_, cx| f(cx)).ok();
1040 });
1041 }
1042
1043 /// Subscribe to events emitted by a model or view.
1044 /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
1045 /// The callback will be invoked a handle to the emitting entity (either a [`View`] or [`Model`]), the event, and a window context for the current window.
1046 pub fn observe<E, T>(
1047 &mut self,
1048 entity: &E,
1049 mut on_notify: impl FnMut(E, &mut WindowContext<'_>) + 'static,
1050 ) -> Subscription
1051 where
1052 E: Entity<T>,
1053 {
1054 let entity_id = entity.entity_id();
1055 let entity = entity.downgrade();
1056 let window_handle = self.window.handle;
1057 self.app.new_observer(
1058 entity_id,
1059 Box::new(move |cx| {
1060 window_handle
1061 .update(cx, |_, cx| {
1062 if let Some(handle) = E::upgrade_from(&entity) {
1063 on_notify(handle, cx);
1064 true
1065 } else {
1066 false
1067 }
1068 })
1069 .unwrap_or(false)
1070 }),
1071 )
1072 }
1073
1074 /// Subscribe to events emitted by a model or view.
1075 /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
1076 /// The callback will be invoked a handle to the emitting entity (either a [`View`] or [`Model`]), the event, and a window context for the current window.
1077 pub fn subscribe<Emitter, E, Evt>(
1078 &mut self,
1079 entity: &E,
1080 mut on_event: impl FnMut(E, &Evt, &mut WindowContext<'_>) + 'static,
1081 ) -> Subscription
1082 where
1083 Emitter: EventEmitter<Evt>,
1084 E: Entity<Emitter>,
1085 Evt: 'static,
1086 {
1087 let entity_id = entity.entity_id();
1088 let entity = entity.downgrade();
1089 let window_handle = self.window.handle;
1090 self.app.new_subscription(
1091 entity_id,
1092 (
1093 TypeId::of::<Evt>(),
1094 Box::new(move |event, cx| {
1095 window_handle
1096 .update(cx, |_, cx| {
1097 if let Some(handle) = E::upgrade_from(&entity) {
1098 let event = event.downcast_ref().expect("invalid event type");
1099 on_event(handle, event, cx);
1100 true
1101 } else {
1102 false
1103 }
1104 })
1105 .unwrap_or(false)
1106 }),
1107 ),
1108 )
1109 }
1110
1111 /// Creates an [`AsyncWindowContext`], which has a static lifetime and can be held across
1112 /// await points in async code.
1113 pub fn to_async(&self) -> AsyncWindowContext {
1114 AsyncWindowContext::new(self.app.to_async(), self.window.handle)
1115 }
1116
1117 /// Schedule the given closure to be run directly after the current frame is rendered.
1118 pub fn on_next_frame(&mut self, callback: impl FnOnce(&mut WindowContext) + 'static) {
1119 RefCell::borrow_mut(&self.window.next_frame_callbacks).push(Box::new(callback));
1120 }
1121
1122 /// Spawn the future returned by the given closure on the application thread pool.
1123 /// The closure is provided a handle to the current window and an `AsyncWindowContext` for
1124 /// use within your future.
1125 pub fn spawn<Fut, R>(&mut self, f: impl FnOnce(AsyncWindowContext) -> Fut) -> Task<R>
1126 where
1127 R: 'static,
1128 Fut: Future<Output = R> + 'static,
1129 {
1130 self.app
1131 .spawn(|app| f(AsyncWindowContext::new(app, self.window.handle)))
1132 }
1133
1134 fn bounds_changed(&mut self) {
1135 self.window.scale_factor = self.window.platform_window.scale_factor();
1136 self.window.viewport_size = self.window.platform_window.content_size();
1137 self.window.display_id = self
1138 .window
1139 .platform_window
1140 .display()
1141 .map(|display| display.id());
1142
1143 self.refresh();
1144
1145 self.window
1146 .bounds_observers
1147 .clone()
1148 .retain(&(), |callback| callback(self));
1149 }
1150
1151 /// Returns the bounds of the current window in the global coordinate space, which could span across multiple displays.
1152 pub fn bounds(&self) -> Bounds<Pixels> {
1153 self.window.platform_window.bounds()
1154 }
1155
1156 /// Returns whether or not the window is currently fullscreen
1157 pub fn is_fullscreen(&self) -> bool {
1158 self.window.platform_window.is_fullscreen()
1159 }
1160
1161 pub(crate) fn appearance_changed(&mut self) {
1162 self.window.appearance = self.window.platform_window.appearance();
1163
1164 self.window
1165 .appearance_observers
1166 .clone()
1167 .retain(&(), |callback| callback(self));
1168 }
1169
1170 /// Returns the appearance of the current window.
1171 pub fn appearance(&self) -> WindowAppearance {
1172 self.window.appearance
1173 }
1174
1175 /// Returns the size of the drawable area within the window.
1176 pub fn viewport_size(&self) -> Size<Pixels> {
1177 self.window.viewport_size
1178 }
1179
1180 /// Returns whether this window is focused by the operating system (receiving key events).
1181 pub fn is_window_active(&self) -> bool {
1182 self.window.active.get()
1183 }
1184
1185 /// Toggle zoom on the window.
1186 pub fn zoom_window(&self) {
1187 self.window.platform_window.zoom();
1188 }
1189
1190 /// Opens the native title bar context menu, useful when implementing client side decorations (Wayland and X11)
1191 pub fn show_window_menu(&self, position: Point<Pixels>) {
1192 self.window.platform_window.show_window_menu(position)
1193 }
1194
1195 /// Tells the compositor to take control of window movement (Wayland and X11)
1196 ///
1197 /// Events may not be received during a move operation.
1198 pub fn start_system_move(&self) {
1199 self.window.platform_window.start_system_move()
1200 }
1201
1202 /// Returns whether the title bar window controls need to be rendered by the application (Wayland and X11)
1203 pub fn should_render_window_controls(&self) -> bool {
1204 self.window.platform_window.should_render_window_controls()
1205 }
1206
1207 /// Updates the window's title at the platform level.
1208 pub fn set_window_title(&mut self, title: &str) {
1209 self.window.platform_window.set_title(title);
1210 }
1211
1212 /// Sets the application identifier.
1213 pub fn set_app_id(&mut self, app_id: &str) {
1214 self.window.platform_window.set_app_id(app_id);
1215 }
1216
1217 /// Sets the window background appearance.
1218 pub fn set_background_appearance(&mut self, background_appearance: WindowBackgroundAppearance) {
1219 self.window
1220 .platform_window
1221 .set_background_appearance(background_appearance);
1222 }
1223
1224 /// Mark the window as dirty at the platform level.
1225 pub fn set_window_edited(&mut self, edited: bool) {
1226 self.window.platform_window.set_edited(edited);
1227 }
1228
1229 /// Determine the display on which the window is visible.
1230 pub fn display(&self) -> Option<Rc<dyn PlatformDisplay>> {
1231 self.platform
1232 .displays()
1233 .into_iter()
1234 .find(|display| Some(display.id()) == self.window.display_id)
1235 }
1236
1237 /// Show the platform character palette.
1238 pub fn show_character_palette(&self) {
1239 self.window.platform_window.show_character_palette();
1240 }
1241
1242 /// The scale factor of the display associated with the window. For example, it could
1243 /// return 2.0 for a "retina" display, indicating that each logical pixel should actually
1244 /// be rendered as two pixels on screen.
1245 pub fn scale_factor(&self) -> f32 {
1246 self.window.scale_factor
1247 }
1248
1249 /// The size of an em for the base font of the application. Adjusting this value allows the
1250 /// UI to scale, just like zooming a web page.
1251 pub fn rem_size(&self) -> Pixels {
1252 self.window
1253 .rem_size_override_stack
1254 .last()
1255 .copied()
1256 .unwrap_or(self.window.rem_size)
1257 }
1258
1259 /// Sets the size of an em for the base font of the application. Adjusting this value allows the
1260 /// UI to scale, just like zooming a web page.
1261 pub fn set_rem_size(&mut self, rem_size: impl Into<Pixels>) {
1262 self.window.rem_size = rem_size.into();
1263 }
1264
1265 /// Executes the provided function with the specified rem size.
1266 ///
1267 /// This method must only be called as part of element drawing.
1268 pub fn with_rem_size<F, R>(&mut self, rem_size: Option<impl Into<Pixels>>, f: F) -> R
1269 where
1270 F: FnOnce(&mut Self) -> R,
1271 {
1272 debug_assert!(
1273 matches!(
1274 self.window.draw_phase,
1275 DrawPhase::Prepaint | DrawPhase::Paint
1276 ),
1277 "this method can only be called during request_layout, prepaint, or paint"
1278 );
1279
1280 if let Some(rem_size) = rem_size {
1281 self.window.rem_size_override_stack.push(rem_size.into());
1282 let result = f(self);
1283 self.window.rem_size_override_stack.pop();
1284 result
1285 } else {
1286 f(self)
1287 }
1288 }
1289
1290 /// The line height associated with the current text style.
1291 pub fn line_height(&self) -> Pixels {
1292 let rem_size = self.rem_size();
1293 let text_style = self.text_style();
1294 text_style
1295 .line_height
1296 .to_pixels(text_style.font_size, rem_size)
1297 }
1298
1299 /// Call to prevent the default action of an event. Currently only used to prevent
1300 /// parent elements from becoming focused on mouse down.
1301 pub fn prevent_default(&mut self) {
1302 self.window.default_prevented = true;
1303 }
1304
1305 /// Obtain whether default has been prevented for the event currently being dispatched.
1306 pub fn default_prevented(&self) -> bool {
1307 self.window.default_prevented
1308 }
1309
1310 /// Determine whether the given action is available along the dispatch path to the currently focused element.
1311 pub fn is_action_available(&self, action: &dyn Action) -> bool {
1312 let target = self
1313 .focused()
1314 .and_then(|focused_handle| {
1315 self.window
1316 .rendered_frame
1317 .dispatch_tree
1318 .focusable_node_id(focused_handle.id)
1319 })
1320 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
1321 self.window
1322 .rendered_frame
1323 .dispatch_tree
1324 .is_action_available(action, target)
1325 }
1326
1327 /// The position of the mouse relative to the window.
1328 pub fn mouse_position(&self) -> Point<Pixels> {
1329 self.window.mouse_position
1330 }
1331
1332 /// The current state of the keyboard's modifiers
1333 pub fn modifiers(&self) -> Modifiers {
1334 self.window.modifiers
1335 }
1336
1337 fn complete_frame(&self) {
1338 self.window.platform_window.completed_frame();
1339 }
1340
1341 /// Produces a new frame and assigns it to `rendered_frame`. To actually show
1342 /// the contents of the new [Scene], use [present].
1343 #[profiling::function]
1344 pub fn draw(&mut self) {
1345 self.window.dirty.set(false);
1346 self.window.requested_autoscroll = None;
1347
1348 // Restore the previously-used input handler.
1349 if let Some(input_handler) = self.window.platform_window.take_input_handler() {
1350 self.window
1351 .rendered_frame
1352 .input_handlers
1353 .push(Some(input_handler));
1354 }
1355
1356 self.draw_roots();
1357 self.window.dirty_views.clear();
1358
1359 self.window
1360 .next_frame
1361 .dispatch_tree
1362 .preserve_pending_keystrokes(
1363 &mut self.window.rendered_frame.dispatch_tree,
1364 self.window.focus,
1365 );
1366 self.window.next_frame.focus = self.window.focus;
1367 self.window.next_frame.window_active = self.window.active.get();
1368
1369 // Register requested input handler with the platform window.
1370 if let Some(input_handler) = self.window.next_frame.input_handlers.pop() {
1371 self.window
1372 .platform_window
1373 .set_input_handler(input_handler.unwrap());
1374 }
1375
1376 self.window.layout_engine.as_mut().unwrap().clear();
1377 self.text_system().finish_frame();
1378 self.window
1379 .next_frame
1380 .finish(&mut self.window.rendered_frame);
1381 ELEMENT_ARENA.with_borrow_mut(|element_arena| {
1382 let percentage = (element_arena.len() as f32 / element_arena.capacity() as f32) * 100.;
1383 if percentage >= 80. {
1384 log::warn!("elevated element arena occupation: {}.", percentage);
1385 }
1386 element_arena.clear();
1387 });
1388
1389 self.window.draw_phase = DrawPhase::Focus;
1390 let previous_focus_path = self.window.rendered_frame.focus_path();
1391 let previous_window_active = self.window.rendered_frame.window_active;
1392 mem::swap(&mut self.window.rendered_frame, &mut self.window.next_frame);
1393 self.window.next_frame.clear();
1394 let current_focus_path = self.window.rendered_frame.focus_path();
1395 let current_window_active = self.window.rendered_frame.window_active;
1396
1397 if previous_focus_path != current_focus_path
1398 || previous_window_active != current_window_active
1399 {
1400 if !previous_focus_path.is_empty() && current_focus_path.is_empty() {
1401 self.window
1402 .focus_lost_listeners
1403 .clone()
1404 .retain(&(), |listener| listener(self));
1405 }
1406
1407 let event = WindowFocusEvent {
1408 previous_focus_path: if previous_window_active {
1409 previous_focus_path
1410 } else {
1411 Default::default()
1412 },
1413 current_focus_path: if current_window_active {
1414 current_focus_path
1415 } else {
1416 Default::default()
1417 },
1418 };
1419 self.window
1420 .focus_listeners
1421 .clone()
1422 .retain(&(), |listener| listener(&event, self));
1423 }
1424
1425 self.reset_cursor_style();
1426 self.window.refreshing = false;
1427 self.window.draw_phase = DrawPhase::None;
1428 self.window.needs_present.set(true);
1429 }
1430
1431 #[profiling::function]
1432 fn present(&self) {
1433 self.window
1434 .platform_window
1435 .draw(&self.window.rendered_frame.scene);
1436 self.window.needs_present.set(false);
1437 profiling::finish_frame!();
1438 }
1439
1440 fn draw_roots(&mut self) {
1441 self.window.draw_phase = DrawPhase::Prepaint;
1442 self.window.tooltip_bounds.take();
1443
1444 // Layout all root elements.
1445 let mut root_element = self.window.root_view.as_ref().unwrap().clone().into_any();
1446 root_element.prepaint_as_root(Point::default(), self.window.viewport_size.into(), self);
1447
1448 let mut sorted_deferred_draws =
1449 (0..self.window.next_frame.deferred_draws.len()).collect::<SmallVec<[_; 8]>>();
1450 sorted_deferred_draws.sort_by_key(|ix| self.window.next_frame.deferred_draws[*ix].priority);
1451 self.prepaint_deferred_draws(&sorted_deferred_draws);
1452
1453 let mut prompt_element = None;
1454 let mut active_drag_element = None;
1455 let mut tooltip_element = None;
1456 if let Some(prompt) = self.window.prompt.take() {
1457 let mut element = prompt.view.any_view().into_any();
1458 element.prepaint_as_root(Point::default(), self.window.viewport_size.into(), self);
1459 prompt_element = Some(element);
1460 self.window.prompt = Some(prompt);
1461 } else if let Some(active_drag) = self.app.active_drag.take() {
1462 let mut element = active_drag.view.clone().into_any();
1463 let offset = self.mouse_position() - active_drag.cursor_offset;
1464 element.prepaint_as_root(offset, AvailableSpace::min_size(), self);
1465 active_drag_element = Some(element);
1466 self.app.active_drag = Some(active_drag);
1467 } else {
1468 tooltip_element = self.prepaint_tooltip();
1469 }
1470
1471 self.window.mouse_hit_test = self.window.next_frame.hit_test(self.window.mouse_position);
1472
1473 // Now actually paint the elements.
1474 self.window.draw_phase = DrawPhase::Paint;
1475 root_element.paint(self);
1476
1477 self.paint_deferred_draws(&sorted_deferred_draws);
1478
1479 if let Some(mut prompt_element) = prompt_element {
1480 prompt_element.paint(self)
1481 } else if let Some(mut drag_element) = active_drag_element {
1482 drag_element.paint(self);
1483 } else if let Some(mut tooltip_element) = tooltip_element {
1484 tooltip_element.paint(self);
1485 }
1486 }
1487
1488 fn prepaint_tooltip(&mut self) -> Option<AnyElement> {
1489 let tooltip_request = self.window.next_frame.tooltip_requests.last().cloned()?;
1490 let tooltip_request = tooltip_request.unwrap();
1491 let mut element = tooltip_request.tooltip.view.clone().into_any();
1492 let mouse_position = tooltip_request.tooltip.mouse_position;
1493 let tooltip_size = element.layout_as_root(AvailableSpace::min_size(), self);
1494
1495 let mut tooltip_bounds = Bounds::new(mouse_position + point(px(1.), px(1.)), tooltip_size);
1496 let window_bounds = Bounds {
1497 origin: Point::default(),
1498 size: self.viewport_size(),
1499 };
1500
1501 if tooltip_bounds.right() > window_bounds.right() {
1502 let new_x = mouse_position.x - tooltip_bounds.size.width - px(1.);
1503 if new_x >= Pixels::ZERO {
1504 tooltip_bounds.origin.x = new_x;
1505 } else {
1506 tooltip_bounds.origin.x = cmp::max(
1507 Pixels::ZERO,
1508 tooltip_bounds.origin.x - tooltip_bounds.right() - window_bounds.right(),
1509 );
1510 }
1511 }
1512
1513 if tooltip_bounds.bottom() > window_bounds.bottom() {
1514 let new_y = mouse_position.y - tooltip_bounds.size.height - px(1.);
1515 if new_y >= Pixels::ZERO {
1516 tooltip_bounds.origin.y = new_y;
1517 } else {
1518 tooltip_bounds.origin.y = cmp::max(
1519 Pixels::ZERO,
1520 tooltip_bounds.origin.y - tooltip_bounds.bottom() - window_bounds.bottom(),
1521 );
1522 }
1523 }
1524
1525 self.with_absolute_element_offset(tooltip_bounds.origin, |cx| element.prepaint(cx));
1526
1527 self.window.tooltip_bounds = Some(TooltipBounds {
1528 id: tooltip_request.id,
1529 bounds: tooltip_bounds,
1530 });
1531 Some(element)
1532 }
1533
1534 fn prepaint_deferred_draws(&mut self, deferred_draw_indices: &[usize]) {
1535 assert_eq!(self.window.element_id_stack.len(), 0);
1536
1537 let mut deferred_draws = mem::take(&mut self.window.next_frame.deferred_draws);
1538 for deferred_draw_ix in deferred_draw_indices {
1539 let deferred_draw = &mut deferred_draws[*deferred_draw_ix];
1540 self.window
1541 .element_id_stack
1542 .clone_from(&deferred_draw.element_id_stack);
1543 self.window
1544 .text_style_stack
1545 .clone_from(&deferred_draw.text_style_stack);
1546 self.window
1547 .next_frame
1548 .dispatch_tree
1549 .set_active_node(deferred_draw.parent_node);
1550
1551 let prepaint_start = self.prepaint_index();
1552 if let Some(element) = deferred_draw.element.as_mut() {
1553 self.with_absolute_element_offset(deferred_draw.absolute_offset, |cx| {
1554 element.prepaint(cx)
1555 });
1556 } else {
1557 self.reuse_prepaint(deferred_draw.prepaint_range.clone());
1558 }
1559 let prepaint_end = self.prepaint_index();
1560 deferred_draw.prepaint_range = prepaint_start..prepaint_end;
1561 }
1562 assert_eq!(
1563 self.window.next_frame.deferred_draws.len(),
1564 0,
1565 "cannot call defer_draw during deferred drawing"
1566 );
1567 self.window.next_frame.deferred_draws = deferred_draws;
1568 self.window.element_id_stack.clear();
1569 self.window.text_style_stack.clear();
1570 }
1571
1572 fn paint_deferred_draws(&mut self, deferred_draw_indices: &[usize]) {
1573 assert_eq!(self.window.element_id_stack.len(), 0);
1574
1575 let mut deferred_draws = mem::take(&mut self.window.next_frame.deferred_draws);
1576 for deferred_draw_ix in deferred_draw_indices {
1577 let mut deferred_draw = &mut deferred_draws[*deferred_draw_ix];
1578 self.window
1579 .element_id_stack
1580 .clone_from(&deferred_draw.element_id_stack);
1581 self.window
1582 .next_frame
1583 .dispatch_tree
1584 .set_active_node(deferred_draw.parent_node);
1585
1586 let paint_start = self.paint_index();
1587 if let Some(element) = deferred_draw.element.as_mut() {
1588 element.paint(self);
1589 } else {
1590 self.reuse_paint(deferred_draw.paint_range.clone());
1591 }
1592 let paint_end = self.paint_index();
1593 deferred_draw.paint_range = paint_start..paint_end;
1594 }
1595 self.window.next_frame.deferred_draws = deferred_draws;
1596 self.window.element_id_stack.clear();
1597 }
1598
1599 pub(crate) fn prepaint_index(&self) -> PrepaintStateIndex {
1600 PrepaintStateIndex {
1601 hitboxes_index: self.window.next_frame.hitboxes.len(),
1602 tooltips_index: self.window.next_frame.tooltip_requests.len(),
1603 deferred_draws_index: self.window.next_frame.deferred_draws.len(),
1604 dispatch_tree_index: self.window.next_frame.dispatch_tree.len(),
1605 accessed_element_states_index: self.window.next_frame.accessed_element_states.len(),
1606 line_layout_index: self.window.text_system.layout_index(),
1607 }
1608 }
1609
1610 pub(crate) fn reuse_prepaint(&mut self, range: Range<PrepaintStateIndex>) {
1611 let window = &mut self.window;
1612 window.next_frame.hitboxes.extend(
1613 window.rendered_frame.hitboxes[range.start.hitboxes_index..range.end.hitboxes_index]
1614 .iter()
1615 .cloned(),
1616 );
1617 window.next_frame.tooltip_requests.extend(
1618 window.rendered_frame.tooltip_requests
1619 [range.start.tooltips_index..range.end.tooltips_index]
1620 .iter_mut()
1621 .map(|request| request.take()),
1622 );
1623 window.next_frame.accessed_element_states.extend(
1624 window.rendered_frame.accessed_element_states[range.start.accessed_element_states_index
1625 ..range.end.accessed_element_states_index]
1626 .iter()
1627 .map(|(id, type_id)| (GlobalElementId(id.0.clone()), *type_id)),
1628 );
1629 window
1630 .text_system
1631 .reuse_layouts(range.start.line_layout_index..range.end.line_layout_index);
1632
1633 let reused_subtree = window.next_frame.dispatch_tree.reuse_subtree(
1634 range.start.dispatch_tree_index..range.end.dispatch_tree_index,
1635 &mut window.rendered_frame.dispatch_tree,
1636 );
1637 window.next_frame.deferred_draws.extend(
1638 window.rendered_frame.deferred_draws
1639 [range.start.deferred_draws_index..range.end.deferred_draws_index]
1640 .iter()
1641 .map(|deferred_draw| DeferredDraw {
1642 parent_node: reused_subtree.refresh_node_id(deferred_draw.parent_node),
1643 element_id_stack: deferred_draw.element_id_stack.clone(),
1644 text_style_stack: deferred_draw.text_style_stack.clone(),
1645 priority: deferred_draw.priority,
1646 element: None,
1647 absolute_offset: deferred_draw.absolute_offset,
1648 prepaint_range: deferred_draw.prepaint_range.clone(),
1649 paint_range: deferred_draw.paint_range.clone(),
1650 }),
1651 );
1652 }
1653
1654 pub(crate) fn paint_index(&self) -> PaintIndex {
1655 PaintIndex {
1656 scene_index: self.window.next_frame.scene.len(),
1657 mouse_listeners_index: self.window.next_frame.mouse_listeners.len(),
1658 input_handlers_index: self.window.next_frame.input_handlers.len(),
1659 cursor_styles_index: self.window.next_frame.cursor_styles.len(),
1660 accessed_element_states_index: self.window.next_frame.accessed_element_states.len(),
1661 line_layout_index: self.window.text_system.layout_index(),
1662 }
1663 }
1664
1665 pub(crate) fn reuse_paint(&mut self, range: Range<PaintIndex>) {
1666 let window = &mut self.window;
1667
1668 window.next_frame.cursor_styles.extend(
1669 window.rendered_frame.cursor_styles
1670 [range.start.cursor_styles_index..range.end.cursor_styles_index]
1671 .iter()
1672 .cloned(),
1673 );
1674 window.next_frame.input_handlers.extend(
1675 window.rendered_frame.input_handlers
1676 [range.start.input_handlers_index..range.end.input_handlers_index]
1677 .iter_mut()
1678 .map(|handler| handler.take()),
1679 );
1680 window.next_frame.mouse_listeners.extend(
1681 window.rendered_frame.mouse_listeners
1682 [range.start.mouse_listeners_index..range.end.mouse_listeners_index]
1683 .iter_mut()
1684 .map(|listener| listener.take()),
1685 );
1686 window.next_frame.accessed_element_states.extend(
1687 window.rendered_frame.accessed_element_states[range.start.accessed_element_states_index
1688 ..range.end.accessed_element_states_index]
1689 .iter()
1690 .map(|(id, type_id)| (GlobalElementId(id.0.clone()), *type_id)),
1691 );
1692 window
1693 .text_system
1694 .reuse_layouts(range.start.line_layout_index..range.end.line_layout_index);
1695 window.next_frame.scene.replay(
1696 range.start.scene_index..range.end.scene_index,
1697 &window.rendered_frame.scene,
1698 );
1699 }
1700
1701 /// Push a text style onto the stack, and call a function with that style active.
1702 /// Use [`AppContext::text_style`] to get the current, combined text style. This method
1703 /// should only be called as part of element drawing.
1704 pub fn with_text_style<F, R>(&mut self, style: Option<TextStyleRefinement>, f: F) -> R
1705 where
1706 F: FnOnce(&mut Self) -> R,
1707 {
1708 debug_assert!(
1709 matches!(
1710 self.window.draw_phase,
1711 DrawPhase::Prepaint | DrawPhase::Paint
1712 ),
1713 "this method can only be called during request_layout, prepaint, or paint"
1714 );
1715 if let Some(style) = style {
1716 self.window.text_style_stack.push(style);
1717 let result = f(self);
1718 self.window.text_style_stack.pop();
1719 result
1720 } else {
1721 f(self)
1722 }
1723 }
1724
1725 /// Updates the cursor style at the platform level. This method should only be called
1726 /// during the prepaint phase of element drawing.
1727 pub fn set_cursor_style(&mut self, style: CursorStyle, hitbox: &Hitbox) {
1728 debug_assert_eq!(
1729 self.window.draw_phase,
1730 DrawPhase::Paint,
1731 "this method can only be called during paint"
1732 );
1733 self.window
1734 .next_frame
1735 .cursor_styles
1736 .push(CursorStyleRequest {
1737 hitbox_id: hitbox.id,
1738 style,
1739 });
1740 }
1741
1742 /// Sets a tooltip to be rendered for the upcoming frame. This method should only be called
1743 /// during the paint phase of element drawing.
1744 pub fn set_tooltip(&mut self, tooltip: AnyTooltip) -> TooltipId {
1745 debug_assert_eq!(
1746 self.window.draw_phase,
1747 DrawPhase::Prepaint,
1748 "this method can only be called during prepaint"
1749 );
1750 let id = TooltipId(post_inc(&mut self.window.next_tooltip_id.0));
1751 self.window
1752 .next_frame
1753 .tooltip_requests
1754 .push(Some(TooltipRequest { id, tooltip }));
1755 id
1756 }
1757
1758 /// Invoke the given function with the given content mask after intersecting it
1759 /// with the current mask. This method should only be called during element drawing.
1760 pub fn with_content_mask<R>(
1761 &mut self,
1762 mask: Option<ContentMask<Pixels>>,
1763 f: impl FnOnce(&mut Self) -> R,
1764 ) -> R {
1765 debug_assert!(
1766 matches!(
1767 self.window.draw_phase,
1768 DrawPhase::Prepaint | DrawPhase::Paint
1769 ),
1770 "this method can only be called during request_layout, prepaint, or paint"
1771 );
1772 if let Some(mask) = mask {
1773 let mask = mask.intersect(&self.content_mask());
1774 self.window_mut().content_mask_stack.push(mask);
1775 let result = f(self);
1776 self.window_mut().content_mask_stack.pop();
1777 result
1778 } else {
1779 f(self)
1780 }
1781 }
1782
1783 /// Updates the global element offset relative to the current offset. This is used to implement
1784 /// scrolling. This method should only be called during the prepaint phase of element drawing.
1785 pub fn with_element_offset<R>(
1786 &mut self,
1787 offset: Point<Pixels>,
1788 f: impl FnOnce(&mut Self) -> R,
1789 ) -> R {
1790 debug_assert_eq!(
1791 self.window.draw_phase,
1792 DrawPhase::Prepaint,
1793 "this method can only be called during request_layout, or prepaint"
1794 );
1795
1796 if offset.is_zero() {
1797 return f(self);
1798 };
1799
1800 let abs_offset = self.element_offset() + offset;
1801 self.with_absolute_element_offset(abs_offset, f)
1802 }
1803
1804 /// Updates the global element offset based on the given offset. This is used to implement
1805 /// drag handles and other manual painting of elements. This method should only be called during
1806 /// the prepaint phase of element drawing.
1807 pub fn with_absolute_element_offset<R>(
1808 &mut self,
1809 offset: Point<Pixels>,
1810 f: impl FnOnce(&mut Self) -> R,
1811 ) -> R {
1812 debug_assert_eq!(
1813 self.window.draw_phase,
1814 DrawPhase::Prepaint,
1815 "this method can only be called during request_layout, or prepaint"
1816 );
1817 self.window_mut().element_offset_stack.push(offset);
1818 let result = f(self);
1819 self.window_mut().element_offset_stack.pop();
1820 result
1821 }
1822
1823 /// Perform prepaint on child elements in a "retryable" manner, so that any side effects
1824 /// of prepaints can be discarded before prepainting again. This is used to support autoscroll
1825 /// where we need to prepaint children to detect the autoscroll bounds, then adjust the
1826 /// element offset and prepaint again. See [`List`] for an example. This method should only be
1827 /// called during the prepaint phase of element drawing.
1828 pub fn transact<T, U>(&mut self, f: impl FnOnce(&mut Self) -> Result<T, U>) -> Result<T, U> {
1829 debug_assert_eq!(
1830 self.window.draw_phase,
1831 DrawPhase::Prepaint,
1832 "this method can only be called during prepaint"
1833 );
1834 let index = self.prepaint_index();
1835 let result = f(self);
1836 if result.is_err() {
1837 self.window
1838 .next_frame
1839 .hitboxes
1840 .truncate(index.hitboxes_index);
1841 self.window
1842 .next_frame
1843 .tooltip_requests
1844 .truncate(index.tooltips_index);
1845 self.window
1846 .next_frame
1847 .deferred_draws
1848 .truncate(index.deferred_draws_index);
1849 self.window
1850 .next_frame
1851 .dispatch_tree
1852 .truncate(index.dispatch_tree_index);
1853 self.window
1854 .next_frame
1855 .accessed_element_states
1856 .truncate(index.accessed_element_states_index);
1857 self.window
1858 .text_system
1859 .truncate_layouts(index.line_layout_index);
1860 }
1861 result
1862 }
1863
1864 /// When you call this method during [`prepaint`], containing elements will attempt to
1865 /// scroll to cause the specified bounds to become visible. When they decide to autoscroll, they will call
1866 /// [`prepaint`] again with a new set of bounds. See [`List`] for an example of an element
1867 /// that supports this method being called on the elements it contains. This method should only be
1868 /// called during the prepaint phase of element drawing.
1869 pub fn request_autoscroll(&mut self, bounds: Bounds<Pixels>) {
1870 debug_assert_eq!(
1871 self.window.draw_phase,
1872 DrawPhase::Prepaint,
1873 "this method can only be called during prepaint"
1874 );
1875 self.window.requested_autoscroll = Some(bounds);
1876 }
1877
1878 /// This method can be called from a containing element such as [`List`] to support the autoscroll behavior
1879 /// described in [`request_autoscroll`].
1880 pub fn take_autoscroll(&mut self) -> Option<Bounds<Pixels>> {
1881 debug_assert_eq!(
1882 self.window.draw_phase,
1883 DrawPhase::Prepaint,
1884 "this method can only be called during prepaint"
1885 );
1886 self.window.requested_autoscroll.take()
1887 }
1888
1889 /// Remove an asset from GPUI's cache
1890 pub fn remove_cached_asset<A: Asset + 'static>(
1891 &mut self,
1892 source: &A::Source,
1893 ) -> Option<A::Output> {
1894 self.asset_cache.remove::<A>(source)
1895 }
1896
1897 /// Asynchronously load an asset, if the asset hasn't finished loading this will return None.
1898 /// Your view will be re-drawn once the asset has finished loading.
1899 ///
1900 /// Note that the multiple calls to this method will only result in one `Asset::load` call.
1901 /// The results of that call will be cached, and returned on subsequent uses of this API.
1902 ///
1903 /// Use [Self::remove_cached_asset] to reload your asset.
1904 pub fn use_cached_asset<A: Asset + 'static>(
1905 &mut self,
1906 source: &A::Source,
1907 ) -> Option<A::Output> {
1908 self.asset_cache.get::<A>(source).or_else(|| {
1909 if let Some(asset) = self.use_asset::<A>(source) {
1910 self.asset_cache
1911 .insert::<A>(source.to_owned(), asset.clone());
1912 Some(asset)
1913 } else {
1914 None
1915 }
1916 })
1917 }
1918
1919 /// Asynchronously load an asset, if the asset hasn't finished loading this will return None.
1920 /// Your view will be re-drawn once the asset has finished loading.
1921 ///
1922 /// Note that the multiple calls to this method will only result in one `Asset::load` call at a
1923 /// time.
1924 ///
1925 /// This asset will not be cached by default, see [Self::use_cached_asset]
1926 pub fn use_asset<A: Asset + 'static>(&mut self, source: &A::Source) -> Option<A::Output> {
1927 let asset_id = (TypeId::of::<A>(), hash(source));
1928 let mut is_first = false;
1929 let task = self
1930 .loading_assets
1931 .remove(&asset_id)
1932 .map(|boxed_task| *boxed_task.downcast::<Shared<Task<A::Output>>>().unwrap())
1933 .unwrap_or_else(|| {
1934 is_first = true;
1935 let future = A::load(source.clone(), self);
1936 let task = self.background_executor().spawn(future).shared();
1937 task
1938 });
1939
1940 task.clone().now_or_never().or_else(|| {
1941 if is_first {
1942 let parent_id = self.parent_view_id();
1943 self.spawn({
1944 let task = task.clone();
1945 |mut cx| async move {
1946 task.await;
1947
1948 cx.on_next_frame(move |cx| {
1949 if let Some(parent_id) = parent_id {
1950 cx.notify(parent_id)
1951 } else {
1952 cx.refresh()
1953 }
1954 });
1955 }
1956 })
1957 .detach();
1958 }
1959
1960 self.loading_assets.insert(asset_id, Box::new(task));
1961
1962 None
1963 })
1964 }
1965
1966 /// Obtain the current element offset. This method should only be called during the
1967 /// prepaint phase of element drawing.
1968 pub fn element_offset(&self) -> Point<Pixels> {
1969 debug_assert_eq!(
1970 self.window.draw_phase,
1971 DrawPhase::Prepaint,
1972 "this method can only be called during prepaint"
1973 );
1974 self.window()
1975 .element_offset_stack
1976 .last()
1977 .copied()
1978 .unwrap_or_default()
1979 }
1980
1981 /// Obtain the current content mask. This method should only be called during element drawing.
1982 pub fn content_mask(&self) -> ContentMask<Pixels> {
1983 debug_assert!(
1984 matches!(
1985 self.window.draw_phase,
1986 DrawPhase::Prepaint | DrawPhase::Paint
1987 ),
1988 "this method can only be called during prepaint, or paint"
1989 );
1990 self.window()
1991 .content_mask_stack
1992 .last()
1993 .cloned()
1994 .unwrap_or_else(|| ContentMask {
1995 bounds: Bounds {
1996 origin: Point::default(),
1997 size: self.window().viewport_size,
1998 },
1999 })
2000 }
2001
2002 /// Provide elements in the called function with a new namespace in which their identiers must be unique.
2003 /// This can be used within a custom element to distinguish multiple sets of child elements.
2004 pub fn with_element_namespace<R>(
2005 &mut self,
2006 element_id: impl Into<ElementId>,
2007 f: impl FnOnce(&mut Self) -> R,
2008 ) -> R {
2009 self.window.element_id_stack.push(element_id.into());
2010 let result = f(self);
2011 self.window.element_id_stack.pop();
2012 result
2013 }
2014
2015 /// Updates or initializes state for an element with the given id that lives across multiple
2016 /// frames. If an element with this ID existed in the rendered frame, its state will be passed
2017 /// to the given closure. The state returned by the closure will be stored so it can be referenced
2018 /// when drawing the next frame. This method should only be called as part of element drawing.
2019 pub fn with_element_state<S, R>(
2020 &mut self,
2021 global_id: &GlobalElementId,
2022 f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
2023 ) -> R
2024 where
2025 S: 'static,
2026 {
2027 debug_assert!(
2028 matches!(
2029 self.window.draw_phase,
2030 DrawPhase::Prepaint | DrawPhase::Paint
2031 ),
2032 "this method can only be called during request_layout, prepaint, or paint"
2033 );
2034
2035 let key = (GlobalElementId(global_id.0.clone()), TypeId::of::<S>());
2036 self.window
2037 .next_frame
2038 .accessed_element_states
2039 .push((GlobalElementId(key.0.clone()), TypeId::of::<S>()));
2040
2041 if let Some(any) = self
2042 .window
2043 .next_frame
2044 .element_states
2045 .remove(&key)
2046 .or_else(|| self.window.rendered_frame.element_states.remove(&key))
2047 {
2048 let ElementStateBox {
2049 inner,
2050 #[cfg(debug_assertions)]
2051 type_name,
2052 } = any;
2053 // Using the extra inner option to avoid needing to reallocate a new box.
2054 let mut state_box = inner
2055 .downcast::<Option<S>>()
2056 .map_err(|_| {
2057 #[cfg(debug_assertions)]
2058 {
2059 anyhow::anyhow!(
2060 "invalid element state type for id, requested {:?}, actual: {:?}",
2061 std::any::type_name::<S>(),
2062 type_name
2063 )
2064 }
2065
2066 #[cfg(not(debug_assertions))]
2067 {
2068 anyhow::anyhow!(
2069 "invalid element state type for id, requested {:?}",
2070 std::any::type_name::<S>(),
2071 )
2072 }
2073 })
2074 .unwrap();
2075
2076 let state = state_box.take().expect(
2077 "reentrant call to with_element_state for the same state type and element id",
2078 );
2079 let (result, state) = f(Some(state), self);
2080 state_box.replace(state);
2081 self.window.next_frame.element_states.insert(
2082 key,
2083 ElementStateBox {
2084 inner: state_box,
2085 #[cfg(debug_assertions)]
2086 type_name,
2087 },
2088 );
2089 result
2090 } else {
2091 let (result, state) = f(None, self);
2092 self.window.next_frame.element_states.insert(
2093 key,
2094 ElementStateBox {
2095 inner: Box::new(Some(state)),
2096 #[cfg(debug_assertions)]
2097 type_name: std::any::type_name::<S>(),
2098 },
2099 );
2100 result
2101 }
2102 }
2103
2104 /// A variant of `with_element_state` that allows the element's id to be optional. This is a convenience
2105 /// method for elements where the element id may or may not be assigned. Prefer using `with_element_state`
2106 /// when the element is guaranteed to have an id.
2107 pub fn with_optional_element_state<S, R>(
2108 &mut self,
2109 global_id: Option<&GlobalElementId>,
2110 f: impl FnOnce(Option<Option<S>>, &mut Self) -> (R, Option<S>),
2111 ) -> R
2112 where
2113 S: 'static,
2114 {
2115 debug_assert!(
2116 matches!(
2117 self.window.draw_phase,
2118 DrawPhase::Prepaint | DrawPhase::Paint
2119 ),
2120 "this method can only be called during request_layout, prepaint, or paint"
2121 );
2122
2123 if let Some(global_id) = global_id {
2124 self.with_element_state(global_id, |state, cx| {
2125 let (result, state) = f(Some(state), cx);
2126 let state =
2127 state.expect("you must return some state when you pass some element id");
2128 (result, state)
2129 })
2130 } else {
2131 let (result, state) = f(None, self);
2132 debug_assert!(
2133 state.is_none(),
2134 "you must not return an element state when passing None for the global id"
2135 );
2136 result
2137 }
2138 }
2139
2140 /// Defers the drawing of the given element, scheduling it to be painted on top of the currently-drawn tree
2141 /// at a later time. The `priority` parameter determines the drawing order relative to other deferred elements,
2142 /// with higher values being drawn on top.
2143 ///
2144 /// This method should only be called as part of the prepaint phase of element drawing.
2145 pub fn defer_draw(
2146 &mut self,
2147 element: AnyElement,
2148 absolute_offset: Point<Pixels>,
2149 priority: usize,
2150 ) {
2151 let window = &mut self.window;
2152 debug_assert_eq!(
2153 window.draw_phase,
2154 DrawPhase::Prepaint,
2155 "this method can only be called during request_layout or prepaint"
2156 );
2157 let parent_node = window.next_frame.dispatch_tree.active_node_id().unwrap();
2158 window.next_frame.deferred_draws.push(DeferredDraw {
2159 parent_node,
2160 element_id_stack: window.element_id_stack.clone(),
2161 text_style_stack: window.text_style_stack.clone(),
2162 priority,
2163 element: Some(element),
2164 absolute_offset,
2165 prepaint_range: PrepaintStateIndex::default()..PrepaintStateIndex::default(),
2166 paint_range: PaintIndex::default()..PaintIndex::default(),
2167 });
2168 }
2169
2170 /// Creates a new painting layer for the specified bounds. A "layer" is a batch
2171 /// of geometry that are non-overlapping and have the same draw order. This is typically used
2172 /// for performance reasons.
2173 ///
2174 /// This method should only be called as part of the paint phase of element drawing.
2175 pub fn paint_layer<R>(&mut self, bounds: Bounds<Pixels>, f: impl FnOnce(&mut Self) -> R) -> R {
2176 debug_assert_eq!(
2177 self.window.draw_phase,
2178 DrawPhase::Paint,
2179 "this method can only be called during paint"
2180 );
2181
2182 let scale_factor = self.scale_factor();
2183 let content_mask = self.content_mask();
2184 let clipped_bounds = bounds.intersect(&content_mask.bounds);
2185 if !clipped_bounds.is_empty() {
2186 self.window
2187 .next_frame
2188 .scene
2189 .push_layer(clipped_bounds.scale(scale_factor));
2190 }
2191
2192 let result = f(self);
2193
2194 if !clipped_bounds.is_empty() {
2195 self.window.next_frame.scene.pop_layer();
2196 }
2197
2198 result
2199 }
2200
2201 /// Paint one or more drop shadows into the scene for the next frame at the current z-index.
2202 ///
2203 /// This method should only be called as part of the paint phase of element drawing.
2204 pub fn paint_shadows(
2205 &mut self,
2206 bounds: Bounds<Pixels>,
2207 corner_radii: Corners<Pixels>,
2208 shadows: &[BoxShadow],
2209 ) {
2210 debug_assert_eq!(
2211 self.window.draw_phase,
2212 DrawPhase::Paint,
2213 "this method can only be called during paint"
2214 );
2215
2216 let scale_factor = self.scale_factor();
2217 let content_mask = self.content_mask();
2218 for shadow in shadows {
2219 let mut shadow_bounds = bounds;
2220 shadow_bounds.origin += shadow.offset;
2221 shadow_bounds.dilate(shadow.spread_radius);
2222 self.window.next_frame.scene.insert_primitive(Shadow {
2223 order: 0,
2224 blur_radius: shadow.blur_radius.scale(scale_factor),
2225 bounds: shadow_bounds.scale(scale_factor),
2226 content_mask: content_mask.scale(scale_factor),
2227 corner_radii: corner_radii.scale(scale_factor),
2228 color: shadow.color,
2229 });
2230 }
2231 }
2232
2233 /// Paint one or more quads into the scene for the next frame at the current stacking context.
2234 /// Quads are colored rectangular regions with an optional background, border, and corner radius.
2235 /// see [`fill`](crate::fill), [`outline`](crate::outline), and [`quad`](crate::quad) to construct this type.
2236 ///
2237 /// This method should only be called as part of the paint phase of element drawing.
2238 pub fn paint_quad(&mut self, quad: PaintQuad) {
2239 debug_assert_eq!(
2240 self.window.draw_phase,
2241 DrawPhase::Paint,
2242 "this method can only be called during paint"
2243 );
2244
2245 let scale_factor = self.scale_factor();
2246 let content_mask = self.content_mask();
2247 self.window.next_frame.scene.insert_primitive(Quad {
2248 order: 0,
2249 pad: 0,
2250 bounds: quad.bounds.scale(scale_factor),
2251 content_mask: content_mask.scale(scale_factor),
2252 background: quad.background,
2253 border_color: quad.border_color,
2254 corner_radii: quad.corner_radii.scale(scale_factor),
2255 border_widths: quad.border_widths.scale(scale_factor),
2256 });
2257 }
2258
2259 /// Paint the given `Path` into the scene for the next frame at the current z-index.
2260 ///
2261 /// This method should only be called as part of the paint phase of element drawing.
2262 pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Hsla>) {
2263 debug_assert_eq!(
2264 self.window.draw_phase,
2265 DrawPhase::Paint,
2266 "this method can only be called during paint"
2267 );
2268
2269 let scale_factor = self.scale_factor();
2270 let content_mask = self.content_mask();
2271 path.content_mask = content_mask;
2272 path.color = color.into();
2273 self.window
2274 .next_frame
2275 .scene
2276 .insert_primitive(path.scale(scale_factor));
2277 }
2278
2279 /// Paint an underline into the scene for the next frame at the current z-index.
2280 ///
2281 /// This method should only be called as part of the paint phase of element drawing.
2282 pub fn paint_underline(
2283 &mut self,
2284 origin: Point<Pixels>,
2285 width: Pixels,
2286 style: &UnderlineStyle,
2287 ) {
2288 debug_assert_eq!(
2289 self.window.draw_phase,
2290 DrawPhase::Paint,
2291 "this method can only be called during paint"
2292 );
2293
2294 let scale_factor = self.scale_factor();
2295 let height = if style.wavy {
2296 style.thickness * 3.
2297 } else {
2298 style.thickness
2299 };
2300 let bounds = Bounds {
2301 origin,
2302 size: size(width, height),
2303 };
2304 let content_mask = self.content_mask();
2305
2306 self.window.next_frame.scene.insert_primitive(Underline {
2307 order: 0,
2308 pad: 0,
2309 bounds: bounds.scale(scale_factor),
2310 content_mask: content_mask.scale(scale_factor),
2311 color: style.color.unwrap_or_default(),
2312 thickness: style.thickness.scale(scale_factor),
2313 wavy: style.wavy,
2314 });
2315 }
2316
2317 /// Paint a strikethrough into the scene for the next frame at the current z-index.
2318 ///
2319 /// This method should only be called as part of the paint phase of element drawing.
2320 pub fn paint_strikethrough(
2321 &mut self,
2322 origin: Point<Pixels>,
2323 width: Pixels,
2324 style: &StrikethroughStyle,
2325 ) {
2326 debug_assert_eq!(
2327 self.window.draw_phase,
2328 DrawPhase::Paint,
2329 "this method can only be called during paint"
2330 );
2331
2332 let scale_factor = self.scale_factor();
2333 let height = style.thickness;
2334 let bounds = Bounds {
2335 origin,
2336 size: size(width, height),
2337 };
2338 let content_mask = self.content_mask();
2339
2340 self.window.next_frame.scene.insert_primitive(Underline {
2341 order: 0,
2342 pad: 0,
2343 bounds: bounds.scale(scale_factor),
2344 content_mask: content_mask.scale(scale_factor),
2345 thickness: style.thickness.scale(scale_factor),
2346 color: style.color.unwrap_or_default(),
2347 wavy: false,
2348 });
2349 }
2350
2351 /// Paints a monochrome (non-emoji) glyph into the scene for the next frame at the current z-index.
2352 ///
2353 /// The y component of the origin is the baseline of the glyph.
2354 /// You should generally prefer to use the [`ShapedLine::paint`](crate::ShapedLine::paint) or
2355 /// [`WrappedLine::paint`](crate::WrappedLine::paint) methods in the [`TextSystem`](crate::TextSystem).
2356 /// This method is only useful if you need to paint a single glyph that has already been shaped.
2357 ///
2358 /// This method should only be called as part of the paint phase of element drawing.
2359 pub fn paint_glyph(
2360 &mut self,
2361 origin: Point<Pixels>,
2362 font_id: FontId,
2363 glyph_id: GlyphId,
2364 font_size: Pixels,
2365 color: Hsla,
2366 ) -> Result<()> {
2367 debug_assert_eq!(
2368 self.window.draw_phase,
2369 DrawPhase::Paint,
2370 "this method can only be called during paint"
2371 );
2372
2373 let scale_factor = self.scale_factor();
2374 let glyph_origin = origin.scale(scale_factor);
2375 let subpixel_variant = Point {
2376 x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
2377 y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
2378 };
2379 let params = RenderGlyphParams {
2380 font_id,
2381 glyph_id,
2382 font_size,
2383 subpixel_variant,
2384 scale_factor,
2385 is_emoji: false,
2386 };
2387
2388 let raster_bounds = self.text_system().raster_bounds(¶ms)?;
2389 if !raster_bounds.is_zero() {
2390 let tile = self
2391 .window
2392 .sprite_atlas
2393 .get_or_insert_with(¶ms.clone().into(), &mut || {
2394 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
2395 Ok(Some((size, Cow::Owned(bytes))))
2396 })?
2397 .expect("Callback above only errors or returns Some");
2398 let bounds = Bounds {
2399 origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
2400 size: tile.bounds.size.map(Into::into),
2401 };
2402 let content_mask = self.content_mask().scale(scale_factor);
2403 self.window
2404 .next_frame
2405 .scene
2406 .insert_primitive(MonochromeSprite {
2407 order: 0,
2408 pad: 0,
2409 bounds,
2410 content_mask,
2411 color,
2412 tile,
2413 transformation: TransformationMatrix::unit(),
2414 });
2415 }
2416 Ok(())
2417 }
2418
2419 /// Paints an emoji glyph into the scene for the next frame at the current z-index.
2420 ///
2421 /// The y component of the origin is the baseline of the glyph.
2422 /// You should generally prefer to use the [`ShapedLine::paint`](crate::ShapedLine::paint) or
2423 /// [`WrappedLine::paint`](crate::WrappedLine::paint) methods in the [`TextSystem`](crate::TextSystem).
2424 /// This method is only useful if you need to paint a single emoji that has already been shaped.
2425 ///
2426 /// This method should only be called as part of the paint phase of element drawing.
2427 pub fn paint_emoji(
2428 &mut self,
2429 origin: Point<Pixels>,
2430 font_id: FontId,
2431 glyph_id: GlyphId,
2432 font_size: Pixels,
2433 ) -> Result<()> {
2434 debug_assert_eq!(
2435 self.window.draw_phase,
2436 DrawPhase::Paint,
2437 "this method can only be called during paint"
2438 );
2439
2440 let scale_factor = self.scale_factor();
2441 let glyph_origin = origin.scale(scale_factor);
2442 let params = RenderGlyphParams {
2443 font_id,
2444 glyph_id,
2445 font_size,
2446 // We don't render emojis with subpixel variants.
2447 subpixel_variant: Default::default(),
2448 scale_factor,
2449 is_emoji: true,
2450 };
2451
2452 let raster_bounds = self.text_system().raster_bounds(¶ms)?;
2453 if !raster_bounds.is_zero() {
2454 let tile = self
2455 .window
2456 .sprite_atlas
2457 .get_or_insert_with(¶ms.clone().into(), &mut || {
2458 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
2459 Ok(Some((size, Cow::Owned(bytes))))
2460 })?
2461 .expect("Callback above only errors or returns Some");
2462
2463 let bounds = Bounds {
2464 origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
2465 size: tile.bounds.size.map(Into::into),
2466 };
2467 let content_mask = self.content_mask().scale(scale_factor);
2468
2469 self.window
2470 .next_frame
2471 .scene
2472 .insert_primitive(PolychromeSprite {
2473 order: 0,
2474 grayscale: false,
2475 bounds,
2476 corner_radii: Default::default(),
2477 content_mask,
2478 tile,
2479 });
2480 }
2481 Ok(())
2482 }
2483
2484 /// Paint a monochrome SVG into the scene for the next frame at the current stacking context.
2485 ///
2486 /// This method should only be called as part of the paint phase of element drawing.
2487 pub fn paint_svg(
2488 &mut self,
2489 bounds: Bounds<Pixels>,
2490 path: SharedString,
2491 transformation: TransformationMatrix,
2492 color: Hsla,
2493 ) -> Result<()> {
2494 debug_assert_eq!(
2495 self.window.draw_phase,
2496 DrawPhase::Paint,
2497 "this method can only be called during paint"
2498 );
2499
2500 let scale_factor = self.scale_factor();
2501 let bounds = bounds.scale(scale_factor);
2502 // Render the SVG at twice the size to get a higher quality result.
2503 let params = RenderSvgParams {
2504 path,
2505 size: bounds
2506 .size
2507 .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
2508 };
2509
2510 let Some(tile) =
2511 self.window
2512 .sprite_atlas
2513 .get_or_insert_with(¶ms.clone().into(), &mut || {
2514 let Some(bytes) = self.svg_renderer.render(¶ms)? else {
2515 return Ok(None);
2516 };
2517 Ok(Some((params.size, Cow::Owned(bytes))))
2518 })?
2519 else {
2520 return Ok(());
2521 };
2522 let content_mask = self.content_mask().scale(scale_factor);
2523
2524 self.window
2525 .next_frame
2526 .scene
2527 .insert_primitive(MonochromeSprite {
2528 order: 0,
2529 pad: 0,
2530 bounds,
2531 content_mask,
2532 color,
2533 tile,
2534 transformation,
2535 });
2536
2537 Ok(())
2538 }
2539
2540 /// Paint an image into the scene for the next frame at the current z-index.
2541 ///
2542 /// This method should only be called as part of the paint phase of element drawing.
2543 pub fn paint_image(
2544 &mut self,
2545 bounds: Bounds<Pixels>,
2546 corner_radii: Corners<Pixels>,
2547 data: Arc<ImageData>,
2548 grayscale: bool,
2549 ) -> Result<()> {
2550 debug_assert_eq!(
2551 self.window.draw_phase,
2552 DrawPhase::Paint,
2553 "this method can only be called during paint"
2554 );
2555
2556 let scale_factor = self.scale_factor();
2557 let bounds = bounds.scale(scale_factor);
2558 let params = RenderImageParams { image_id: data.id };
2559
2560 let tile = self
2561 .window
2562 .sprite_atlas
2563 .get_or_insert_with(¶ms.clone().into(), &mut || {
2564 Ok(Some((data.size(), Cow::Borrowed(data.as_bytes()))))
2565 })?
2566 .expect("Callback above only returns Some");
2567 let content_mask = self.content_mask().scale(scale_factor);
2568 let corner_radii = corner_radii.scale(scale_factor);
2569
2570 self.window
2571 .next_frame
2572 .scene
2573 .insert_primitive(PolychromeSprite {
2574 order: 0,
2575 grayscale,
2576 bounds,
2577 content_mask,
2578 corner_radii,
2579 tile,
2580 });
2581 Ok(())
2582 }
2583
2584 /// Paint a surface into the scene for the next frame at the current z-index.
2585 ///
2586 /// This method should only be called as part of the paint phase of element drawing.
2587 #[cfg(target_os = "macos")]
2588 pub fn paint_surface(&mut self, bounds: Bounds<Pixels>, image_buffer: CVImageBuffer) {
2589 debug_assert_eq!(
2590 self.window.draw_phase,
2591 DrawPhase::Paint,
2592 "this method can only be called during paint"
2593 );
2594
2595 let scale_factor = self.scale_factor();
2596 let bounds = bounds.scale(scale_factor);
2597 let content_mask = self.content_mask().scale(scale_factor);
2598 self.window
2599 .next_frame
2600 .scene
2601 .insert_primitive(crate::Surface {
2602 order: 0,
2603 bounds,
2604 content_mask,
2605 image_buffer,
2606 });
2607 }
2608
2609 #[must_use]
2610 /// Add a node to the layout tree for the current frame. Takes the `Style` of the element for which
2611 /// layout is being requested, along with the layout ids of any children. This method is called during
2612 /// calls to the [`Element::request_layout`] trait method and enables any element to participate in layout.
2613 ///
2614 /// This method should only be called as part of the request_layout or prepaint phase of element drawing.
2615 pub fn request_layout(
2616 &mut self,
2617 style: Style,
2618 children: impl IntoIterator<Item = LayoutId>,
2619 ) -> LayoutId {
2620 debug_assert_eq!(
2621 self.window.draw_phase,
2622 DrawPhase::Prepaint,
2623 "this method can only be called during request_layout, or prepaint"
2624 );
2625
2626 self.app.layout_id_buffer.clear();
2627 self.app.layout_id_buffer.extend(children);
2628 let rem_size = self.rem_size();
2629
2630 self.window.layout_engine.as_mut().unwrap().request_layout(
2631 style,
2632 rem_size,
2633 &self.app.layout_id_buffer,
2634 )
2635 }
2636
2637 /// Add a node to the layout tree for the current frame. Instead of taking a `Style` and children,
2638 /// this variant takes a function that is invoked during layout so you can use arbitrary logic to
2639 /// determine the element's size. One place this is used internally is when measuring text.
2640 ///
2641 /// The given closure is invoked at layout time with the known dimensions and available space and
2642 /// returns a `Size`.
2643 ///
2644 /// This method should only be called as part of the request_layout or prepaint phase of element drawing.
2645 pub fn request_measured_layout<
2646 F: FnMut(Size<Option<Pixels>>, Size<AvailableSpace>, &mut WindowContext) -> Size<Pixels>
2647 + 'static,
2648 >(
2649 &mut self,
2650 style: Style,
2651 measure: F,
2652 ) -> LayoutId {
2653 debug_assert_eq!(
2654 self.window.draw_phase,
2655 DrawPhase::Prepaint,
2656 "this method can only be called during request_layout, or prepaint"
2657 );
2658
2659 let rem_size = self.rem_size();
2660 self.window
2661 .layout_engine
2662 .as_mut()
2663 .unwrap()
2664 .request_measured_layout(style, rem_size, measure)
2665 }
2666
2667 /// Compute the layout for the given id within the given available space.
2668 /// This method is called for its side effect, typically by the framework prior to painting.
2669 /// After calling it, you can request the bounds of the given layout node id or any descendant.
2670 ///
2671 /// This method should only be called as part of the prepaint phase of element drawing.
2672 pub fn compute_layout(&mut self, layout_id: LayoutId, available_space: Size<AvailableSpace>) {
2673 debug_assert_eq!(
2674 self.window.draw_phase,
2675 DrawPhase::Prepaint,
2676 "this method can only be called during request_layout, or prepaint"
2677 );
2678
2679 let mut layout_engine = self.window.layout_engine.take().unwrap();
2680 layout_engine.compute_layout(layout_id, available_space, self);
2681 self.window.layout_engine = Some(layout_engine);
2682 }
2683
2684 /// Obtain the bounds computed for the given LayoutId relative to the window. This method will usually be invoked by
2685 /// GPUI itself automatically in order to pass your element its `Bounds` automatically.
2686 ///
2687 /// This method should only be called as part of element drawing.
2688 pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Bounds<Pixels> {
2689 debug_assert_eq!(
2690 self.window.draw_phase,
2691 DrawPhase::Prepaint,
2692 "this method can only be called during request_layout, prepaint, or paint"
2693 );
2694
2695 let mut bounds = self
2696 .window
2697 .layout_engine
2698 .as_mut()
2699 .unwrap()
2700 .layout_bounds(layout_id)
2701 .map(Into::into);
2702 bounds.origin += self.element_offset();
2703 bounds
2704 }
2705
2706 /// This method should be called during `prepaint`. You can use
2707 /// the returned [Hitbox] during `paint` or in an event handler
2708 /// to determine whether the inserted hitbox was the topmost.
2709 ///
2710 /// This method should only be called as part of the prepaint phase of element drawing.
2711 pub fn insert_hitbox(&mut self, bounds: Bounds<Pixels>, opaque: bool) -> Hitbox {
2712 debug_assert_eq!(
2713 self.window.draw_phase,
2714 DrawPhase::Prepaint,
2715 "this method can only be called during prepaint"
2716 );
2717
2718 let content_mask = self.content_mask();
2719 let window = &mut self.window;
2720 let id = window.next_hitbox_id;
2721 window.next_hitbox_id.0 += 1;
2722 let hitbox = Hitbox {
2723 id,
2724 bounds,
2725 content_mask,
2726 opaque,
2727 };
2728 window.next_frame.hitboxes.push(hitbox.clone());
2729 hitbox
2730 }
2731
2732 /// Sets the key context for the current element. This context will be used to translate
2733 /// keybindings into actions.
2734 ///
2735 /// This method should only be called as part of the paint phase of element drawing.
2736 pub fn set_key_context(&mut self, context: KeyContext) {
2737 debug_assert_eq!(
2738 self.window.draw_phase,
2739 DrawPhase::Paint,
2740 "this method can only be called during paint"
2741 );
2742 self.window
2743 .next_frame
2744 .dispatch_tree
2745 .set_key_context(context);
2746 }
2747
2748 /// Sets the focus handle for the current element. This handle will be used to manage focus state
2749 /// and keyboard event dispatch for the element.
2750 ///
2751 /// This method should only be called as part of the paint phase of element drawing.
2752 pub fn set_focus_handle(&mut self, focus_handle: &FocusHandle) {
2753 debug_assert_eq!(
2754 self.window.draw_phase,
2755 DrawPhase::Paint,
2756 "this method can only be called during paint"
2757 );
2758 self.window
2759 .next_frame
2760 .dispatch_tree
2761 .set_focus_id(focus_handle.id);
2762 }
2763
2764 /// Sets the view id for the current element, which will be used to manage view caching.
2765 ///
2766 /// This method should only be called as part of element prepaint. We plan on removing this
2767 /// method eventually when we solve some issues that require us to construct editor elements
2768 /// directly instead of always using editors via views.
2769 pub fn set_view_id(&mut self, view_id: EntityId) {
2770 debug_assert_eq!(
2771 self.window.draw_phase,
2772 DrawPhase::Prepaint,
2773 "this method can only be called during prepaint"
2774 );
2775 self.window.next_frame.dispatch_tree.set_view_id(view_id);
2776 }
2777
2778 /// Get the last view id for the current element
2779 pub fn parent_view_id(&mut self) -> Option<EntityId> {
2780 self.window.next_frame.dispatch_tree.parent_view_id()
2781 }
2782
2783 /// Sets an input handler, such as [`ElementInputHandler`][element_input_handler], which interfaces with the
2784 /// platform to receive textual input with proper integration with concerns such
2785 /// as IME interactions. This handler will be active for the upcoming frame until the following frame is
2786 /// rendered.
2787 ///
2788 /// This method should only be called as part of the paint phase of element drawing.
2789 ///
2790 /// [element_input_handler]: crate::ElementInputHandler
2791 pub fn handle_input(&mut self, focus_handle: &FocusHandle, input_handler: impl InputHandler) {
2792 debug_assert_eq!(
2793 self.window.draw_phase,
2794 DrawPhase::Paint,
2795 "this method can only be called during paint"
2796 );
2797
2798 if focus_handle.is_focused(self) {
2799 let cx = self.to_async();
2800 self.window
2801 .next_frame
2802 .input_handlers
2803 .push(Some(PlatformInputHandler::new(cx, Box::new(input_handler))));
2804 }
2805 }
2806
2807 /// Register a mouse event listener on the window for the next frame. The type of event
2808 /// is determined by the first parameter of the given listener. When the next frame is rendered
2809 /// the listener will be cleared.
2810 ///
2811 /// This method should only be called as part of the paint phase of element drawing.
2812 pub fn on_mouse_event<Event: MouseEvent>(
2813 &mut self,
2814 mut handler: impl FnMut(&Event, DispatchPhase, &mut WindowContext) + 'static,
2815 ) {
2816 debug_assert_eq!(
2817 self.window.draw_phase,
2818 DrawPhase::Paint,
2819 "this method can only be called during paint"
2820 );
2821
2822 self.window.next_frame.mouse_listeners.push(Some(Box::new(
2823 move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| {
2824 if let Some(event) = event.downcast_ref() {
2825 handler(event, phase, cx)
2826 }
2827 },
2828 )));
2829 }
2830
2831 /// Register a key event listener on the window for the next frame. The type of event
2832 /// is determined by the first parameter of the given listener. When the next frame is rendered
2833 /// the listener will be cleared.
2834 ///
2835 /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
2836 /// a specific need to register a global listener.
2837 ///
2838 /// This method should only be called as part of the paint phase of element drawing.
2839 pub fn on_key_event<Event: KeyEvent>(
2840 &mut self,
2841 listener: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static,
2842 ) {
2843 debug_assert_eq!(
2844 self.window.draw_phase,
2845 DrawPhase::Paint,
2846 "this method can only be called during paint"
2847 );
2848
2849 self.window.next_frame.dispatch_tree.on_key_event(Rc::new(
2850 move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| {
2851 if let Some(event) = event.downcast_ref::<Event>() {
2852 listener(event, phase, cx)
2853 }
2854 },
2855 ));
2856 }
2857
2858 /// Register a modifiers changed event listener on the window for the next frame.
2859 ///
2860 /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
2861 /// a specific need to register a global listener.
2862 ///
2863 /// This method should only be called as part of the paint phase of element drawing.
2864 pub fn on_modifiers_changed(
2865 &mut self,
2866 listener: impl Fn(&ModifiersChangedEvent, &mut WindowContext) + 'static,
2867 ) {
2868 debug_assert_eq!(
2869 self.window.draw_phase,
2870 DrawPhase::Paint,
2871 "this method can only be called during paint"
2872 );
2873
2874 self.window
2875 .next_frame
2876 .dispatch_tree
2877 .on_modifiers_changed(Rc::new(
2878 move |event: &ModifiersChangedEvent, cx: &mut WindowContext<'_>| {
2879 listener(event, cx)
2880 },
2881 ));
2882 }
2883
2884 fn reset_cursor_style(&self) {
2885 // Set the cursor only if we're the active window.
2886 if self.is_window_active() {
2887 let style = self
2888 .window
2889 .rendered_frame
2890 .cursor_styles
2891 .iter()
2892 .rev()
2893 .find(|request| request.hitbox_id.is_hovered(self))
2894 .map(|request| request.style)
2895 .unwrap_or(CursorStyle::Arrow);
2896 self.platform.set_cursor_style(style);
2897 }
2898 }
2899
2900 /// Dispatch a given keystroke as though the user had typed it.
2901 /// You can create a keystroke with Keystroke::parse("").
2902 pub fn dispatch_keystroke(&mut self, keystroke: Keystroke) -> bool {
2903 let keystroke = keystroke.with_simulated_ime();
2904 let result = self.dispatch_event(PlatformInput::KeyDown(KeyDownEvent {
2905 keystroke: keystroke.clone(),
2906 is_held: false,
2907 }));
2908 if !result.propagate {
2909 return true;
2910 }
2911
2912 if let Some(input) = keystroke.ime_key {
2913 if let Some(mut input_handler) = self.window.platform_window.take_input_handler() {
2914 input_handler.dispatch_input(&input, self);
2915 self.window.platform_window.set_input_handler(input_handler);
2916 return true;
2917 }
2918 }
2919
2920 false
2921 }
2922
2923 /// Represent this action as a key binding string, to display in the UI.
2924 pub fn keystroke_text_for(&self, action: &dyn Action) -> String {
2925 self.bindings_for_action(action)
2926 .into_iter()
2927 .next()
2928 .map(|binding| {
2929 binding
2930 .keystrokes()
2931 .iter()
2932 .map(ToString::to_string)
2933 .collect::<Vec<_>>()
2934 .join(" ")
2935 })
2936 .unwrap_or_else(|| action.name().to_string())
2937 }
2938
2939 /// Dispatch a mouse or keyboard event on the window.
2940 #[profiling::function]
2941 pub fn dispatch_event(&mut self, event: PlatformInput) -> DispatchEventResult {
2942 self.window.last_input_timestamp.set(Instant::now());
2943 // Handlers may set this to false by calling `stop_propagation`.
2944 self.app.propagate_event = true;
2945 // Handlers may set this to true by calling `prevent_default`.
2946 self.window.default_prevented = false;
2947
2948 let event = match event {
2949 // Track the mouse position with our own state, since accessing the platform
2950 // API for the mouse position can only occur on the main thread.
2951 PlatformInput::MouseMove(mouse_move) => {
2952 self.window.mouse_position = mouse_move.position;
2953 self.window.modifiers = mouse_move.modifiers;
2954 PlatformInput::MouseMove(mouse_move)
2955 }
2956 PlatformInput::MouseDown(mouse_down) => {
2957 self.window.mouse_position = mouse_down.position;
2958 self.window.modifiers = mouse_down.modifiers;
2959 PlatformInput::MouseDown(mouse_down)
2960 }
2961 PlatformInput::MouseUp(mouse_up) => {
2962 self.window.mouse_position = mouse_up.position;
2963 self.window.modifiers = mouse_up.modifiers;
2964 PlatformInput::MouseUp(mouse_up)
2965 }
2966 PlatformInput::MouseExited(mouse_exited) => {
2967 self.window.modifiers = mouse_exited.modifiers;
2968 PlatformInput::MouseExited(mouse_exited)
2969 }
2970 PlatformInput::ModifiersChanged(modifiers_changed) => {
2971 self.window.modifiers = modifiers_changed.modifiers;
2972 PlatformInput::ModifiersChanged(modifiers_changed)
2973 }
2974 PlatformInput::ScrollWheel(scroll_wheel) => {
2975 self.window.mouse_position = scroll_wheel.position;
2976 self.window.modifiers = scroll_wheel.modifiers;
2977 PlatformInput::ScrollWheel(scroll_wheel)
2978 }
2979 // Translate dragging and dropping of external files from the operating system
2980 // to internal drag and drop events.
2981 PlatformInput::FileDrop(file_drop) => match file_drop {
2982 FileDropEvent::Entered { position, paths } => {
2983 self.window.mouse_position = position;
2984 if self.active_drag.is_none() {
2985 self.active_drag = Some(AnyDrag {
2986 value: Box::new(paths.clone()),
2987 view: self.new_view(|_| paths).into(),
2988 cursor_offset: position,
2989 });
2990 }
2991 PlatformInput::MouseMove(MouseMoveEvent {
2992 position,
2993 pressed_button: Some(MouseButton::Left),
2994 modifiers: Modifiers::default(),
2995 })
2996 }
2997 FileDropEvent::Pending { position } => {
2998 self.window.mouse_position = position;
2999 PlatformInput::MouseMove(MouseMoveEvent {
3000 position,
3001 pressed_button: Some(MouseButton::Left),
3002 modifiers: Modifiers::default(),
3003 })
3004 }
3005 FileDropEvent::Submit { position } => {
3006 self.activate(true);
3007 self.window.mouse_position = position;
3008 PlatformInput::MouseUp(MouseUpEvent {
3009 button: MouseButton::Left,
3010 position,
3011 modifiers: Modifiers::default(),
3012 click_count: 1,
3013 })
3014 }
3015 FileDropEvent::Exited => {
3016 self.active_drag.take();
3017 PlatformInput::FileDrop(FileDropEvent::Exited)
3018 }
3019 },
3020 PlatformInput::KeyDown(_) | PlatformInput::KeyUp(_) => event,
3021 };
3022
3023 if let Some(any_mouse_event) = event.mouse_event() {
3024 self.dispatch_mouse_event(any_mouse_event);
3025 } else if let Some(any_key_event) = event.keyboard_event() {
3026 self.dispatch_key_event(any_key_event);
3027 }
3028
3029 DispatchEventResult {
3030 propagate: self.app.propagate_event,
3031 default_prevented: self.window.default_prevented,
3032 }
3033 }
3034
3035 fn dispatch_mouse_event(&mut self, event: &dyn Any) {
3036 let hit_test = self.window.rendered_frame.hit_test(self.mouse_position());
3037 if hit_test != self.window.mouse_hit_test {
3038 self.window.mouse_hit_test = hit_test;
3039 self.reset_cursor_style();
3040 }
3041
3042 let mut mouse_listeners = mem::take(&mut self.window.rendered_frame.mouse_listeners);
3043
3044 // Capture phase, events bubble from back to front. Handlers for this phase are used for
3045 // special purposes, such as detecting events outside of a given Bounds.
3046 for listener in &mut mouse_listeners {
3047 let listener = listener.as_mut().unwrap();
3048 listener(event, DispatchPhase::Capture, self);
3049 if !self.app.propagate_event {
3050 break;
3051 }
3052 }
3053
3054 // Bubble phase, where most normal handlers do their work.
3055 if self.app.propagate_event {
3056 for listener in mouse_listeners.iter_mut().rev() {
3057 let listener = listener.as_mut().unwrap();
3058 listener(event, DispatchPhase::Bubble, self);
3059 if !self.app.propagate_event {
3060 break;
3061 }
3062 }
3063 }
3064
3065 self.window.rendered_frame.mouse_listeners = mouse_listeners;
3066
3067 if self.has_active_drag() {
3068 if event.is::<MouseMoveEvent>() {
3069 // If this was a mouse move event, redraw the window so that the
3070 // active drag can follow the mouse cursor.
3071 self.refresh();
3072 } else if event.is::<MouseUpEvent>() {
3073 // If this was a mouse up event, cancel the active drag and redraw
3074 // the window.
3075 self.active_drag = None;
3076 self.refresh();
3077 }
3078 }
3079 }
3080
3081 fn dispatch_key_event(&mut self, event: &dyn Any) {
3082 if self.window.dirty.get() {
3083 self.draw();
3084 }
3085
3086 let node_id = self
3087 .window
3088 .focus
3089 .and_then(|focus_id| {
3090 self.window
3091 .rendered_frame
3092 .dispatch_tree
3093 .focusable_node_id(focus_id)
3094 })
3095 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
3096
3097 let dispatch_path = self
3098 .window
3099 .rendered_frame
3100 .dispatch_tree
3101 .dispatch_path(node_id);
3102
3103 if let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() {
3104 let KeymatchResult { bindings, pending } = self
3105 .window
3106 .rendered_frame
3107 .dispatch_tree
3108 .dispatch_key(&key_down_event.keystroke, &dispatch_path);
3109
3110 if pending {
3111 let mut currently_pending = self.window.pending_input.take().unwrap_or_default();
3112 if currently_pending.focus.is_some() && currently_pending.focus != self.window.focus
3113 {
3114 currently_pending = PendingInput::default();
3115 }
3116 currently_pending.focus = self.window.focus;
3117 currently_pending
3118 .keystrokes
3119 .push(key_down_event.keystroke.clone());
3120 for binding in bindings {
3121 currently_pending.bindings.push(binding);
3122 }
3123
3124 currently_pending.timer = Some(self.spawn(|mut cx| async move {
3125 cx.background_executor.timer(Duration::from_secs(1)).await;
3126 cx.update(move |cx| {
3127 cx.clear_pending_keystrokes();
3128 let Some(currently_pending) = cx.window.pending_input.take() else {
3129 return;
3130 };
3131 cx.replay_pending_input(currently_pending)
3132 })
3133 .log_err();
3134 }));
3135
3136 self.window.pending_input = Some(currently_pending);
3137
3138 self.propagate_event = false;
3139 return;
3140 } else if let Some(currently_pending) = self.window.pending_input.take() {
3141 if bindings
3142 .iter()
3143 .all(|binding| !currently_pending.used_by_binding(binding))
3144 {
3145 self.replay_pending_input(currently_pending)
3146 }
3147 }
3148
3149 if !bindings.is_empty() {
3150 self.clear_pending_keystrokes();
3151 }
3152
3153 self.propagate_event = true;
3154 for binding in bindings {
3155 self.dispatch_action_on_node(node_id, binding.action.as_ref());
3156 if !self.propagate_event {
3157 self.dispatch_keystroke_observers(event, Some(binding.action));
3158 return;
3159 }
3160 }
3161 }
3162
3163 self.dispatch_key_down_up_event(event, &dispatch_path);
3164 if !self.propagate_event {
3165 return;
3166 }
3167
3168 self.dispatch_modifiers_changed_event(event, &dispatch_path);
3169 if !self.propagate_event {
3170 return;
3171 }
3172
3173 self.dispatch_keystroke_observers(event, None);
3174 }
3175
3176 fn dispatch_key_down_up_event(
3177 &mut self,
3178 event: &dyn Any,
3179 dispatch_path: &SmallVec<[DispatchNodeId; 32]>,
3180 ) {
3181 // Capture phase
3182 for node_id in dispatch_path {
3183 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
3184
3185 for key_listener in node.key_listeners.clone() {
3186 key_listener(event, DispatchPhase::Capture, self);
3187 if !self.propagate_event {
3188 return;
3189 }
3190 }
3191 }
3192
3193 // Bubble phase
3194 for node_id in dispatch_path.iter().rev() {
3195 // Handle low level key events
3196 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
3197 for key_listener in node.key_listeners.clone() {
3198 key_listener(event, DispatchPhase::Bubble, self);
3199 if !self.propagate_event {
3200 return;
3201 }
3202 }
3203 }
3204 }
3205
3206 fn dispatch_modifiers_changed_event(
3207 &mut self,
3208 event: &dyn Any,
3209 dispatch_path: &SmallVec<[DispatchNodeId; 32]>,
3210 ) {
3211 let Some(event) = event.downcast_ref::<ModifiersChangedEvent>() else {
3212 return;
3213 };
3214 for node_id in dispatch_path.iter().rev() {
3215 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
3216 for listener in node.modifiers_changed_listeners.clone() {
3217 listener(event, self);
3218 if !self.propagate_event {
3219 return;
3220 }
3221 }
3222 }
3223 }
3224
3225 /// Determine whether a potential multi-stroke key binding is in progress on this window.
3226 pub fn has_pending_keystrokes(&self) -> bool {
3227 self.window
3228 .rendered_frame
3229 .dispatch_tree
3230 .has_pending_keystrokes()
3231 }
3232
3233 fn replay_pending_input(&mut self, currently_pending: PendingInput) {
3234 let node_id = self
3235 .window
3236 .focus
3237 .and_then(|focus_id| {
3238 self.window
3239 .rendered_frame
3240 .dispatch_tree
3241 .focusable_node_id(focus_id)
3242 })
3243 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
3244
3245 if self.window.focus != currently_pending.focus {
3246 return;
3247 }
3248
3249 let input = currently_pending.input();
3250
3251 self.propagate_event = true;
3252 for binding in currently_pending.bindings {
3253 self.dispatch_action_on_node(node_id, binding.action.as_ref());
3254 if !self.propagate_event {
3255 return;
3256 }
3257 }
3258
3259 let dispatch_path = self
3260 .window
3261 .rendered_frame
3262 .dispatch_tree
3263 .dispatch_path(node_id);
3264
3265 for keystroke in currently_pending.keystrokes {
3266 let event = KeyDownEvent {
3267 keystroke,
3268 is_held: false,
3269 };
3270
3271 self.dispatch_key_down_up_event(&event, &dispatch_path);
3272 if !self.propagate_event {
3273 return;
3274 }
3275 }
3276
3277 if !input.is_empty() {
3278 if let Some(mut input_handler) = self.window.platform_window.take_input_handler() {
3279 input_handler.dispatch_input(&input, self);
3280 self.window.platform_window.set_input_handler(input_handler)
3281 }
3282 }
3283 }
3284
3285 fn dispatch_action_on_node(&mut self, node_id: DispatchNodeId, action: &dyn Action) {
3286 let dispatch_path = self
3287 .window
3288 .rendered_frame
3289 .dispatch_tree
3290 .dispatch_path(node_id);
3291
3292 // Capture phase for global actions.
3293 self.propagate_event = true;
3294 if let Some(mut global_listeners) = self
3295 .global_action_listeners
3296 .remove(&action.as_any().type_id())
3297 {
3298 for listener in &global_listeners {
3299 listener(action.as_any(), DispatchPhase::Capture, self);
3300 if !self.propagate_event {
3301 break;
3302 }
3303 }
3304
3305 global_listeners.extend(
3306 self.global_action_listeners
3307 .remove(&action.as_any().type_id())
3308 .unwrap_or_default(),
3309 );
3310
3311 self.global_action_listeners
3312 .insert(action.as_any().type_id(), global_listeners);
3313 }
3314
3315 if !self.propagate_event {
3316 return;
3317 }
3318
3319 // Capture phase for window actions.
3320 for node_id in &dispatch_path {
3321 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
3322 for DispatchActionListener {
3323 action_type,
3324 listener,
3325 } in node.action_listeners.clone()
3326 {
3327 let any_action = action.as_any();
3328 if action_type == any_action.type_id() {
3329 listener(any_action, DispatchPhase::Capture, self);
3330
3331 if !self.propagate_event {
3332 return;
3333 }
3334 }
3335 }
3336 }
3337
3338 // Bubble phase for window actions.
3339 for node_id in dispatch_path.iter().rev() {
3340 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
3341 for DispatchActionListener {
3342 action_type,
3343 listener,
3344 } in node.action_listeners.clone()
3345 {
3346 let any_action = action.as_any();
3347 if action_type == any_action.type_id() {
3348 self.propagate_event = false; // Actions stop propagation by default during the bubble phase
3349 listener(any_action, DispatchPhase::Bubble, self);
3350
3351 if !self.propagate_event {
3352 return;
3353 }
3354 }
3355 }
3356 }
3357
3358 // Bubble phase for global actions.
3359 if let Some(mut global_listeners) = self
3360 .global_action_listeners
3361 .remove(&action.as_any().type_id())
3362 {
3363 for listener in global_listeners.iter().rev() {
3364 self.propagate_event = false; // Actions stop propagation by default during the bubble phase
3365
3366 listener(action.as_any(), DispatchPhase::Bubble, self);
3367 if !self.propagate_event {
3368 break;
3369 }
3370 }
3371
3372 global_listeners.extend(
3373 self.global_action_listeners
3374 .remove(&action.as_any().type_id())
3375 .unwrap_or_default(),
3376 );
3377
3378 self.global_action_listeners
3379 .insert(action.as_any().type_id(), global_listeners);
3380 }
3381 }
3382
3383 /// Register the given handler to be invoked whenever the global of the given type
3384 /// is updated.
3385 pub fn observe_global<G: Global>(
3386 &mut self,
3387 f: impl Fn(&mut WindowContext<'_>) + 'static,
3388 ) -> Subscription {
3389 let window_handle = self.window.handle;
3390 let (subscription, activate) = self.global_observers.insert(
3391 TypeId::of::<G>(),
3392 Box::new(move |cx| window_handle.update(cx, |_, cx| f(cx)).is_ok()),
3393 );
3394 self.app.defer(move |_| activate());
3395 subscription
3396 }
3397
3398 /// Focus the current window and bring it to the foreground at the platform level.
3399 pub fn activate_window(&self) {
3400 self.window.platform_window.activate();
3401 }
3402
3403 /// Minimize the current window at the platform level.
3404 pub fn minimize_window(&self) {
3405 self.window.platform_window.minimize();
3406 }
3407
3408 /// Toggle full screen status on the current window at the platform level.
3409 pub fn toggle_fullscreen(&self) {
3410 self.window.platform_window.toggle_fullscreen();
3411 }
3412
3413 /// Present a platform dialog.
3414 /// The provided message will be presented, along with buttons for each answer.
3415 /// When a button is clicked, the returned Receiver will receive the index of the clicked button.
3416 pub fn prompt(
3417 &mut self,
3418 level: PromptLevel,
3419 message: &str,
3420 detail: Option<&str>,
3421 answers: &[&str],
3422 ) -> oneshot::Receiver<usize> {
3423 let prompt_builder = self.app.prompt_builder.take();
3424 let Some(prompt_builder) = prompt_builder else {
3425 unreachable!("Re-entrant window prompting is not supported by GPUI");
3426 };
3427
3428 let receiver = match &prompt_builder {
3429 PromptBuilder::Default => self
3430 .window
3431 .platform_window
3432 .prompt(level, message, detail, answers)
3433 .unwrap_or_else(|| {
3434 self.build_custom_prompt(&prompt_builder, level, message, detail, answers)
3435 }),
3436 PromptBuilder::Custom(_) => {
3437 self.build_custom_prompt(&prompt_builder, level, message, detail, answers)
3438 }
3439 };
3440
3441 self.app.prompt_builder = Some(prompt_builder);
3442
3443 receiver
3444 }
3445
3446 fn build_custom_prompt(
3447 &mut self,
3448 prompt_builder: &PromptBuilder,
3449 level: PromptLevel,
3450 message: &str,
3451 detail: Option<&str>,
3452 answers: &[&str],
3453 ) -> oneshot::Receiver<usize> {
3454 let (sender, receiver) = oneshot::channel();
3455 let handle = PromptHandle::new(sender);
3456 let handle = (prompt_builder)(level, message, detail, answers, handle, self);
3457 self.window.prompt = Some(handle);
3458 receiver
3459 }
3460
3461 /// Returns all available actions for the focused element.
3462 pub fn available_actions(&self) -> Vec<Box<dyn Action>> {
3463 let node_id = self
3464 .window
3465 .focus
3466 .and_then(|focus_id| {
3467 self.window
3468 .rendered_frame
3469 .dispatch_tree
3470 .focusable_node_id(focus_id)
3471 })
3472 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
3473
3474 let mut actions = self
3475 .window
3476 .rendered_frame
3477 .dispatch_tree
3478 .available_actions(node_id);
3479 for action_type in self.global_action_listeners.keys() {
3480 if let Err(ix) = actions.binary_search_by_key(action_type, |a| a.as_any().type_id()) {
3481 let action = self.actions.build_action_type(action_type).ok();
3482 if let Some(action) = action {
3483 actions.insert(ix, action);
3484 }
3485 }
3486 }
3487 actions
3488 }
3489
3490 /// Returns key bindings that invoke the given action on the currently focused element.
3491 pub fn bindings_for_action(&self, action: &dyn Action) -> Vec<KeyBinding> {
3492 self.window
3493 .rendered_frame
3494 .dispatch_tree
3495 .bindings_for_action(
3496 action,
3497 &self.window.rendered_frame.dispatch_tree.context_stack,
3498 )
3499 }
3500
3501 /// Returns any bindings that would invoke the given action on the given focus handle if it were focused.
3502 pub fn bindings_for_action_in(
3503 &self,
3504 action: &dyn Action,
3505 focus_handle: &FocusHandle,
3506 ) -> Vec<KeyBinding> {
3507 let dispatch_tree = &self.window.rendered_frame.dispatch_tree;
3508
3509 let Some(node_id) = dispatch_tree.focusable_node_id(focus_handle.id) else {
3510 return vec![];
3511 };
3512 let context_stack: Vec<_> = dispatch_tree
3513 .dispatch_path(node_id)
3514 .into_iter()
3515 .filter_map(|node_id| dispatch_tree.node(node_id).context.clone())
3516 .collect();
3517 dispatch_tree.bindings_for_action(action, &context_stack)
3518 }
3519
3520 /// Returns a generic event listener that invokes the given listener with the view and context associated with the given view handle.
3521 pub fn listener_for<V: Render, E>(
3522 &self,
3523 view: &View<V>,
3524 f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
3525 ) -> impl Fn(&E, &mut WindowContext) + 'static {
3526 let view = view.downgrade();
3527 move |e: &E, cx: &mut WindowContext| {
3528 view.update(cx, |view, cx| f(view, e, cx)).ok();
3529 }
3530 }
3531
3532 /// Returns a generic handler that invokes the given handler with the view and context associated with the given view handle.
3533 pub fn handler_for<V: Render>(
3534 &self,
3535 view: &View<V>,
3536 f: impl Fn(&mut V, &mut ViewContext<V>) + 'static,
3537 ) -> impl Fn(&mut WindowContext) {
3538 let view = view.downgrade();
3539 move |cx: &mut WindowContext| {
3540 view.update(cx, |view, cx| f(view, cx)).ok();
3541 }
3542 }
3543
3544 /// Register a callback that can interrupt the closing of the current window based the returned boolean.
3545 /// If the callback returns false, the window won't be closed.
3546 pub fn on_window_should_close(&mut self, f: impl Fn(&mut WindowContext) -> bool + 'static) {
3547 let mut this = self.to_async();
3548 self.window
3549 .platform_window
3550 .on_should_close(Box::new(move || this.update(|cx| f(cx)).unwrap_or(true)))
3551 }
3552
3553 /// Register an action listener on the window for the next frame. The type of action
3554 /// is determined by the first parameter of the given listener. When the next frame is rendered
3555 /// the listener will be cleared.
3556 ///
3557 /// This is a fairly low-level method, so prefer using action handlers on elements unless you have
3558 /// a specific need to register a global listener.
3559 pub fn on_action(
3560 &mut self,
3561 action_type: TypeId,
3562 listener: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static,
3563 ) {
3564 self.window
3565 .next_frame
3566 .dispatch_tree
3567 .on_action(action_type, Rc::new(listener));
3568 }
3569}
3570
3571#[cfg(target_os = "windows")]
3572impl WindowContext<'_> {
3573 /// Returns the raw HWND handle for the window.
3574 pub fn get_raw_handle(&self) -> windows::Win32::Foundation::HWND {
3575 self.window.platform_window.get_raw_handle()
3576 }
3577}
3578
3579impl Context for WindowContext<'_> {
3580 type Result<T> = T;
3581
3582 fn new_model<T>(&mut self, build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T) -> Model<T>
3583 where
3584 T: 'static,
3585 {
3586 let slot = self.app.entities.reserve();
3587 let model = build_model(&mut ModelContext::new(&mut *self.app, slot.downgrade()));
3588 self.entities.insert(slot, model)
3589 }
3590
3591 fn reserve_model<T: 'static>(&mut self) -> Self::Result<crate::Reservation<T>> {
3592 self.app.reserve_model()
3593 }
3594
3595 fn insert_model<T: 'static>(
3596 &mut self,
3597 reservation: crate::Reservation<T>,
3598 build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
3599 ) -> Self::Result<Model<T>> {
3600 self.app.insert_model(reservation, build_model)
3601 }
3602
3603 fn update_model<T: 'static, R>(
3604 &mut self,
3605 model: &Model<T>,
3606 update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
3607 ) -> R {
3608 let mut entity = self.entities.lease(model);
3609 let result = update(
3610 &mut *entity,
3611 &mut ModelContext::new(&mut *self.app, model.downgrade()),
3612 );
3613 self.entities.end_lease(entity);
3614 result
3615 }
3616
3617 fn read_model<T, R>(
3618 &self,
3619 handle: &Model<T>,
3620 read: impl FnOnce(&T, &AppContext) -> R,
3621 ) -> Self::Result<R>
3622 where
3623 T: 'static,
3624 {
3625 let entity = self.entities.read(handle);
3626 read(entity, &*self.app)
3627 }
3628
3629 fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
3630 where
3631 F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
3632 {
3633 if window == self.window.handle {
3634 let root_view = self.window.root_view.clone().unwrap();
3635 Ok(update(root_view, self))
3636 } else {
3637 window.update(self.app, update)
3638 }
3639 }
3640
3641 fn read_window<T, R>(
3642 &self,
3643 window: &WindowHandle<T>,
3644 read: impl FnOnce(View<T>, &AppContext) -> R,
3645 ) -> Result<R>
3646 where
3647 T: 'static,
3648 {
3649 if window.any_handle == self.window.handle {
3650 let root_view = self
3651 .window
3652 .root_view
3653 .clone()
3654 .unwrap()
3655 .downcast::<T>()
3656 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
3657 Ok(read(root_view, self))
3658 } else {
3659 self.app.read_window(window, read)
3660 }
3661 }
3662}
3663
3664impl VisualContext for WindowContext<'_> {
3665 fn new_view<V>(
3666 &mut self,
3667 build_view_state: impl FnOnce(&mut ViewContext<'_, V>) -> V,
3668 ) -> Self::Result<View<V>>
3669 where
3670 V: 'static + Render,
3671 {
3672 let slot = self.app.entities.reserve();
3673 let view = View {
3674 model: slot.clone(),
3675 };
3676 let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view);
3677 let entity = build_view_state(&mut cx);
3678 cx.entities.insert(slot, entity);
3679
3680 // Non-generic part to avoid leaking SubscriberSet to invokers of `new_view`.
3681 fn notify_observers(cx: &mut WindowContext, tid: TypeId, view: AnyView) {
3682 cx.new_view_observers.clone().retain(&tid, |observer| {
3683 let any_view = view.clone();
3684 (observer)(any_view, cx);
3685 true
3686 });
3687 }
3688 notify_observers(self, TypeId::of::<V>(), AnyView::from(view.clone()));
3689
3690 view
3691 }
3692
3693 /// Updates the given view. Prefer calling [`View::update`] instead, which calls this method.
3694 fn update_view<T: 'static, R>(
3695 &mut self,
3696 view: &View<T>,
3697 update: impl FnOnce(&mut T, &mut ViewContext<'_, T>) -> R,
3698 ) -> Self::Result<R> {
3699 let mut lease = self.app.entities.lease(&view.model);
3700 let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, view);
3701 let result = update(&mut *lease, &mut cx);
3702 cx.app.entities.end_lease(lease);
3703 result
3704 }
3705
3706 fn replace_root_view<V>(
3707 &mut self,
3708 build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V,
3709 ) -> Self::Result<View<V>>
3710 where
3711 V: 'static + Render,
3712 {
3713 let view = self.new_view(build_view);
3714 self.window.root_view = Some(view.clone().into());
3715 self.refresh();
3716 view
3717 }
3718
3719 fn focus_view<V: crate::FocusableView>(&mut self, view: &View<V>) -> Self::Result<()> {
3720 self.update_view(view, |view, cx| {
3721 view.focus_handle(cx).clone().focus(cx);
3722 })
3723 }
3724
3725 fn dismiss_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
3726 where
3727 V: ManagedView,
3728 {
3729 self.update_view(view, |_, cx| cx.emit(DismissEvent))
3730 }
3731}
3732
3733impl<'a> std::ops::Deref for WindowContext<'a> {
3734 type Target = AppContext;
3735
3736 fn deref(&self) -> &Self::Target {
3737 self.app
3738 }
3739}
3740
3741impl<'a> std::ops::DerefMut for WindowContext<'a> {
3742 fn deref_mut(&mut self) -> &mut Self::Target {
3743 self.app
3744 }
3745}
3746
3747impl<'a> Borrow<AppContext> for WindowContext<'a> {
3748 fn borrow(&self) -> &AppContext {
3749 self.app
3750 }
3751}
3752
3753impl<'a> BorrowMut<AppContext> for WindowContext<'a> {
3754 fn borrow_mut(&mut self) -> &mut AppContext {
3755 self.app
3756 }
3757}
3758
3759/// This trait contains functionality that is shared across [`ViewContext`] and [`WindowContext`]
3760pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
3761 #[doc(hidden)]
3762 fn app_mut(&mut self) -> &mut AppContext {
3763 self.borrow_mut()
3764 }
3765
3766 #[doc(hidden)]
3767 fn app(&self) -> &AppContext {
3768 self.borrow()
3769 }
3770
3771 #[doc(hidden)]
3772 fn window(&self) -> &Window {
3773 self.borrow()
3774 }
3775
3776 #[doc(hidden)]
3777 fn window_mut(&mut self) -> &mut Window {
3778 self.borrow_mut()
3779 }
3780}
3781
3782impl Borrow<Window> for WindowContext<'_> {
3783 fn borrow(&self) -> &Window {
3784 self.window
3785 }
3786}
3787
3788impl BorrowMut<Window> for WindowContext<'_> {
3789 fn borrow_mut(&mut self) -> &mut Window {
3790 self.window
3791 }
3792}
3793
3794impl<T> BorrowWindow for T where T: BorrowMut<AppContext> + BorrowMut<Window> {}
3795
3796/// Provides access to application state that is specialized for a particular [`View`].
3797/// Allows you to interact with focus, emit events, etc.
3798/// ViewContext also derefs to [`WindowContext`], giving you access to all of its methods as well.
3799/// When you call [`View::update`], you're passed a `&mut V` and an `&mut ViewContext<V>`.
3800pub struct ViewContext<'a, V> {
3801 window_cx: WindowContext<'a>,
3802 view: &'a View<V>,
3803}
3804
3805impl<V> Borrow<AppContext> for ViewContext<'_, V> {
3806 fn borrow(&self) -> &AppContext {
3807 &*self.window_cx.app
3808 }
3809}
3810
3811impl<V> BorrowMut<AppContext> for ViewContext<'_, V> {
3812 fn borrow_mut(&mut self) -> &mut AppContext {
3813 &mut *self.window_cx.app
3814 }
3815}
3816
3817impl<V> Borrow<Window> for ViewContext<'_, V> {
3818 fn borrow(&self) -> &Window {
3819 &*self.window_cx.window
3820 }
3821}
3822
3823impl<V> BorrowMut<Window> for ViewContext<'_, V> {
3824 fn borrow_mut(&mut self) -> &mut Window {
3825 &mut *self.window_cx.window
3826 }
3827}
3828
3829impl<'a, V: 'static> ViewContext<'a, V> {
3830 pub(crate) fn new(app: &'a mut AppContext, window: &'a mut Window, view: &'a View<V>) -> Self {
3831 Self {
3832 window_cx: WindowContext::new(app, window),
3833 view,
3834 }
3835 }
3836
3837 /// Get the entity_id of this view.
3838 pub fn entity_id(&self) -> EntityId {
3839 self.view.entity_id()
3840 }
3841
3842 /// Get the view pointer underlying this context.
3843 pub fn view(&self) -> &View<V> {
3844 self.view
3845 }
3846
3847 /// Get the model underlying this view.
3848 pub fn model(&self) -> &Model<V> {
3849 &self.view.model
3850 }
3851
3852 /// Access the underlying window context.
3853 pub fn window_context(&mut self) -> &mut WindowContext<'a> {
3854 &mut self.window_cx
3855 }
3856
3857 /// Sets a given callback to be run on the next frame.
3858 pub fn on_next_frame(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + 'static)
3859 where
3860 V: 'static,
3861 {
3862 let view = self.view().clone();
3863 self.window_cx.on_next_frame(move |cx| view.update(cx, f));
3864 }
3865
3866 /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
3867 /// that are currently on the stack to be returned to the app.
3868 pub fn defer(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + 'static) {
3869 let view = self.view().downgrade();
3870 self.window_cx.defer(move |cx| {
3871 view.update(cx, f).ok();
3872 });
3873 }
3874
3875 /// Observe another model or view for changes to its state, as tracked by [`ModelContext::notify`].
3876 pub fn observe<V2, E>(
3877 &mut self,
3878 entity: &E,
3879 mut on_notify: impl FnMut(&mut V, E, &mut ViewContext<'_, V>) + 'static,
3880 ) -> Subscription
3881 where
3882 V2: 'static,
3883 V: 'static,
3884 E: Entity<V2>,
3885 {
3886 let view = self.view().downgrade();
3887 let entity_id = entity.entity_id();
3888 let entity = entity.downgrade();
3889 let window_handle = self.window.handle;
3890 self.app.new_observer(
3891 entity_id,
3892 Box::new(move |cx| {
3893 window_handle
3894 .update(cx, |_, cx| {
3895 if let Some(handle) = E::upgrade_from(&entity) {
3896 view.update(cx, |this, cx| on_notify(this, handle, cx))
3897 .is_ok()
3898 } else {
3899 false
3900 }
3901 })
3902 .unwrap_or(false)
3903 }),
3904 )
3905 }
3906
3907 /// Subscribe to events emitted by another model or view.
3908 /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
3909 /// The callback will be invoked with a reference to the current view, a handle to the emitting entity (either a [`View`] or [`Model`]), the event, and a view context for the current view.
3910 pub fn subscribe<V2, E, Evt>(
3911 &mut self,
3912 entity: &E,
3913 mut on_event: impl FnMut(&mut V, E, &Evt, &mut ViewContext<'_, V>) + 'static,
3914 ) -> Subscription
3915 where
3916 V2: EventEmitter<Evt>,
3917 E: Entity<V2>,
3918 Evt: 'static,
3919 {
3920 let view = self.view().downgrade();
3921 let entity_id = entity.entity_id();
3922 let handle = entity.downgrade();
3923 let window_handle = self.window.handle;
3924 self.app.new_subscription(
3925 entity_id,
3926 (
3927 TypeId::of::<Evt>(),
3928 Box::new(move |event, cx| {
3929 window_handle
3930 .update(cx, |_, cx| {
3931 if let Some(handle) = E::upgrade_from(&handle) {
3932 let event = event.downcast_ref().expect("invalid event type");
3933 view.update(cx, |this, cx| on_event(this, handle, event, cx))
3934 .is_ok()
3935 } else {
3936 false
3937 }
3938 })
3939 .unwrap_or(false)
3940 }),
3941 ),
3942 )
3943 }
3944
3945 /// Register a callback to be invoked when the view is released.
3946 ///
3947 /// The callback receives a handle to the view's window. This handle may be
3948 /// invalid, if the window was closed before the view was released.
3949 pub fn on_release(
3950 &mut self,
3951 on_release: impl FnOnce(&mut V, AnyWindowHandle, &mut AppContext) + 'static,
3952 ) -> Subscription {
3953 let window_handle = self.window.handle;
3954 let (subscription, activate) = self.app.release_listeners.insert(
3955 self.view.model.entity_id,
3956 Box::new(move |this, cx| {
3957 let this = this.downcast_mut().expect("invalid entity type");
3958 on_release(this, window_handle, cx)
3959 }),
3960 );
3961 activate();
3962 subscription
3963 }
3964
3965 /// Register a callback to be invoked when the given Model or View is released.
3966 pub fn observe_release<V2, E>(
3967 &mut self,
3968 entity: &E,
3969 mut on_release: impl FnMut(&mut V, &mut V2, &mut ViewContext<'_, V>) + 'static,
3970 ) -> Subscription
3971 where
3972 V: 'static,
3973 V2: 'static,
3974 E: Entity<V2>,
3975 {
3976 let view = self.view().downgrade();
3977 let entity_id = entity.entity_id();
3978 let window_handle = self.window.handle;
3979 let (subscription, activate) = self.app.release_listeners.insert(
3980 entity_id,
3981 Box::new(move |entity, cx| {
3982 let entity = entity.downcast_mut().expect("invalid entity type");
3983 let _ = window_handle.update(cx, |_, cx| {
3984 view.update(cx, |this, cx| on_release(this, entity, cx))
3985 });
3986 }),
3987 );
3988 activate();
3989 subscription
3990 }
3991
3992 /// Indicate that this view has changed, which will invoke any observers and also mark the window as dirty.
3993 /// If this view or any of its ancestors are *cached*, notifying it will cause it or its ancestors to be redrawn.
3994 pub fn notify(&mut self) {
3995 self.window_cx.notify(self.view.entity_id());
3996 }
3997
3998 /// Register a callback to be invoked when the window is resized.
3999 pub fn observe_window_bounds(
4000 &mut self,
4001 mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
4002 ) -> Subscription {
4003 let view = self.view.downgrade();
4004 let (subscription, activate) = self.window.bounds_observers.insert(
4005 (),
4006 Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
4007 );
4008 activate();
4009 subscription
4010 }
4011
4012 /// Register a callback to be invoked when the window is activated or deactivated.
4013 pub fn observe_window_activation(
4014 &mut self,
4015 mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
4016 ) -> Subscription {
4017 let view = self.view.downgrade();
4018 let (subscription, activate) = self.window.activation_observers.insert(
4019 (),
4020 Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
4021 );
4022 activate();
4023 subscription
4024 }
4025
4026 /// Registers a callback to be invoked when the window appearance changes.
4027 pub fn observe_window_appearance(
4028 &mut self,
4029 mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
4030 ) -> Subscription {
4031 let view = self.view.downgrade();
4032 let (subscription, activate) = self.window.appearance_observers.insert(
4033 (),
4034 Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
4035 );
4036 activate();
4037 subscription
4038 }
4039
4040 /// Register a listener to be called when the given focus handle receives focus.
4041 /// Returns a subscription and persists until the subscription is dropped.
4042 pub fn on_focus(
4043 &mut self,
4044 handle: &FocusHandle,
4045 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
4046 ) -> Subscription {
4047 let view = self.view.downgrade();
4048 let focus_id = handle.id;
4049 let (subscription, activate) =
4050 self.window.new_focus_listener(Box::new(move |event, cx| {
4051 view.update(cx, |view, cx| {
4052 if event.previous_focus_path.last() != Some(&focus_id)
4053 && event.current_focus_path.last() == Some(&focus_id)
4054 {
4055 listener(view, cx)
4056 }
4057 })
4058 .is_ok()
4059 }));
4060 self.app.defer(|_| activate());
4061 subscription
4062 }
4063
4064 /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
4065 /// This does not fire if the given focus handle - or one of its descendants - was previously focused.
4066 /// Returns a subscription and persists until the subscription is dropped.
4067 pub fn on_focus_in(
4068 &mut self,
4069 handle: &FocusHandle,
4070 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
4071 ) -> Subscription {
4072 let view = self.view.downgrade();
4073 let focus_id = handle.id;
4074 let (subscription, activate) =
4075 self.window.new_focus_listener(Box::new(move |event, cx| {
4076 view.update(cx, |view, cx| {
4077 if !event.previous_focus_path.contains(&focus_id)
4078 && event.current_focus_path.contains(&focus_id)
4079 {
4080 listener(view, cx)
4081 }
4082 })
4083 .is_ok()
4084 }));
4085 self.app.defer(move |_| activate());
4086 subscription
4087 }
4088
4089 /// Register a listener to be called when the given focus handle loses focus.
4090 /// Returns a subscription and persists until the subscription is dropped.
4091 pub fn on_blur(
4092 &mut self,
4093 handle: &FocusHandle,
4094 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
4095 ) -> Subscription {
4096 let view = self.view.downgrade();
4097 let focus_id = handle.id;
4098 let (subscription, activate) =
4099 self.window.new_focus_listener(Box::new(move |event, cx| {
4100 view.update(cx, |view, cx| {
4101 if event.previous_focus_path.last() == Some(&focus_id)
4102 && event.current_focus_path.last() != Some(&focus_id)
4103 {
4104 listener(view, cx)
4105 }
4106 })
4107 .is_ok()
4108 }));
4109 self.app.defer(move |_| activate());
4110 subscription
4111 }
4112
4113 /// Register a listener to be called when nothing in the window has focus.
4114 /// This typically happens when the node that was focused is removed from the tree,
4115 /// and this callback lets you chose a default place to restore the users focus.
4116 /// Returns a subscription and persists until the subscription is dropped.
4117 pub fn on_focus_lost(
4118 &mut self,
4119 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
4120 ) -> Subscription {
4121 let view = self.view.downgrade();
4122 let (subscription, activate) = self.window.focus_lost_listeners.insert(
4123 (),
4124 Box::new(move |cx| view.update(cx, |view, cx| listener(view, cx)).is_ok()),
4125 );
4126 activate();
4127 subscription
4128 }
4129
4130 /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
4131 /// Returns a subscription and persists until the subscription is dropped.
4132 pub fn on_focus_out(
4133 &mut self,
4134 handle: &FocusHandle,
4135 mut listener: impl FnMut(&mut V, FocusOutEvent, &mut ViewContext<V>) + 'static,
4136 ) -> Subscription {
4137 let view = self.view.downgrade();
4138 let focus_id = handle.id;
4139 let (subscription, activate) =
4140 self.window.new_focus_listener(Box::new(move |event, cx| {
4141 view.update(cx, |view, cx| {
4142 if let Some(blurred_id) = event.previous_focus_path.last().copied() {
4143 if event.previous_focus_path.contains(&focus_id)
4144 && !event.current_focus_path.contains(&focus_id)
4145 {
4146 let event = FocusOutEvent {
4147 blurred: WeakFocusHandle {
4148 id: blurred_id,
4149 handles: Arc::downgrade(&cx.window.focus_handles),
4150 },
4151 };
4152 listener(view, event, cx)
4153 }
4154 }
4155 })
4156 .is_ok()
4157 }));
4158 self.app.defer(move |_| activate());
4159 subscription
4160 }
4161
4162 /// Schedule a future to be run asynchronously.
4163 /// The given callback is invoked with a [`WeakView<V>`] to avoid leaking the view for a long-running process.
4164 /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the view across await points.
4165 /// The returned future will be polled on the main thread.
4166 pub fn spawn<Fut, R>(
4167 &mut self,
4168 f: impl FnOnce(WeakView<V>, AsyncWindowContext) -> Fut,
4169 ) -> Task<R>
4170 where
4171 R: 'static,
4172 Fut: Future<Output = R> + 'static,
4173 {
4174 let view = self.view().downgrade();
4175 self.window_cx.spawn(|cx| f(view, cx))
4176 }
4177
4178 /// Register a callback to be invoked when the given global state changes.
4179 pub fn observe_global<G: Global>(
4180 &mut self,
4181 mut f: impl FnMut(&mut V, &mut ViewContext<'_, V>) + 'static,
4182 ) -> Subscription {
4183 let window_handle = self.window.handle;
4184 let view = self.view().downgrade();
4185 let (subscription, activate) = self.global_observers.insert(
4186 TypeId::of::<G>(),
4187 Box::new(move |cx| {
4188 window_handle
4189 .update(cx, |_, cx| view.update(cx, |view, cx| f(view, cx)).is_ok())
4190 .unwrap_or(false)
4191 }),
4192 );
4193 self.app.defer(move |_| activate());
4194 subscription
4195 }
4196
4197 /// Register a callback to be invoked when the given Action type is dispatched to the window.
4198 pub fn on_action(
4199 &mut self,
4200 action_type: TypeId,
4201 listener: impl Fn(&mut V, &dyn Any, DispatchPhase, &mut ViewContext<V>) + 'static,
4202 ) {
4203 let handle = self.view().clone();
4204 self.window_cx
4205 .on_action(action_type, move |action, phase, cx| {
4206 handle.update(cx, |view, cx| {
4207 listener(view, action, phase, cx);
4208 })
4209 });
4210 }
4211
4212 /// Emit an event to be handled by any other views that have subscribed via [ViewContext::subscribe].
4213 pub fn emit<Evt>(&mut self, event: Evt)
4214 where
4215 Evt: 'static,
4216 V: EventEmitter<Evt>,
4217 {
4218 let emitter = self.view.model.entity_id;
4219 self.app.push_effect(Effect::Emit {
4220 emitter,
4221 event_type: TypeId::of::<Evt>(),
4222 event: Box::new(event),
4223 });
4224 }
4225
4226 /// Move focus to the current view, assuming it implements [`FocusableView`].
4227 pub fn focus_self(&mut self)
4228 where
4229 V: FocusableView,
4230 {
4231 self.defer(|view, cx| view.focus_handle(cx).focus(cx))
4232 }
4233
4234 /// Convenience method for accessing view state in an event callback.
4235 ///
4236 /// Many GPUI callbacks take the form of `Fn(&E, &mut WindowContext)`,
4237 /// but it's often useful to be able to access view state in these
4238 /// callbacks. This method provides a convenient way to do so.
4239 pub fn listener<E>(
4240 &self,
4241 f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
4242 ) -> impl Fn(&E, &mut WindowContext) + 'static {
4243 let view = self.view().downgrade();
4244 move |e: &E, cx: &mut WindowContext| {
4245 view.update(cx, |view, cx| f(view, e, cx)).ok();
4246 }
4247 }
4248}
4249
4250impl<V> Context for ViewContext<'_, V> {
4251 type Result<U> = U;
4252
4253 fn new_model<T: 'static>(
4254 &mut self,
4255 build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
4256 ) -> Model<T> {
4257 self.window_cx.new_model(build_model)
4258 }
4259
4260 fn reserve_model<T: 'static>(&mut self) -> Self::Result<crate::Reservation<T>> {
4261 self.window_cx.reserve_model()
4262 }
4263
4264 fn insert_model<T: 'static>(
4265 &mut self,
4266 reservation: crate::Reservation<T>,
4267 build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
4268 ) -> Self::Result<Model<T>> {
4269 self.window_cx.insert_model(reservation, build_model)
4270 }
4271
4272 fn update_model<T: 'static, R>(
4273 &mut self,
4274 model: &Model<T>,
4275 update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
4276 ) -> R {
4277 self.window_cx.update_model(model, update)
4278 }
4279
4280 fn read_model<T, R>(
4281 &self,
4282 handle: &Model<T>,
4283 read: impl FnOnce(&T, &AppContext) -> R,
4284 ) -> Self::Result<R>
4285 where
4286 T: 'static,
4287 {
4288 self.window_cx.read_model(handle, read)
4289 }
4290
4291 fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
4292 where
4293 F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
4294 {
4295 self.window_cx.update_window(window, update)
4296 }
4297
4298 fn read_window<T, R>(
4299 &self,
4300 window: &WindowHandle<T>,
4301 read: impl FnOnce(View<T>, &AppContext) -> R,
4302 ) -> Result<R>
4303 where
4304 T: 'static,
4305 {
4306 self.window_cx.read_window(window, read)
4307 }
4308}
4309
4310impl<V: 'static> VisualContext for ViewContext<'_, V> {
4311 fn new_view<W: Render + 'static>(
4312 &mut self,
4313 build_view_state: impl FnOnce(&mut ViewContext<'_, W>) -> W,
4314 ) -> Self::Result<View<W>> {
4315 self.window_cx.new_view(build_view_state)
4316 }
4317
4318 fn update_view<V2: 'static, R>(
4319 &mut self,
4320 view: &View<V2>,
4321 update: impl FnOnce(&mut V2, &mut ViewContext<'_, V2>) -> R,
4322 ) -> Self::Result<R> {
4323 self.window_cx.update_view(view, update)
4324 }
4325
4326 fn replace_root_view<W>(
4327 &mut self,
4328 build_view: impl FnOnce(&mut ViewContext<'_, W>) -> W,
4329 ) -> Self::Result<View<W>>
4330 where
4331 W: 'static + Render,
4332 {
4333 self.window_cx.replace_root_view(build_view)
4334 }
4335
4336 fn focus_view<W: FocusableView>(&mut self, view: &View<W>) -> Self::Result<()> {
4337 self.window_cx.focus_view(view)
4338 }
4339
4340 fn dismiss_view<W: ManagedView>(&mut self, view: &View<W>) -> Self::Result<()> {
4341 self.window_cx.dismiss_view(view)
4342 }
4343}
4344
4345impl<'a, V> std::ops::Deref for ViewContext<'a, V> {
4346 type Target = WindowContext<'a>;
4347
4348 fn deref(&self) -> &Self::Target {
4349 &self.window_cx
4350 }
4351}
4352
4353impl<'a, V> std::ops::DerefMut for ViewContext<'a, V> {
4354 fn deref_mut(&mut self) -> &mut Self::Target {
4355 &mut self.window_cx
4356 }
4357}
4358
4359// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
4360slotmap::new_key_type! {
4361 /// A unique identifier for a window.
4362 pub struct WindowId;
4363}
4364
4365impl WindowId {
4366 /// Converts this window ID to a `u64`.
4367 pub fn as_u64(&self) -> u64 {
4368 self.0.as_ffi()
4369 }
4370}
4371
4372/// A handle to a window with a specific root view type.
4373/// Note that this does not keep the window alive on its own.
4374#[derive(Deref, DerefMut)]
4375pub struct WindowHandle<V> {
4376 #[deref]
4377 #[deref_mut]
4378 pub(crate) any_handle: AnyWindowHandle,
4379 state_type: PhantomData<V>,
4380}
4381
4382impl<V: 'static + Render> WindowHandle<V> {
4383 /// Creates a new handle from a window ID.
4384 /// This does not check if the root type of the window is `V`.
4385 pub fn new(id: WindowId) -> Self {
4386 WindowHandle {
4387 any_handle: AnyWindowHandle {
4388 id,
4389 state_type: TypeId::of::<V>(),
4390 },
4391 state_type: PhantomData,
4392 }
4393 }
4394
4395 /// Get the root view out of this window.
4396 ///
4397 /// This will fail if the window is closed or if the root view's type does not match `V`.
4398 pub fn root<C>(&self, cx: &mut C) -> Result<View<V>>
4399 where
4400 C: Context,
4401 {
4402 Flatten::flatten(cx.update_window(self.any_handle, |root_view, _| {
4403 root_view
4404 .downcast::<V>()
4405 .map_err(|_| anyhow!("the type of the window's root view has changed"))
4406 }))
4407 }
4408
4409 /// Updates the root view of this window.
4410 ///
4411 /// This will fail if the window has been closed or if the root view's type does not match
4412 pub fn update<C, R>(
4413 &self,
4414 cx: &mut C,
4415 update: impl FnOnce(&mut V, &mut ViewContext<'_, V>) -> R,
4416 ) -> Result<R>
4417 where
4418 C: Context,
4419 {
4420 cx.update_window(self.any_handle, |root_view, cx| {
4421 let view = root_view
4422 .downcast::<V>()
4423 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
4424 Ok(cx.update_view(&view, update))
4425 })?
4426 }
4427
4428 /// Read the root view out of this window.
4429 ///
4430 /// This will fail if the window is closed or if the root view's type does not match `V`.
4431 pub fn read<'a>(&self, cx: &'a AppContext) -> Result<&'a V> {
4432 let x = cx
4433 .windows
4434 .get(self.id)
4435 .and_then(|window| {
4436 window
4437 .as_ref()
4438 .and_then(|window| window.root_view.clone())
4439 .map(|root_view| root_view.downcast::<V>())
4440 })
4441 .ok_or_else(|| anyhow!("window not found"))?
4442 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
4443
4444 Ok(x.read(cx))
4445 }
4446
4447 /// Read the root view out of this window, with a callback
4448 ///
4449 /// This will fail if the window is closed or if the root view's type does not match `V`.
4450 pub fn read_with<C, R>(&self, cx: &C, read_with: impl FnOnce(&V, &AppContext) -> R) -> Result<R>
4451 where
4452 C: Context,
4453 {
4454 cx.read_window(self, |root_view, cx| read_with(root_view.read(cx), cx))
4455 }
4456
4457 /// Read the root view pointer off of this window.
4458 ///
4459 /// This will fail if the window is closed or if the root view's type does not match `V`.
4460 pub fn root_view<C>(&self, cx: &C) -> Result<View<V>>
4461 where
4462 C: Context,
4463 {
4464 cx.read_window(self, |root_view, _cx| root_view.clone())
4465 }
4466
4467 /// Check if this window is 'active'.
4468 ///
4469 /// Will return `None` if the window is closed or currently
4470 /// borrowed.
4471 pub fn is_active(&self, cx: &mut AppContext) -> Option<bool> {
4472 cx.update_window(self.any_handle, |_, cx| cx.is_window_active())
4473 .ok()
4474 }
4475}
4476
4477impl<V> Copy for WindowHandle<V> {}
4478
4479impl<V> Clone for WindowHandle<V> {
4480 fn clone(&self) -> Self {
4481 *self
4482 }
4483}
4484
4485impl<V> PartialEq for WindowHandle<V> {
4486 fn eq(&self, other: &Self) -> bool {
4487 self.any_handle == other.any_handle
4488 }
4489}
4490
4491impl<V> Eq for WindowHandle<V> {}
4492
4493impl<V> Hash for WindowHandle<V> {
4494 fn hash<H: Hasher>(&self, state: &mut H) {
4495 self.any_handle.hash(state);
4496 }
4497}
4498
4499impl<V: 'static> From<WindowHandle<V>> for AnyWindowHandle {
4500 fn from(val: WindowHandle<V>) -> Self {
4501 val.any_handle
4502 }
4503}
4504
4505unsafe impl<V> Send for WindowHandle<V> {}
4506unsafe impl<V> Sync for WindowHandle<V> {}
4507
4508/// A handle to a window with any root view type, which can be downcast to a window with a specific root view type.
4509#[derive(Copy, Clone, PartialEq, Eq, Hash)]
4510pub struct AnyWindowHandle {
4511 pub(crate) id: WindowId,
4512 state_type: TypeId,
4513}
4514
4515impl AnyWindowHandle {
4516 /// Get the ID of this window.
4517 pub fn window_id(&self) -> WindowId {
4518 self.id
4519 }
4520
4521 /// Attempt to convert this handle to a window handle with a specific root view type.
4522 /// If the types do not match, this will return `None`.
4523 pub fn downcast<T: 'static>(&self) -> Option<WindowHandle<T>> {
4524 if TypeId::of::<T>() == self.state_type {
4525 Some(WindowHandle {
4526 any_handle: *self,
4527 state_type: PhantomData,
4528 })
4529 } else {
4530 None
4531 }
4532 }
4533
4534 /// Updates the state of the root view of this window.
4535 ///
4536 /// This will fail if the window has been closed.
4537 pub fn update<C, R>(
4538 self,
4539 cx: &mut C,
4540 update: impl FnOnce(AnyView, &mut WindowContext<'_>) -> R,
4541 ) -> Result<R>
4542 where
4543 C: Context,
4544 {
4545 cx.update_window(self, update)
4546 }
4547
4548 /// Read the state of the root view of this window.
4549 ///
4550 /// This will fail if the window has been closed.
4551 pub fn read<T, C, R>(self, cx: &C, read: impl FnOnce(View<T>, &AppContext) -> R) -> Result<R>
4552 where
4553 C: Context,
4554 T: 'static,
4555 {
4556 let view = self
4557 .downcast::<T>()
4558 .context("the type of the window's root view has changed")?;
4559
4560 cx.read_window(&view, read)
4561 }
4562}
4563
4564/// An identifier for an [`Element`](crate::Element).
4565///
4566/// Can be constructed with a string, a number, or both, as well
4567/// as other internal representations.
4568#[derive(Clone, Debug, Eq, PartialEq, Hash)]
4569pub enum ElementId {
4570 /// The ID of a View element
4571 View(EntityId),
4572 /// An integer ID.
4573 Integer(usize),
4574 /// A string based ID.
4575 Name(SharedString),
4576 /// A UUID.
4577 Uuid(Uuid),
4578 /// An ID that's equated with a focus handle.
4579 FocusHandle(FocusId),
4580 /// A combination of a name and an integer.
4581 NamedInteger(SharedString, usize),
4582}
4583
4584impl Display for ElementId {
4585 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4586 match self {
4587 ElementId::View(entity_id) => write!(f, "view-{}", entity_id)?,
4588 ElementId::Integer(ix) => write!(f, "{}", ix)?,
4589 ElementId::Name(name) => write!(f, "{}", name)?,
4590 ElementId::FocusHandle(_) => write!(f, "FocusHandle")?,
4591 ElementId::NamedInteger(s, i) => write!(f, "{}-{}", s, i)?,
4592 ElementId::Uuid(uuid) => write!(f, "{}", uuid)?,
4593 }
4594
4595 Ok(())
4596 }
4597}
4598
4599impl TryInto<SharedString> for ElementId {
4600 type Error = anyhow::Error;
4601
4602 fn try_into(self) -> anyhow::Result<SharedString> {
4603 if let ElementId::Name(name) = self {
4604 Ok(name)
4605 } else {
4606 Err(anyhow!("element id is not string"))
4607 }
4608 }
4609}
4610
4611impl From<usize> for ElementId {
4612 fn from(id: usize) -> Self {
4613 ElementId::Integer(id)
4614 }
4615}
4616
4617impl From<i32> for ElementId {
4618 fn from(id: i32) -> Self {
4619 Self::Integer(id as usize)
4620 }
4621}
4622
4623impl From<SharedString> for ElementId {
4624 fn from(name: SharedString) -> Self {
4625 ElementId::Name(name)
4626 }
4627}
4628
4629impl From<&'static str> for ElementId {
4630 fn from(name: &'static str) -> Self {
4631 ElementId::Name(name.into())
4632 }
4633}
4634
4635impl<'a> From<&'a FocusHandle> for ElementId {
4636 fn from(handle: &'a FocusHandle) -> Self {
4637 ElementId::FocusHandle(handle.id)
4638 }
4639}
4640
4641impl From<(&'static str, EntityId)> for ElementId {
4642 fn from((name, id): (&'static str, EntityId)) -> Self {
4643 ElementId::NamedInteger(name.into(), id.as_u64() as usize)
4644 }
4645}
4646
4647impl From<(&'static str, usize)> for ElementId {
4648 fn from((name, id): (&'static str, usize)) -> Self {
4649 ElementId::NamedInteger(name.into(), id)
4650 }
4651}
4652
4653impl From<(&'static str, u64)> for ElementId {
4654 fn from((name, id): (&'static str, u64)) -> Self {
4655 ElementId::NamedInteger(name.into(), id as usize)
4656 }
4657}
4658
4659impl From<Uuid> for ElementId {
4660 fn from(value: Uuid) -> Self {
4661 Self::Uuid(value)
4662 }
4663}
4664
4665impl From<(&'static str, u32)> for ElementId {
4666 fn from((name, id): (&'static str, u32)) -> Self {
4667 ElementId::NamedInteger(name.into(), id as usize)
4668 }
4669}
4670
4671/// A rectangle to be rendered in the window at the given position and size.
4672/// Passed as an argument [`WindowContext::paint_quad`].
4673#[derive(Clone)]
4674pub struct PaintQuad {
4675 /// The bounds of the quad within the window.
4676 pub bounds: Bounds<Pixels>,
4677 /// The radii of the quad's corners.
4678 pub corner_radii: Corners<Pixels>,
4679 /// The background color of the quad.
4680 pub background: Hsla,
4681 /// The widths of the quad's borders.
4682 pub border_widths: Edges<Pixels>,
4683 /// The color of the quad's borders.
4684 pub border_color: Hsla,
4685}
4686
4687impl PaintQuad {
4688 /// Sets the corner radii of the quad.
4689 pub fn corner_radii(self, corner_radii: impl Into<Corners<Pixels>>) -> Self {
4690 PaintQuad {
4691 corner_radii: corner_radii.into(),
4692 ..self
4693 }
4694 }
4695
4696 /// Sets the border widths of the quad.
4697 pub fn border_widths(self, border_widths: impl Into<Edges<Pixels>>) -> Self {
4698 PaintQuad {
4699 border_widths: border_widths.into(),
4700 ..self
4701 }
4702 }
4703
4704 /// Sets the border color of the quad.
4705 pub fn border_color(self, border_color: impl Into<Hsla>) -> Self {
4706 PaintQuad {
4707 border_color: border_color.into(),
4708 ..self
4709 }
4710 }
4711
4712 /// Sets the background color of the quad.
4713 pub fn background(self, background: impl Into<Hsla>) -> Self {
4714 PaintQuad {
4715 background: background.into(),
4716 ..self
4717 }
4718 }
4719}
4720
4721/// Creates a quad with the given parameters.
4722pub fn quad(
4723 bounds: Bounds<Pixels>,
4724 corner_radii: impl Into<Corners<Pixels>>,
4725 background: impl Into<Hsla>,
4726 border_widths: impl Into<Edges<Pixels>>,
4727 border_color: impl Into<Hsla>,
4728) -> PaintQuad {
4729 PaintQuad {
4730 bounds,
4731 corner_radii: corner_radii.into(),
4732 background: background.into(),
4733 border_widths: border_widths.into(),
4734 border_color: border_color.into(),
4735 }
4736}
4737
4738/// Creates a filled quad with the given bounds and background color.
4739pub fn fill(bounds: impl Into<Bounds<Pixels>>, background: impl Into<Hsla>) -> PaintQuad {
4740 PaintQuad {
4741 bounds: bounds.into(),
4742 corner_radii: (0.).into(),
4743 background: background.into(),
4744 border_widths: (0.).into(),
4745 border_color: transparent_black(),
4746 }
4747}
4748
4749/// Creates a rectangle outline with the given bounds, border color, and a 1px border width
4750pub fn outline(bounds: impl Into<Bounds<Pixels>>, border_color: impl Into<Hsla>) -> PaintQuad {
4751 PaintQuad {
4752 bounds: bounds.into(),
4753 corner_radii: (0.).into(),
4754 background: transparent_black(),
4755 border_widths: (1.).into(),
4756 border_color: border_color.into(),
4757 }
4758}