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