1#![deny(missing_docs)]
2
3use crate::{
4 px, size, transparent_black, Action, AnyDrag, AnyView, AppContext, Arena, AsyncWindowContext,
5 AvailableSpace, Bounds, BoxShadow, Context, Corners, CursorStyle, DevicePixels,
6 DispatchActionListener, DispatchNodeId, DispatchTree, DisplayId, Edges, Effect, Entity,
7 EntityId, EventEmitter, FileDropEvent, Flatten, FontId, GlobalElementId, GlyphId, Hsla,
8 ImageData, InputEvent, IsZero, KeyBinding, KeyContext, KeyDownEvent, KeystrokeEvent, LayoutId,
9 Model, ModelContext, Modifiers, MonochromeSprite, MouseButton, MouseMoveEvent, MouseUpEvent,
10 Path, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point,
11 PolychromeSprite, PromptLevel, Quad, Render, RenderGlyphParams, RenderImageParams,
12 RenderSvgParams, ScaledPixels, Scene, Shadow, SharedString, Size, Style, SubscriberSet,
13 Subscription, Surface, TaffyLayoutEngine, Task, Underline, UnderlineStyle, View, VisualContext,
14 WeakView, WindowBounds, WindowOptions, SUBPIXEL_VARIANTS,
15};
16use anyhow::{anyhow, Context as _, Result};
17use collections::{FxHashMap, FxHashSet};
18use derive_more::{Deref, DerefMut};
19use futures::{
20 channel::{mpsc, oneshot},
21 StreamExt,
22};
23use media::core_video::CVImageBuffer;
24use parking_lot::RwLock;
25use slotmap::SlotMap;
26use smallvec::SmallVec;
27use std::{
28 any::{Any, TypeId},
29 borrow::{Borrow, BorrowMut, Cow},
30 cell::RefCell,
31 collections::hash_map::Entry,
32 fmt::Debug,
33 future::Future,
34 hash::{Hash, Hasher},
35 marker::PhantomData,
36 mem,
37 rc::Rc,
38 sync::{
39 atomic::{AtomicUsize, Ordering::SeqCst},
40 Arc,
41 },
42};
43use util::{post_inc, ResultExt};
44
45const ACTIVE_DRAG_Z_INDEX: u8 = 1;
46
47/// A global stacking order, which is created by stacking successive z-index values.
48/// Each z-index will always be interpreted in the context of its parent z-index.
49#[derive(Deref, DerefMut, Clone, Ord, PartialOrd, PartialEq, Eq, Default)]
50pub struct StackingOrder {
51 #[deref]
52 #[deref_mut]
53 context_stack: SmallVec<[u8; 64]>,
54 id: u32,
55}
56
57impl std::fmt::Debug for StackingOrder {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 let mut stacks = self.context_stack.iter().peekable();
60 write!(f, "[({}): ", self.id)?;
61 while let Some(z_index) = stacks.next() {
62 write!(f, "{z_index}")?;
63 if stacks.peek().is_some() {
64 write!(f, "->")?;
65 }
66 }
67 write!(f, "]")?;
68 Ok(())
69 }
70}
71
72/// Represents the two different phases when dispatching events.
73#[derive(Default, Copy, Clone, Debug, Eq, PartialEq)]
74pub enum DispatchPhase {
75 /// After the capture phase comes the bubble phase, in which mouse event listeners are
76 /// invoked front to back and keyboard event listeners are invoked from the focused element
77 /// to the root of the element tree. This is the phase you'll most commonly want to use when
78 /// registering event listeners.
79 #[default]
80 Bubble,
81 /// During the initial capture phase, mouse event listeners are invoked back to front, and keyboard
82 /// listeners are invoked from the root of the tree downward toward the focused element. This phase
83 /// is used for special purposes such as clearing the "pressed" state for click events. If
84 /// you stop event propagation during this phase, you need to know what you're doing. Handlers
85 /// outside of the immediate region may rely on detecting non-local events during this phase.
86 Capture,
87}
88
89impl DispatchPhase {
90 /// Returns true if this represents the "bubble" phase.
91 pub fn bubble(self) -> bool {
92 self == DispatchPhase::Bubble
93 }
94
95 /// Returns true if this represents the "capture" phase.
96 pub fn capture(self) -> bool {
97 self == DispatchPhase::Capture
98 }
99}
100
101type AnyObserver = Box<dyn FnMut(&mut WindowContext) -> bool + 'static>;
102type AnyMouseListener = Box<dyn FnMut(&dyn Any, DispatchPhase, &mut WindowContext) + 'static>;
103type AnyWindowFocusListener = Box<dyn FnMut(&FocusEvent, &mut WindowContext) -> bool + 'static>;
104
105struct FocusEvent {
106 previous_focus_path: SmallVec<[FocusId; 8]>,
107 current_focus_path: SmallVec<[FocusId; 8]>,
108}
109
110slotmap::new_key_type! {
111 /// A globally unique identifier for a focusable element.
112 pub struct FocusId;
113}
114
115thread_local! {
116 pub(crate) static ELEMENT_ARENA: RefCell<Arena> = RefCell::new(Arena::new(4 * 1024 * 1024));
117}
118
119impl FocusId {
120 /// Obtains whether the element associated with this handle is currently focused.
121 pub fn is_focused(&self, cx: &WindowContext) -> bool {
122 cx.window.focus == Some(*self)
123 }
124
125 /// Obtains whether the element associated with this handle contains the focused
126 /// element or is itself focused.
127 pub fn contains_focused(&self, cx: &WindowContext) -> bool {
128 cx.focused()
129 .map_or(false, |focused| self.contains(focused.id, cx))
130 }
131
132 /// Obtains whether the element associated with this handle is contained within the
133 /// focused element or is itself focused.
134 pub fn within_focused(&self, cx: &WindowContext) -> bool {
135 let focused = cx.focused();
136 focused.map_or(false, |focused| focused.id.contains(*self, cx))
137 }
138
139 /// Obtains whether this handle contains the given handle in the most recently rendered frame.
140 pub(crate) fn contains(&self, other: Self, cx: &WindowContext) -> bool {
141 cx.window
142 .rendered_frame
143 .dispatch_tree
144 .focus_contains(*self, other)
145 }
146}
147
148/// A handle which can be used to track and manipulate the focused element in a window.
149pub struct FocusHandle {
150 pub(crate) id: FocusId,
151 handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
152}
153
154impl std::fmt::Debug for FocusHandle {
155 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
156 f.write_fmt(format_args!("FocusHandle({:?})", self.id))
157 }
158}
159
160impl FocusHandle {
161 pub(crate) fn new(handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>) -> Self {
162 let id = handles.write().insert(AtomicUsize::new(1));
163 Self {
164 id,
165 handles: handles.clone(),
166 }
167 }
168
169 pub(crate) fn for_id(
170 id: FocusId,
171 handles: &Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
172 ) -> Option<Self> {
173 let lock = handles.read();
174 let ref_count = lock.get(id)?;
175 if ref_count.load(SeqCst) == 0 {
176 None
177 } else {
178 ref_count.fetch_add(1, SeqCst);
179 Some(Self {
180 id,
181 handles: handles.clone(),
182 })
183 }
184 }
185
186 /// Moves the focus to the element associated with this handle.
187 pub fn focus(&self, cx: &mut WindowContext) {
188 cx.focus(self)
189 }
190
191 /// Obtains whether the element associated with this handle is currently focused.
192 pub fn is_focused(&self, cx: &WindowContext) -> bool {
193 self.id.is_focused(cx)
194 }
195
196 /// Obtains whether the element associated with this handle contains the focused
197 /// element or is itself focused.
198 pub fn contains_focused(&self, cx: &WindowContext) -> bool {
199 self.id.contains_focused(cx)
200 }
201
202 /// Obtains whether the element associated with this handle is contained within the
203 /// focused element or is itself focused.
204 pub fn within_focused(&self, cx: &WindowContext) -> bool {
205 self.id.within_focused(cx)
206 }
207
208 /// Obtains whether this handle contains the given handle in the most recently rendered frame.
209 pub fn contains(&self, other: &Self, cx: &WindowContext) -> bool {
210 self.id.contains(other.id, cx)
211 }
212}
213
214impl Clone for FocusHandle {
215 fn clone(&self) -> Self {
216 Self::for_id(self.id, &self.handles).unwrap()
217 }
218}
219
220impl PartialEq for FocusHandle {
221 fn eq(&self, other: &Self) -> bool {
222 self.id == other.id
223 }
224}
225
226impl Eq for FocusHandle {}
227
228impl Drop for FocusHandle {
229 fn drop(&mut self) {
230 self.handles
231 .read()
232 .get(self.id)
233 .unwrap()
234 .fetch_sub(1, SeqCst);
235 }
236}
237
238/// FocusableView allows users of your view to easily
239/// focus it (using cx.focus_view(view))
240pub trait FocusableView: 'static + Render {
241 /// Returns the focus handle associated with this view.
242 fn focus_handle(&self, cx: &AppContext) -> FocusHandle;
243}
244
245/// ManagedView is a view (like a Modal, Popover, Menu, etc.)
246/// where the lifecycle of the view is handled by another view.
247pub trait ManagedView: FocusableView + EventEmitter<DismissEvent> {}
248
249impl<M: FocusableView + EventEmitter<DismissEvent>> ManagedView for M {}
250
251/// Emitted by implementers of [`ManagedView`] to indicate the view should be dismissed, such as when a view is presented as a modal.
252pub struct DismissEvent;
253
254// Holds the state for a specific window.
255#[doc(hidden)]
256pub struct Window {
257 pub(crate) handle: AnyWindowHandle,
258 pub(crate) removed: bool,
259 pub(crate) platform_window: Box<dyn PlatformWindow>,
260 display_id: DisplayId,
261 sprite_atlas: Arc<dyn PlatformAtlas>,
262 rem_size: Pixels,
263 viewport_size: Size<Pixels>,
264 layout_engine: Option<TaffyLayoutEngine>,
265 pub(crate) root_view: Option<AnyView>,
266 pub(crate) element_id_stack: GlobalElementId,
267 pub(crate) rendered_frame: Frame,
268 pub(crate) next_frame: Frame,
269 pub(crate) dirty_views: FxHashSet<EntityId>,
270 pub(crate) focus_handles: Arc<RwLock<SlotMap<FocusId, AtomicUsize>>>,
271 focus_listeners: SubscriberSet<(), AnyWindowFocusListener>,
272 focus_lost_listeners: SubscriberSet<(), AnyObserver>,
273 default_prevented: bool,
274 mouse_position: Point<Pixels>,
275 modifiers: Modifiers,
276 scale_factor: f32,
277 bounds: WindowBounds,
278 bounds_observers: SubscriberSet<(), AnyObserver>,
279 active: bool,
280 pub(crate) dirty: bool,
281 pub(crate) refreshing: bool,
282 pub(crate) drawing: bool,
283 activation_observers: SubscriberSet<(), AnyObserver>,
284 pub(crate) focus: Option<FocusId>,
285 focus_enabled: bool,
286
287 #[cfg(any(test, feature = "test-support"))]
288 pub(crate) focus_invalidated: bool,
289}
290
291pub(crate) struct ElementStateBox {
292 inner: Box<dyn Any>,
293 parent_view_id: EntityId,
294 #[cfg(debug_assertions)]
295 type_name: &'static str,
296}
297
298struct RequestedInputHandler {
299 view_id: EntityId,
300 handler: Option<Box<dyn PlatformInputHandler>>,
301}
302
303pub(crate) struct Frame {
304 focus: Option<FocusId>,
305 window_active: bool,
306 pub(crate) element_states: FxHashMap<GlobalElementId, ElementStateBox>,
307 mouse_listeners: FxHashMap<TypeId, Vec<(StackingOrder, EntityId, AnyMouseListener)>>,
308 pub(crate) dispatch_tree: DispatchTree,
309 pub(crate) scene: Scene,
310 pub(crate) depth_map: Vec<(StackingOrder, EntityId, Bounds<Pixels>)>,
311 pub(crate) z_index_stack: StackingOrder,
312 pub(crate) next_stacking_order_id: u32,
313 content_mask_stack: Vec<ContentMask<Pixels>>,
314 element_offset_stack: Vec<Point<Pixels>>,
315 requested_input_handler: Option<RequestedInputHandler>,
316 cursor_styles: FxHashMap<EntityId, CursorStyle>,
317 requested_cursor_style: Option<CursorStyle>,
318 pub(crate) view_stack: Vec<EntityId>,
319 pub(crate) reused_views: FxHashSet<EntityId>,
320}
321
322impl Frame {
323 fn new(dispatch_tree: DispatchTree) -> Self {
324 Frame {
325 focus: None,
326 window_active: false,
327 element_states: FxHashMap::default(),
328 mouse_listeners: FxHashMap::default(),
329 dispatch_tree,
330 scene: Scene::default(),
331 z_index_stack: StackingOrder::default(),
332 next_stacking_order_id: 0,
333 depth_map: Vec::new(),
334 content_mask_stack: Vec::new(),
335 element_offset_stack: Vec::new(),
336 requested_input_handler: None,
337 cursor_styles: FxHashMap::default(),
338 requested_cursor_style: None,
339 view_stack: Vec::new(),
340 reused_views: FxHashSet::default(),
341 }
342 }
343
344 fn clear(&mut self) {
345 self.element_states.clear();
346 self.mouse_listeners.values_mut().for_each(Vec::clear);
347 self.dispatch_tree.clear();
348 self.depth_map.clear();
349 self.next_stacking_order_id = 0;
350 self.reused_views.clear();
351 self.scene.clear();
352 self.requested_input_handler.take();
353 self.cursor_styles.clear();
354 self.requested_cursor_style.take();
355 debug_assert_eq!(self.view_stack.len(), 0);
356 }
357
358 fn focus_path(&self) -> SmallVec<[FocusId; 8]> {
359 self.focus
360 .map(|focus_id| self.dispatch_tree.focus_path(focus_id))
361 .unwrap_or_default()
362 }
363
364 fn reuse_views(&mut self, prev_frame: &mut Self) {
365 // Reuse mouse listeners that didn't change since the last frame.
366 for (type_id, listeners) in &mut prev_frame.mouse_listeners {
367 let next_listeners = self.mouse_listeners.entry(*type_id).or_default();
368 for (order, view_id, listener) in listeners.drain(..) {
369 if self.reused_views.contains(&view_id) {
370 next_listeners.push((order, view_id, listener));
371 }
372 }
373 }
374
375 // Reuse entries in the depth map that didn't change since the last frame.
376 for (order, view_id, bounds) in prev_frame.depth_map.drain(..) {
377 if self.reused_views.contains(&view_id) {
378 self.depth_map.push((order, view_id, bounds));
379 }
380 }
381 self.depth_map.sort_by(|a, b| a.0.cmp(&b.0));
382
383 // Retain element states for views that didn't change since the last frame.
384 for (element_id, state) in prev_frame.element_states.drain() {
385 if self.reused_views.contains(&state.parent_view_id) {
386 self.element_states.entry(element_id).or_insert(state);
387 }
388 }
389
390 // Reuse geometry that didn't change since the last frame.
391 self.scene
392 .reuse_views(&self.reused_views, &mut prev_frame.scene);
393 }
394}
395
396impl Window {
397 pub(crate) fn new(
398 handle: AnyWindowHandle,
399 options: WindowOptions,
400 cx: &mut AppContext,
401 ) -> Self {
402 let platform_window = cx.platform.open_window(handle, options);
403 let display_id = platform_window.display().id();
404 let sprite_atlas = platform_window.sprite_atlas();
405 let mouse_position = platform_window.mouse_position();
406 let modifiers = platform_window.modifiers();
407 let content_size = platform_window.content_size();
408 let scale_factor = platform_window.scale_factor();
409 let bounds = platform_window.bounds();
410
411 platform_window.on_request_frame(Box::new({
412 let mut cx = cx.to_async();
413 move || {
414 handle.update(&mut cx, |_, cx| cx.draw()).log_err();
415 }
416 }));
417 platform_window.on_resize(Box::new({
418 let mut cx = cx.to_async();
419 move |_, _| {
420 handle
421 .update(&mut cx, |_, cx| cx.window_bounds_changed())
422 .log_err();
423 }
424 }));
425 platform_window.on_moved(Box::new({
426 let mut cx = cx.to_async();
427 move || {
428 handle
429 .update(&mut cx, |_, cx| cx.window_bounds_changed())
430 .log_err();
431 }
432 }));
433 platform_window.on_active_status_change(Box::new({
434 let mut cx = cx.to_async();
435 move |active| {
436 handle
437 .update(&mut cx, |_, cx| {
438 cx.window.active = active;
439 cx.window
440 .activation_observers
441 .clone()
442 .retain(&(), |callback| callback(cx));
443 })
444 .log_err();
445 }
446 }));
447
448 platform_window.on_input({
449 let mut cx = cx.to_async();
450 Box::new(move |event| {
451 handle
452 .update(&mut cx, |_, cx| cx.dispatch_event(event))
453 .log_err()
454 .unwrap_or(false)
455 })
456 });
457
458 Window {
459 handle,
460 removed: false,
461 platform_window,
462 display_id,
463 sprite_atlas,
464 rem_size: px(16.),
465 viewport_size: content_size,
466 layout_engine: Some(TaffyLayoutEngine::new()),
467 root_view: None,
468 element_id_stack: GlobalElementId::default(),
469 rendered_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
470 next_frame: Frame::new(DispatchTree::new(cx.keymap.clone(), cx.actions.clone())),
471 dirty_views: FxHashSet::default(),
472 focus_handles: Arc::new(RwLock::new(SlotMap::with_key())),
473 focus_listeners: SubscriberSet::new(),
474 focus_lost_listeners: SubscriberSet::new(),
475 default_prevented: true,
476 mouse_position,
477 modifiers,
478 scale_factor,
479 bounds,
480 bounds_observers: SubscriberSet::new(),
481 active: false,
482 dirty: false,
483 refreshing: false,
484 drawing: false,
485 activation_observers: SubscriberSet::new(),
486 focus: None,
487 focus_enabled: true,
488
489 #[cfg(any(test, feature = "test-support"))]
490 focus_invalidated: false,
491 }
492 }
493}
494
495/// Indicates which region of the window is visible. Content falling outside of this mask will not be
496/// rendered. Currently, only rectangular content masks are supported, but we give the mask its own type
497/// to leave room to support more complex shapes in the future.
498#[derive(Clone, Debug, Default, PartialEq, Eq)]
499#[repr(C)]
500pub struct ContentMask<P: Clone + Default + Debug> {
501 /// The bounds
502 pub bounds: Bounds<P>,
503}
504
505impl ContentMask<Pixels> {
506 /// Scale the content mask's pixel units by the given scaling factor.
507 pub fn scale(&self, factor: f32) -> ContentMask<ScaledPixels> {
508 ContentMask {
509 bounds: self.bounds.scale(factor),
510 }
511 }
512
513 /// Intersect the content mask with the given content mask.
514 pub fn intersect(&self, other: &Self) -> Self {
515 let bounds = self.bounds.intersect(&other.bounds);
516 ContentMask { bounds }
517 }
518}
519
520/// Provides access to application state in the context of a single window. Derefs
521/// to an [`AppContext`], so you can also pass a [`WindowContext`] to any method that takes
522/// an [`AppContext`] and call any [`AppContext`] methods.
523pub struct WindowContext<'a> {
524 pub(crate) app: &'a mut AppContext,
525 pub(crate) window: &'a mut Window,
526}
527
528impl<'a> WindowContext<'a> {
529 pub(crate) fn new(app: &'a mut AppContext, window: &'a mut Window) -> Self {
530 Self { app, window }
531 }
532
533 /// Obtain a handle to the window that belongs to this context.
534 pub fn window_handle(&self) -> AnyWindowHandle {
535 self.window.handle
536 }
537
538 /// Mark the window as dirty, scheduling it to be redrawn on the next frame.
539 pub fn refresh(&mut self) {
540 if !self.window.drawing {
541 self.window.refreshing = true;
542 self.window.dirty = true;
543 }
544 }
545
546 /// Close this window.
547 pub fn remove_window(&mut self) {
548 self.window.removed = true;
549 }
550
551 /// Obtain a new [`FocusHandle`], which allows you to track and manipulate the keyboard focus
552 /// for elements rendered within this window.
553 pub fn focus_handle(&mut self) -> FocusHandle {
554 FocusHandle::new(&self.window.focus_handles)
555 }
556
557 /// Obtain the currently focused [`FocusHandle`]. If no elements are focused, returns `None`.
558 pub fn focused(&self) -> Option<FocusHandle> {
559 self.window
560 .focus
561 .and_then(|id| FocusHandle::for_id(id, &self.window.focus_handles))
562 }
563
564 /// Move focus to the element associated with the given [`FocusHandle`].
565 pub fn focus(&mut self, handle: &FocusHandle) {
566 if !self.window.focus_enabled || self.window.focus == Some(handle.id) {
567 return;
568 }
569
570 self.window.focus = Some(handle.id);
571 self.window
572 .rendered_frame
573 .dispatch_tree
574 .clear_pending_keystrokes();
575
576 #[cfg(any(test, feature = "test-support"))]
577 {
578 self.window.focus_invalidated = true;
579 }
580
581 self.refresh();
582 }
583
584 /// Remove focus from all elements within this context's window.
585 pub fn blur(&mut self) {
586 if !self.window.focus_enabled {
587 return;
588 }
589
590 self.window.focus = None;
591 self.refresh();
592 }
593
594 /// Blur the window and don't allow anything in it to be focused again.
595 pub fn disable_focus(&mut self) {
596 self.blur();
597 self.window.focus_enabled = false;
598 }
599
600 /// Dispatch the given action on the currently focused element.
601 pub fn dispatch_action(&mut self, action: Box<dyn Action>) {
602 let focus_handle = self.focused();
603
604 self.defer(move |cx| {
605 let node_id = focus_handle
606 .and_then(|handle| {
607 cx.window
608 .rendered_frame
609 .dispatch_tree
610 .focusable_node_id(handle.id)
611 })
612 .unwrap_or_else(|| cx.window.rendered_frame.dispatch_tree.root_node_id());
613
614 cx.propagate_event = true;
615 cx.dispatch_action_on_node(node_id, action);
616 })
617 }
618
619 pub(crate) fn dispatch_keystroke_observers(
620 &mut self,
621 event: &dyn Any,
622 action: Option<Box<dyn Action>>,
623 ) {
624 let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() else {
625 return;
626 };
627
628 self.keystroke_observers
629 .clone()
630 .retain(&(), move |callback| {
631 (callback)(
632 &KeystrokeEvent {
633 keystroke: key_down_event.keystroke.clone(),
634 action: action.as_ref().map(|action| action.boxed_clone()),
635 },
636 self,
637 );
638 true
639 });
640 }
641
642 pub(crate) fn clear_pending_keystrokes(&mut self) {
643 self.window
644 .rendered_frame
645 .dispatch_tree
646 .clear_pending_keystrokes();
647 self.window
648 .next_frame
649 .dispatch_tree
650 .clear_pending_keystrokes();
651 }
652
653 /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
654 /// that are currently on the stack to be returned to the app.
655 pub fn defer(&mut self, f: impl FnOnce(&mut WindowContext) + 'static) {
656 let handle = self.window.handle;
657 self.app.defer(move |cx| {
658 handle.update(cx, |_, cx| f(cx)).ok();
659 });
660 }
661
662 /// Subscribe to events emitted by a model or view.
663 /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
664 /// 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.
665 pub fn subscribe<Emitter, E, Evt>(
666 &mut self,
667 entity: &E,
668 mut on_event: impl FnMut(E, &Evt, &mut WindowContext<'_>) + 'static,
669 ) -> Subscription
670 where
671 Emitter: EventEmitter<Evt>,
672 E: Entity<Emitter>,
673 Evt: 'static,
674 {
675 let entity_id = entity.entity_id();
676 let entity = entity.downgrade();
677 let window_handle = self.window.handle;
678 let (subscription, activate) = self.app.event_listeners.insert(
679 entity_id,
680 (
681 TypeId::of::<Evt>(),
682 Box::new(move |event, cx| {
683 window_handle
684 .update(cx, |_, cx| {
685 if let Some(handle) = E::upgrade_from(&entity) {
686 let event = event.downcast_ref().expect("invalid event type");
687 on_event(handle, event, cx);
688 true
689 } else {
690 false
691 }
692 })
693 .unwrap_or(false)
694 }),
695 ),
696 );
697 self.app.defer(move |_| activate());
698 subscription
699 }
700
701 /// Create an `AsyncWindowContext`, which has a static lifetime and can be held across
702 /// await points in async code.
703 pub fn to_async(&self) -> AsyncWindowContext {
704 AsyncWindowContext::new(self.app.to_async(), self.window.handle)
705 }
706
707 /// Schedule the given closure to be run directly after the current frame is rendered.
708 pub fn on_next_frame(&mut self, callback: impl FnOnce(&mut WindowContext) + 'static) {
709 let handle = self.window.handle;
710 let display_id = self.window.display_id;
711
712 let mut frame_consumers = std::mem::take(&mut self.app.frame_consumers);
713 if let Entry::Vacant(e) = frame_consumers.entry(display_id) {
714 let (tx, mut rx) = mpsc::unbounded::<()>();
715 self.platform.set_display_link_output_callback(
716 display_id,
717 Box::new(move |_current_time, _output_time| _ = tx.unbounded_send(())),
718 );
719
720 let consumer_task = self.app.spawn(|cx| async move {
721 while rx.next().await.is_some() {
722 cx.update(|cx| {
723 for callback in cx
724 .next_frame_callbacks
725 .get_mut(&display_id)
726 .unwrap()
727 .drain(..)
728 .collect::<SmallVec<[_; 32]>>()
729 {
730 callback(cx);
731 }
732 })
733 .ok();
734
735 // Flush effects, then stop the display link if no new next_frame_callbacks have been added.
736
737 cx.update(|cx| {
738 if cx.next_frame_callbacks.is_empty() {
739 cx.platform.stop_display_link(display_id);
740 }
741 })
742 .ok();
743 }
744 });
745 e.insert(consumer_task);
746 }
747 debug_assert!(self.app.frame_consumers.is_empty());
748 self.app.frame_consumers = frame_consumers;
749
750 if self.next_frame_callbacks.is_empty() {
751 self.platform.start_display_link(display_id);
752 }
753
754 self.next_frame_callbacks
755 .entry(display_id)
756 .or_default()
757 .push(Box::new(move |cx: &mut AppContext| {
758 cx.update_window(handle, |_root_view, cx| callback(cx)).ok();
759 }));
760 }
761
762 /// Spawn the future returned by the given closure on the application thread pool.
763 /// The closure is provided a handle to the current window and an `AsyncWindowContext` for
764 /// use within your future.
765 pub fn spawn<Fut, R>(&mut self, f: impl FnOnce(AsyncWindowContext) -> Fut) -> Task<R>
766 where
767 R: 'static,
768 Fut: Future<Output = R> + 'static,
769 {
770 self.app
771 .spawn(|app| f(AsyncWindowContext::new(app, self.window.handle)))
772 }
773
774 /// Update the global of the given type. The given closure is given simultaneous mutable
775 /// access both to the global and the context.
776 pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
777 where
778 G: 'static,
779 {
780 let mut global = self.app.lease_global::<G>();
781 let result = f(&mut global, self);
782 self.app.end_global_lease(global);
783 result
784 }
785
786 #[must_use]
787 /// Add a node to the layout tree for the current frame. Takes the `Style` of the element for which
788 /// layout is being requested, along with the layout ids of any children. This method is called during
789 /// calls to the `Element::layout` trait method and enables any element to participate in layout.
790 pub fn request_layout(
791 &mut self,
792 style: &Style,
793 children: impl IntoIterator<Item = LayoutId>,
794 ) -> LayoutId {
795 self.app.layout_id_buffer.clear();
796 self.app.layout_id_buffer.extend(children);
797 let rem_size = self.rem_size();
798
799 self.window.layout_engine.as_mut().unwrap().request_layout(
800 style,
801 rem_size,
802 &self.app.layout_id_buffer,
803 )
804 }
805
806 /// Add a node to the layout tree for the current frame. Instead of taking a `Style` and children,
807 /// this variant takes a function that is invoked during layout so you can use arbitrary logic to
808 /// determine the element's size. One place this is used internally is when measuring text.
809 ///
810 /// The given closure is invoked at layout time with the known dimensions and available space and
811 /// returns a `Size`.
812 pub fn request_measured_layout<
813 F: FnMut(Size<Option<Pixels>>, Size<AvailableSpace>, &mut WindowContext) -> Size<Pixels>
814 + 'static,
815 >(
816 &mut self,
817 style: Style,
818 measure: F,
819 ) -> LayoutId {
820 let rem_size = self.rem_size();
821 self.window
822 .layout_engine
823 .as_mut()
824 .unwrap()
825 .request_measured_layout(style, rem_size, measure)
826 }
827
828 pub(crate) fn layout_style(&self, layout_id: LayoutId) -> Option<&Style> {
829 self.window
830 .layout_engine
831 .as_ref()
832 .unwrap()
833 .requested_style(layout_id)
834 }
835
836 /// Compute the layout for the given id within the given available space.
837 /// This method is called for its side effect, typically by the framework prior to painting.
838 /// After calling it, you can request the bounds of the given layout node id or any descendant.
839 pub fn compute_layout(&mut self, layout_id: LayoutId, available_space: Size<AvailableSpace>) {
840 let mut layout_engine = self.window.layout_engine.take().unwrap();
841 layout_engine.compute_layout(layout_id, available_space, self);
842 self.window.layout_engine = Some(layout_engine);
843 }
844
845 /// Obtain the bounds computed for the given LayoutId relative to the window. This method should not
846 /// be invoked until the paint phase begins, and will usually be invoked by GPUI itself automatically
847 /// in order to pass your element its `Bounds` automatically.
848 pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Bounds<Pixels> {
849 let mut bounds = self
850 .window
851 .layout_engine
852 .as_mut()
853 .unwrap()
854 .layout_bounds(layout_id)
855 .map(Into::into);
856 bounds.origin += self.element_offset();
857 bounds
858 }
859
860 fn window_bounds_changed(&mut self) {
861 self.window.scale_factor = self.window.platform_window.scale_factor();
862 self.window.viewport_size = self.window.platform_window.content_size();
863 self.window.bounds = self.window.platform_window.bounds();
864 self.window.display_id = self.window.platform_window.display().id();
865 self.refresh();
866
867 self.window
868 .bounds_observers
869 .clone()
870 .retain(&(), |callback| callback(self));
871 }
872
873 /// Returns the bounds of the current window in the global coordinate space, which could span across multiple displays.
874 pub fn window_bounds(&self) -> WindowBounds {
875 self.window.bounds
876 }
877
878 /// Returns the size of the drawable area within the window.
879 pub fn viewport_size(&self) -> Size<Pixels> {
880 self.window.viewport_size
881 }
882
883 /// Returns whether this window is focused by the operating system (receiving key events).
884 pub fn is_window_active(&self) -> bool {
885 self.window.active
886 }
887
888 /// Toggle zoom on the window.
889 pub fn zoom_window(&self) {
890 self.window.platform_window.zoom();
891 }
892
893 /// Update the window's title at the platform level.
894 pub fn set_window_title(&mut self, title: &str) {
895 self.window.platform_window.set_title(title);
896 }
897
898 /// Mark the window as dirty at the platform level.
899 pub fn set_window_edited(&mut self, edited: bool) {
900 self.window.platform_window.set_edited(edited);
901 }
902
903 /// Determine the display on which the window is visible.
904 pub fn display(&self) -> Option<Rc<dyn PlatformDisplay>> {
905 self.platform
906 .displays()
907 .into_iter()
908 .find(|display| display.id() == self.window.display_id)
909 }
910
911 /// Show the platform character palette.
912 pub fn show_character_palette(&self) {
913 self.window.platform_window.show_character_palette();
914 }
915
916 /// The scale factor of the display associated with the window. For example, it could
917 /// return 2.0 for a "retina" display, indicating that each logical pixel should actually
918 /// be rendered as two pixels on screen.
919 pub fn scale_factor(&self) -> f32 {
920 self.window.scale_factor
921 }
922
923 /// The size of an em for the base font of the application. Adjusting this value allows the
924 /// UI to scale, just like zooming a web page.
925 pub fn rem_size(&self) -> Pixels {
926 self.window.rem_size
927 }
928
929 /// Sets the size of an em for the base font of the application. Adjusting this value allows the
930 /// UI to scale, just like zooming a web page.
931 pub fn set_rem_size(&mut self, rem_size: impl Into<Pixels>) {
932 self.window.rem_size = rem_size.into();
933 }
934
935 /// The line height associated with the current text style.
936 pub fn line_height(&self) -> Pixels {
937 let rem_size = self.rem_size();
938 let text_style = self.text_style();
939 text_style
940 .line_height
941 .to_pixels(text_style.font_size, rem_size)
942 }
943
944 /// Call to prevent the default action of an event. Currently only used to prevent
945 /// parent elements from becoming focused on mouse down.
946 pub fn prevent_default(&mut self) {
947 self.window.default_prevented = true;
948 }
949
950 /// Obtain whether default has been prevented for the event currently being dispatched.
951 pub fn default_prevented(&self) -> bool {
952 self.window.default_prevented
953 }
954
955 /// Register a mouse event listener on the window for the next frame. The type of event
956 /// is determined by the first parameter of the given listener. When the next frame is rendered
957 /// the listener will be cleared.
958 pub fn on_mouse_event<Event: 'static>(
959 &mut self,
960 mut handler: impl FnMut(&Event, DispatchPhase, &mut WindowContext) + 'static,
961 ) {
962 let view_id = self.parent_view_id();
963 let order = self.window.next_frame.z_index_stack.clone();
964 self.window
965 .next_frame
966 .mouse_listeners
967 .entry(TypeId::of::<Event>())
968 .or_default()
969 .push((
970 order,
971 view_id,
972 Box::new(
973 move |event: &dyn Any, phase: DispatchPhase, cx: &mut WindowContext<'_>| {
974 handler(event.downcast_ref().unwrap(), phase, cx)
975 },
976 ),
977 ))
978 }
979
980 /// Register a key event listener on the window for the next frame. The type of event
981 /// is determined by the first parameter of the given listener. When the next frame is rendered
982 /// the listener will be cleared.
983 ///
984 /// This is a fairly low-level method, so prefer using event handlers on elements unless you have
985 /// a specific need to register a global listener.
986 pub fn on_key_event<Event: 'static>(
987 &mut self,
988 listener: impl Fn(&Event, DispatchPhase, &mut WindowContext) + 'static,
989 ) {
990 self.window.next_frame.dispatch_tree.on_key_event(Rc::new(
991 move |event: &dyn Any, phase, cx: &mut WindowContext<'_>| {
992 if let Some(event) = event.downcast_ref::<Event>() {
993 listener(event, phase, cx)
994 }
995 },
996 ));
997 }
998
999 /// Register an action listener on the window for the next frame. The type of action
1000 /// is determined by the first parameter of the given listener. When the next frame is rendered
1001 /// the listener will be cleared.
1002 ///
1003 /// This is a fairly low-level method, so prefer using action handlers on elements unless you have
1004 /// a specific need to register a global listener.
1005 pub fn on_action(
1006 &mut self,
1007 action_type: TypeId,
1008 listener: impl Fn(&dyn Any, DispatchPhase, &mut WindowContext) + 'static,
1009 ) {
1010 self.window
1011 .next_frame
1012 .dispatch_tree
1013 .on_action(action_type, Rc::new(listener));
1014 }
1015
1016 /// Determine whether the given action is available along the dispatch path to the currently focused element.
1017 pub fn is_action_available(&self, action: &dyn Action) -> bool {
1018 let target = self
1019 .focused()
1020 .and_then(|focused_handle| {
1021 self.window
1022 .rendered_frame
1023 .dispatch_tree
1024 .focusable_node_id(focused_handle.id)
1025 })
1026 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
1027 self.window
1028 .rendered_frame
1029 .dispatch_tree
1030 .is_action_available(action, target)
1031 }
1032
1033 /// The position of the mouse relative to the window.
1034 pub fn mouse_position(&self) -> Point<Pixels> {
1035 self.window.mouse_position
1036 }
1037
1038 /// The current state of the keyboard's modifiers
1039 pub fn modifiers(&self) -> Modifiers {
1040 self.window.modifiers
1041 }
1042
1043 /// Update the cursor style at the platform level.
1044 pub fn set_cursor_style(&mut self, style: CursorStyle) {
1045 let view_id = self.parent_view_id();
1046 self.window.next_frame.cursor_styles.insert(view_id, style);
1047 self.window.next_frame.requested_cursor_style = Some(style);
1048 }
1049
1050 /// Called during painting to track which z-index is on top at each pixel position
1051 pub fn add_opaque_layer(&mut self, bounds: Bounds<Pixels>) {
1052 let stacking_order = self.window.next_frame.z_index_stack.clone();
1053 let view_id = self.parent_view_id();
1054 self.window
1055 .next_frame
1056 .depth_map
1057 .push((stacking_order, view_id, bounds));
1058 }
1059
1060 /// Returns true if there is no opaque layer containing the given point
1061 /// on top of the given level. Layers whose level is an extension of the
1062 /// level are not considered to be on top of the level.
1063 pub fn was_top_layer(&self, point: &Point<Pixels>, level: &StackingOrder) -> bool {
1064 for (opaque_level, _, bounds) in self.window.rendered_frame.depth_map.iter() {
1065 if level >= opaque_level {
1066 break;
1067 }
1068
1069 if bounds.contains(point) && !opaque_level.starts_with(level) {
1070 return false;
1071 }
1072 }
1073 true
1074 }
1075
1076 pub(crate) fn was_top_layer_under_active_drag(
1077 &self,
1078 point: &Point<Pixels>,
1079 level: &StackingOrder,
1080 ) -> bool {
1081 for (opaque_level, _, bounds) in self.window.rendered_frame.depth_map.iter() {
1082 if level >= opaque_level {
1083 break;
1084 }
1085 if opaque_level.starts_with(&[ACTIVE_DRAG_Z_INDEX]) {
1086 continue;
1087 }
1088
1089 if bounds.contains(point) && !opaque_level.starts_with(level) {
1090 return false;
1091 }
1092 }
1093 true
1094 }
1095
1096 /// Called during painting to get the current stacking order.
1097 pub fn stacking_order(&self) -> &StackingOrder {
1098 &self.window.next_frame.z_index_stack
1099 }
1100
1101 /// Paint one or more drop shadows into the scene for the next frame at the current z-index.
1102 pub fn paint_shadows(
1103 &mut self,
1104 bounds: Bounds<Pixels>,
1105 corner_radii: Corners<Pixels>,
1106 shadows: &[BoxShadow],
1107 ) {
1108 let scale_factor = self.scale_factor();
1109 let content_mask = self.content_mask();
1110 let view_id = self.parent_view_id();
1111 let window = &mut *self.window;
1112 for shadow in shadows {
1113 let mut shadow_bounds = bounds;
1114 shadow_bounds.origin += shadow.offset;
1115 shadow_bounds.dilate(shadow.spread_radius);
1116 window.next_frame.scene.insert(
1117 &window.next_frame.z_index_stack,
1118 Shadow {
1119 view_id: view_id.into(),
1120 layer_id: 0,
1121 order: 0,
1122 bounds: shadow_bounds.scale(scale_factor),
1123 content_mask: content_mask.scale(scale_factor),
1124 corner_radii: corner_radii.scale(scale_factor),
1125 color: shadow.color,
1126 blur_radius: shadow.blur_radius.scale(scale_factor),
1127 },
1128 );
1129 }
1130 }
1131
1132 /// Paint one or more quads into the scene for the next frame at the current stacking context.
1133 /// Quads are colored rectangular regions with an optional background, border, and corner radius.
1134 /// see [`fill`], [`outline`], and [`quad`] to construct this type.
1135 pub fn paint_quad(&mut self, quad: PaintQuad) {
1136 let scale_factor = self.scale_factor();
1137 let content_mask = self.content_mask();
1138 let view_id = self.parent_view_id();
1139
1140 let window = &mut *self.window;
1141 window.next_frame.scene.insert(
1142 &window.next_frame.z_index_stack,
1143 Quad {
1144 view_id: view_id.into(),
1145 layer_id: 0,
1146 order: 0,
1147 bounds: quad.bounds.scale(scale_factor),
1148 content_mask: content_mask.scale(scale_factor),
1149 background: quad.background,
1150 border_color: quad.border_color,
1151 corner_radii: quad.corner_radii.scale(scale_factor),
1152 border_widths: quad.border_widths.scale(scale_factor),
1153 },
1154 );
1155 }
1156
1157 /// Paint the given `Path` into the scene for the next frame at the current z-index.
1158 pub fn paint_path(&mut self, mut path: Path<Pixels>, color: impl Into<Hsla>) {
1159 let scale_factor = self.scale_factor();
1160 let content_mask = self.content_mask();
1161 let view_id = self.parent_view_id();
1162
1163 path.content_mask = content_mask;
1164 path.color = color.into();
1165 path.view_id = view_id.into();
1166 let window = &mut *self.window;
1167 window
1168 .next_frame
1169 .scene
1170 .insert(&window.next_frame.z_index_stack, path.scale(scale_factor));
1171 }
1172
1173 /// Paint an underline into the scene for the next frame at the current z-index.
1174 pub fn paint_underline(
1175 &mut self,
1176 origin: Point<Pixels>,
1177 width: Pixels,
1178 style: &UnderlineStyle,
1179 ) {
1180 let scale_factor = self.scale_factor();
1181 let height = if style.wavy {
1182 style.thickness * 3.
1183 } else {
1184 style.thickness
1185 };
1186 let bounds = Bounds {
1187 origin,
1188 size: size(width, height),
1189 };
1190 let content_mask = self.content_mask();
1191 let view_id = self.parent_view_id();
1192
1193 let window = &mut *self.window;
1194 window.next_frame.scene.insert(
1195 &window.next_frame.z_index_stack,
1196 Underline {
1197 view_id: view_id.into(),
1198 layer_id: 0,
1199 order: 0,
1200 bounds: bounds.scale(scale_factor),
1201 content_mask: content_mask.scale(scale_factor),
1202 thickness: style.thickness.scale(scale_factor),
1203 color: style.color.unwrap_or_default(),
1204 wavy: style.wavy,
1205 },
1206 );
1207 }
1208
1209 /// Paint a monochrome (non-emoji) glyph into the scene for the next frame at the current z-index.
1210 /// The y component of the origin is the baseline of the glyph.
1211 pub fn paint_glyph(
1212 &mut self,
1213 origin: Point<Pixels>,
1214 font_id: FontId,
1215 glyph_id: GlyphId,
1216 font_size: Pixels,
1217 color: Hsla,
1218 ) -> Result<()> {
1219 let scale_factor = self.scale_factor();
1220 let glyph_origin = origin.scale(scale_factor);
1221 let subpixel_variant = Point {
1222 x: (glyph_origin.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
1223 y: (glyph_origin.y.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
1224 };
1225 let params = RenderGlyphParams {
1226 font_id,
1227 glyph_id,
1228 font_size,
1229 subpixel_variant,
1230 scale_factor,
1231 is_emoji: false,
1232 };
1233
1234 let raster_bounds = self.text_system().raster_bounds(¶ms)?;
1235 if !raster_bounds.is_zero() {
1236 let tile =
1237 self.window
1238 .sprite_atlas
1239 .get_or_insert_with(¶ms.clone().into(), &mut || {
1240 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
1241 Ok((size, Cow::Owned(bytes)))
1242 })?;
1243 let bounds = Bounds {
1244 origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
1245 size: tile.bounds.size.map(Into::into),
1246 };
1247 let content_mask = self.content_mask().scale(scale_factor);
1248 let view_id = self.parent_view_id();
1249 let window = &mut *self.window;
1250 window.next_frame.scene.insert(
1251 &window.next_frame.z_index_stack,
1252 MonochromeSprite {
1253 view_id: view_id.into(),
1254 layer_id: 0,
1255 order: 0,
1256 bounds,
1257 content_mask,
1258 color,
1259 tile,
1260 },
1261 );
1262 }
1263 Ok(())
1264 }
1265
1266 /// Paint an emoji glyph into the scene for the next frame at the current z-index.
1267 /// The y component of the origin is the baseline of the glyph.
1268 pub fn paint_emoji(
1269 &mut self,
1270 origin: Point<Pixels>,
1271 font_id: FontId,
1272 glyph_id: GlyphId,
1273 font_size: Pixels,
1274 ) -> Result<()> {
1275 let scale_factor = self.scale_factor();
1276 let glyph_origin = origin.scale(scale_factor);
1277 let params = RenderGlyphParams {
1278 font_id,
1279 glyph_id,
1280 font_size,
1281 // We don't render emojis with subpixel variants.
1282 subpixel_variant: Default::default(),
1283 scale_factor,
1284 is_emoji: true,
1285 };
1286
1287 let raster_bounds = self.text_system().raster_bounds(¶ms)?;
1288 if !raster_bounds.is_zero() {
1289 let tile =
1290 self.window
1291 .sprite_atlas
1292 .get_or_insert_with(¶ms.clone().into(), &mut || {
1293 let (size, bytes) = self.text_system().rasterize_glyph(¶ms)?;
1294 Ok((size, Cow::Owned(bytes)))
1295 })?;
1296 let bounds = Bounds {
1297 origin: glyph_origin.map(|px| px.floor()) + raster_bounds.origin.map(Into::into),
1298 size: tile.bounds.size.map(Into::into),
1299 };
1300 let content_mask = self.content_mask().scale(scale_factor);
1301 let view_id = self.parent_view_id();
1302 let window = &mut *self.window;
1303
1304 window.next_frame.scene.insert(
1305 &window.next_frame.z_index_stack,
1306 PolychromeSprite {
1307 view_id: view_id.into(),
1308 layer_id: 0,
1309 order: 0,
1310 bounds,
1311 corner_radii: Default::default(),
1312 content_mask,
1313 tile,
1314 grayscale: false,
1315 },
1316 );
1317 }
1318 Ok(())
1319 }
1320
1321 /// Paint a monochrome SVG into the scene for the next frame at the current stacking context.
1322 pub fn paint_svg(
1323 &mut self,
1324 bounds: Bounds<Pixels>,
1325 path: SharedString,
1326 color: Hsla,
1327 ) -> Result<()> {
1328 let scale_factor = self.scale_factor();
1329 let bounds = bounds.scale(scale_factor);
1330 // Render the SVG at twice the size to get a higher quality result.
1331 let params = RenderSvgParams {
1332 path,
1333 size: bounds
1334 .size
1335 .map(|pixels| DevicePixels::from((pixels.0 * 2.).ceil() as i32)),
1336 };
1337
1338 let tile =
1339 self.window
1340 .sprite_atlas
1341 .get_or_insert_with(¶ms.clone().into(), &mut || {
1342 let bytes = self.svg_renderer.render(¶ms)?;
1343 Ok((params.size, Cow::Owned(bytes)))
1344 })?;
1345 let content_mask = self.content_mask().scale(scale_factor);
1346 let view_id = self.parent_view_id();
1347
1348 let window = &mut *self.window;
1349 window.next_frame.scene.insert(
1350 &window.next_frame.z_index_stack,
1351 MonochromeSprite {
1352 view_id: view_id.into(),
1353 layer_id: 0,
1354 order: 0,
1355 bounds,
1356 content_mask,
1357 color,
1358 tile,
1359 },
1360 );
1361
1362 Ok(())
1363 }
1364
1365 /// Paint an image into the scene for the next frame at the current z-index.
1366 pub fn paint_image(
1367 &mut self,
1368 bounds: Bounds<Pixels>,
1369 corner_radii: Corners<Pixels>,
1370 data: Arc<ImageData>,
1371 grayscale: bool,
1372 ) -> Result<()> {
1373 let scale_factor = self.scale_factor();
1374 let bounds = bounds.scale(scale_factor);
1375 let params = RenderImageParams { image_id: data.id };
1376
1377 let tile = self
1378 .window
1379 .sprite_atlas
1380 .get_or_insert_with(¶ms.clone().into(), &mut || {
1381 Ok((data.size(), Cow::Borrowed(data.as_bytes())))
1382 })?;
1383 let content_mask = self.content_mask().scale(scale_factor);
1384 let corner_radii = corner_radii.scale(scale_factor);
1385 let view_id = self.parent_view_id();
1386
1387 let window = &mut *self.window;
1388 window.next_frame.scene.insert(
1389 &window.next_frame.z_index_stack,
1390 PolychromeSprite {
1391 view_id: view_id.into(),
1392 layer_id: 0,
1393 order: 0,
1394 bounds,
1395 content_mask,
1396 corner_radii,
1397 tile,
1398 grayscale,
1399 },
1400 );
1401 Ok(())
1402 }
1403
1404 /// Paint a surface into the scene for the next frame at the current z-index.
1405 pub fn paint_surface(&mut self, bounds: Bounds<Pixels>, image_buffer: CVImageBuffer) {
1406 let scale_factor = self.scale_factor();
1407 let bounds = bounds.scale(scale_factor);
1408 let content_mask = self.content_mask().scale(scale_factor);
1409 let view_id = self.parent_view_id();
1410 let window = &mut *self.window;
1411 window.next_frame.scene.insert(
1412 &window.next_frame.z_index_stack,
1413 Surface {
1414 view_id: view_id.into(),
1415 layer_id: 0,
1416 order: 0,
1417 bounds,
1418 content_mask,
1419 image_buffer,
1420 },
1421 );
1422 }
1423
1424 pub(crate) fn reuse_view(&mut self) {
1425 let view_id = self.parent_view_id();
1426 let grafted_view_ids = self
1427 .window
1428 .next_frame
1429 .dispatch_tree
1430 .graft(view_id, &mut self.window.rendered_frame.dispatch_tree);
1431 for view_id in grafted_view_ids {
1432 assert!(self.window.next_frame.reused_views.insert(view_id));
1433
1434 // Reuse the previous input handler if it was associated with one of
1435 // the views grafted from the tree in the previous frame.
1436 if self
1437 .window
1438 .rendered_frame
1439 .requested_input_handler
1440 .as_ref()
1441 .map_or(false, |requested| requested.view_id == view_id)
1442 {
1443 self.window.next_frame.requested_input_handler =
1444 self.window.rendered_frame.requested_input_handler.take();
1445 }
1446
1447 if let Some(style) = self.window.rendered_frame.cursor_styles.remove(&view_id) {
1448 self.window.next_frame.cursor_styles.insert(view_id, style);
1449 self.window.next_frame.requested_cursor_style = Some(style);
1450 }
1451 }
1452 }
1453
1454 /// Draw pixels to the display for this window based on the contents of its scene.
1455 pub(crate) fn draw(&mut self) {
1456 self.window.dirty = false;
1457 self.window.drawing = true;
1458
1459 #[cfg(any(test, feature = "test-support"))]
1460 {
1461 self.window.focus_invalidated = false;
1462 }
1463
1464 self.text_system().start_frame();
1465 if let Some(requested_handler) = self.window.rendered_frame.requested_input_handler.as_mut()
1466 {
1467 requested_handler.handler = self.window.platform_window.take_input_handler();
1468 }
1469
1470 self.window.layout_engine.as_mut().unwrap().clear();
1471 self.window.next_frame.clear();
1472 let root_view = self.window.root_view.take().unwrap();
1473
1474 self.with_z_index(0, |cx| {
1475 cx.with_key_dispatch(Some(KeyContext::default()), None, |_, cx| {
1476 for (action_type, action_listeners) in &cx.app.global_action_listeners {
1477 for action_listener in action_listeners.iter().cloned() {
1478 cx.window.next_frame.dispatch_tree.on_action(
1479 *action_type,
1480 Rc::new(move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| {
1481 action_listener(action, phase, cx)
1482 }),
1483 )
1484 }
1485 }
1486
1487 let available_space = cx.window.viewport_size.map(Into::into);
1488 root_view.draw(Point::default(), available_space, cx);
1489 })
1490 });
1491
1492 if let Some(active_drag) = self.app.active_drag.take() {
1493 self.with_z_index(ACTIVE_DRAG_Z_INDEX, |cx| {
1494 let offset = cx.mouse_position() - active_drag.cursor_offset;
1495 let available_space = size(AvailableSpace::MinContent, AvailableSpace::MinContent);
1496 active_drag.view.draw(offset, available_space, cx);
1497 });
1498 self.active_drag = Some(active_drag);
1499 } else if let Some(active_tooltip) = self.app.active_tooltip.take() {
1500 self.with_z_index(1, |cx| {
1501 let available_space = size(AvailableSpace::MinContent, AvailableSpace::MinContent);
1502 active_tooltip
1503 .view
1504 .draw(active_tooltip.cursor_offset, available_space, cx);
1505 });
1506 }
1507 self.window.dirty_views.clear();
1508
1509 self.window
1510 .next_frame
1511 .dispatch_tree
1512 .preserve_pending_keystrokes(
1513 &mut self.window.rendered_frame.dispatch_tree,
1514 self.window.focus,
1515 );
1516 self.window.next_frame.focus = self.window.focus;
1517 self.window.next_frame.window_active = self.window.active;
1518 self.window.root_view = Some(root_view);
1519
1520 // Set the cursor only if we're the active window.
1521 let cursor_style = self
1522 .window
1523 .next_frame
1524 .requested_cursor_style
1525 .take()
1526 .unwrap_or(CursorStyle::Arrow);
1527 if self.is_window_active() {
1528 self.platform.set_cursor_style(cursor_style);
1529 }
1530
1531 self.window
1532 .next_frame
1533 .reuse_views(&mut self.window.rendered_frame);
1534 self.window.next_frame.scene.finish();
1535
1536 // Register requested input handler with the platform window.
1537 if let Some(requested_input) = self.window.next_frame.requested_input_handler.as_mut() {
1538 if let Some(handler) = requested_input.handler.take() {
1539 self.window.platform_window.set_input_handler(handler);
1540 }
1541 }
1542
1543 let previous_focus_path = self.window.rendered_frame.focus_path();
1544 let previous_window_active = self.window.rendered_frame.window_active;
1545 mem::swap(&mut self.window.rendered_frame, &mut self.window.next_frame);
1546 let current_focus_path = self.window.rendered_frame.focus_path();
1547 let current_window_active = self.window.rendered_frame.window_active;
1548
1549 self.window.refreshing = false;
1550 self.window.drawing = false;
1551 ELEMENT_ARENA.with_borrow_mut(|element_arena| element_arena.clear());
1552
1553 if previous_focus_path != current_focus_path
1554 || previous_window_active != current_window_active
1555 {
1556 if !previous_focus_path.is_empty() && current_focus_path.is_empty() {
1557 self.window
1558 .focus_lost_listeners
1559 .clone()
1560 .retain(&(), |listener| listener(self));
1561 }
1562
1563 let event = FocusEvent {
1564 previous_focus_path: if previous_window_active {
1565 previous_focus_path
1566 } else {
1567 Default::default()
1568 },
1569 current_focus_path: if current_window_active {
1570 current_focus_path
1571 } else {
1572 Default::default()
1573 },
1574 };
1575 self.window
1576 .focus_listeners
1577 .clone()
1578 .retain(&(), |listener| listener(&event, self));
1579 }
1580
1581 self.window
1582 .platform_window
1583 .draw(&self.window.rendered_frame.scene);
1584 }
1585
1586 /// Dispatch a mouse or keyboard event on the window.
1587 pub fn dispatch_event(&mut self, event: InputEvent) -> bool {
1588 // Handlers may set this to false by calling `stop_propagation`.
1589 self.app.propagate_event = true;
1590 // Handlers may set this to true by calling `prevent_default`.
1591 self.window.default_prevented = false;
1592
1593 let event = match event {
1594 // Track the mouse position with our own state, since accessing the platform
1595 // API for the mouse position can only occur on the main thread.
1596 InputEvent::MouseMove(mouse_move) => {
1597 self.window.mouse_position = mouse_move.position;
1598 self.window.modifiers = mouse_move.modifiers;
1599 InputEvent::MouseMove(mouse_move)
1600 }
1601 InputEvent::MouseDown(mouse_down) => {
1602 self.window.mouse_position = mouse_down.position;
1603 self.window.modifiers = mouse_down.modifiers;
1604 InputEvent::MouseDown(mouse_down)
1605 }
1606 InputEvent::MouseUp(mouse_up) => {
1607 self.window.mouse_position = mouse_up.position;
1608 self.window.modifiers = mouse_up.modifiers;
1609 InputEvent::MouseUp(mouse_up)
1610 }
1611 InputEvent::MouseExited(mouse_exited) => {
1612 self.window.modifiers = mouse_exited.modifiers;
1613 InputEvent::MouseExited(mouse_exited)
1614 }
1615 InputEvent::ModifiersChanged(modifiers_changed) => {
1616 self.window.modifiers = modifiers_changed.modifiers;
1617 InputEvent::ModifiersChanged(modifiers_changed)
1618 }
1619 InputEvent::ScrollWheel(scroll_wheel) => {
1620 self.window.mouse_position = scroll_wheel.position;
1621 self.window.modifiers = scroll_wheel.modifiers;
1622 InputEvent::ScrollWheel(scroll_wheel)
1623 }
1624 // Translate dragging and dropping of external files from the operating system
1625 // to internal drag and drop events.
1626 InputEvent::FileDrop(file_drop) => match file_drop {
1627 FileDropEvent::Entered { position, paths } => {
1628 self.window.mouse_position = position;
1629 if self.active_drag.is_none() {
1630 self.active_drag = Some(AnyDrag {
1631 value: Box::new(paths.clone()),
1632 view: self.new_view(|_| paths).into(),
1633 cursor_offset: position,
1634 });
1635 }
1636 InputEvent::MouseMove(MouseMoveEvent {
1637 position,
1638 pressed_button: Some(MouseButton::Left),
1639 modifiers: Modifiers::default(),
1640 })
1641 }
1642 FileDropEvent::Pending { position } => {
1643 self.window.mouse_position = position;
1644 InputEvent::MouseMove(MouseMoveEvent {
1645 position,
1646 pressed_button: Some(MouseButton::Left),
1647 modifiers: Modifiers::default(),
1648 })
1649 }
1650 FileDropEvent::Submit { position } => {
1651 self.activate(true);
1652 self.window.mouse_position = position;
1653 InputEvent::MouseUp(MouseUpEvent {
1654 button: MouseButton::Left,
1655 position,
1656 modifiers: Modifiers::default(),
1657 click_count: 1,
1658 })
1659 }
1660 FileDropEvent::Exited => InputEvent::MouseUp(MouseUpEvent {
1661 button: MouseButton::Left,
1662 position: Point::default(),
1663 modifiers: Modifiers::default(),
1664 click_count: 1,
1665 }),
1666 },
1667 InputEvent::KeyDown(_) | InputEvent::KeyUp(_) => event,
1668 };
1669
1670 if let Some(any_mouse_event) = event.mouse_event() {
1671 self.dispatch_mouse_event(any_mouse_event);
1672 } else if let Some(any_key_event) = event.keyboard_event() {
1673 self.dispatch_key_event(any_key_event);
1674 }
1675
1676 !self.app.propagate_event
1677 }
1678
1679 fn dispatch_mouse_event(&mut self, event: &dyn Any) {
1680 if let Some(mut handlers) = self
1681 .window
1682 .rendered_frame
1683 .mouse_listeners
1684 .remove(&event.type_id())
1685 {
1686 // Because handlers may add other handlers, we sort every time.
1687 handlers.sort_by(|(a, _, _), (b, _, _)| a.cmp(b));
1688
1689 // Capture phase, events bubble from back to front. Handlers for this phase are used for
1690 // special purposes, such as detecting events outside of a given Bounds.
1691 for (_, _, handler) in &mut handlers {
1692 handler(event, DispatchPhase::Capture, self);
1693 if !self.app.propagate_event {
1694 break;
1695 }
1696 }
1697
1698 // Bubble phase, where most normal handlers do their work.
1699 if self.app.propagate_event {
1700 for (_, _, handler) in handlers.iter_mut().rev() {
1701 handler(event, DispatchPhase::Bubble, self);
1702 if !self.app.propagate_event {
1703 break;
1704 }
1705 }
1706 }
1707
1708 self.window
1709 .rendered_frame
1710 .mouse_listeners
1711 .insert(event.type_id(), handlers);
1712 }
1713
1714 if self.app.propagate_event && self.has_active_drag() {
1715 if event.is::<MouseMoveEvent>() {
1716 // If this was a mouse move event, redraw the window so that the
1717 // active drag can follow the mouse cursor.
1718 self.refresh();
1719 } else if event.is::<MouseUpEvent>() {
1720 // If this was a mouse up event, cancel the active drag and redraw
1721 // the window.
1722 self.active_drag = None;
1723 self.refresh();
1724 }
1725 }
1726 }
1727
1728 fn dispatch_key_event(&mut self, event: &dyn Any) {
1729 let node_id = self
1730 .window
1731 .focus
1732 .and_then(|focus_id| {
1733 self.window
1734 .rendered_frame
1735 .dispatch_tree
1736 .focusable_node_id(focus_id)
1737 })
1738 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
1739
1740 let dispatch_path = self
1741 .window
1742 .rendered_frame
1743 .dispatch_tree
1744 .dispatch_path(node_id);
1745
1746 let mut actions: Vec<Box<dyn Action>> = Vec::new();
1747
1748 let mut context_stack: SmallVec<[KeyContext; 16]> = SmallVec::new();
1749 for node_id in &dispatch_path {
1750 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1751
1752 if let Some(context) = node.context.clone() {
1753 context_stack.push(context);
1754 }
1755 }
1756
1757 for node_id in dispatch_path.iter().rev() {
1758 // Match keystrokes
1759 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1760 if node.context.is_some() {
1761 if let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() {
1762 let mut new_actions = self
1763 .window
1764 .rendered_frame
1765 .dispatch_tree
1766 .dispatch_key(&key_down_event.keystroke, &context_stack);
1767 actions.append(&mut new_actions);
1768 }
1769
1770 context_stack.pop();
1771 }
1772 }
1773
1774 if !actions.is_empty() {
1775 self.clear_pending_keystrokes();
1776 }
1777
1778 self.propagate_event = true;
1779 for action in actions {
1780 self.dispatch_action_on_node(node_id, action.boxed_clone());
1781 if !self.propagate_event {
1782 self.dispatch_keystroke_observers(event, Some(action));
1783 return;
1784 }
1785 }
1786
1787 // Capture phase
1788 for node_id in &dispatch_path {
1789 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1790
1791 for key_listener in node.key_listeners.clone() {
1792 key_listener(event, DispatchPhase::Capture, self);
1793 if !self.propagate_event {
1794 return;
1795 }
1796 }
1797 }
1798
1799 // Bubble phase
1800 for node_id in dispatch_path.iter().rev() {
1801 // Handle low level key events
1802 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1803 for key_listener in node.key_listeners.clone() {
1804 key_listener(event, DispatchPhase::Bubble, self);
1805 if !self.propagate_event {
1806 return;
1807 }
1808 }
1809 }
1810
1811 self.dispatch_keystroke_observers(event, None);
1812 }
1813
1814 /// Determine whether a potential multi-stroke key binding is in progress on this window.
1815 pub fn has_pending_keystrokes(&self) -> bool {
1816 self.window
1817 .rendered_frame
1818 .dispatch_tree
1819 .has_pending_keystrokes()
1820 }
1821
1822 fn dispatch_action_on_node(&mut self, node_id: DispatchNodeId, action: Box<dyn Action>) {
1823 let dispatch_path = self
1824 .window
1825 .rendered_frame
1826 .dispatch_tree
1827 .dispatch_path(node_id);
1828
1829 // Capture phase
1830 for node_id in &dispatch_path {
1831 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1832 for DispatchActionListener {
1833 action_type,
1834 listener,
1835 } in node.action_listeners.clone()
1836 {
1837 let any_action = action.as_any();
1838 if action_type == any_action.type_id() {
1839 listener(any_action, DispatchPhase::Capture, self);
1840 if !self.propagate_event {
1841 return;
1842 }
1843 }
1844 }
1845 }
1846 // Bubble phase
1847 for node_id in dispatch_path.iter().rev() {
1848 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1849 for DispatchActionListener {
1850 action_type,
1851 listener,
1852 } in node.action_listeners.clone()
1853 {
1854 let any_action = action.as_any();
1855 if action_type == any_action.type_id() {
1856 self.propagate_event = false; // Actions stop propagation by default during the bubble phase
1857 listener(any_action, DispatchPhase::Bubble, self);
1858 if !self.propagate_event {
1859 return;
1860 }
1861 }
1862 }
1863 }
1864 }
1865
1866 /// Register the given handler to be invoked whenever the global of the given type
1867 /// is updated.
1868 pub fn observe_global<G: 'static>(
1869 &mut self,
1870 f: impl Fn(&mut WindowContext<'_>) + 'static,
1871 ) -> Subscription {
1872 let window_handle = self.window.handle;
1873 let (subscription, activate) = self.global_observers.insert(
1874 TypeId::of::<G>(),
1875 Box::new(move |cx| window_handle.update(cx, |_, cx| f(cx)).is_ok()),
1876 );
1877 self.app.defer(move |_| activate());
1878 subscription
1879 }
1880
1881 /// Focus the current window and bring it to the foreground at the platform level.
1882 pub fn activate_window(&self) {
1883 self.window.platform_window.activate();
1884 }
1885
1886 /// Minimize the current window at the platform level.
1887 pub fn minimize_window(&self) {
1888 self.window.platform_window.minimize();
1889 }
1890
1891 /// Toggle full screen status on the current window at the platform level.
1892 pub fn toggle_full_screen(&self) {
1893 self.window.platform_window.toggle_full_screen();
1894 }
1895
1896 /// Present a platform dialog.
1897 /// The provided message will be presented, along with buttons for each answer.
1898 /// When a button is clicked, the returned Receiver will receive the index of the clicked button.
1899 pub fn prompt(
1900 &self,
1901 level: PromptLevel,
1902 message: &str,
1903 answers: &[&str],
1904 ) -> oneshot::Receiver<usize> {
1905 self.window.platform_window.prompt(level, message, answers)
1906 }
1907
1908 /// Returns all available actions for the focused element.
1909 pub fn available_actions(&self) -> Vec<Box<dyn Action>> {
1910 let node_id = self
1911 .window
1912 .focus
1913 .and_then(|focus_id| {
1914 self.window
1915 .rendered_frame
1916 .dispatch_tree
1917 .focusable_node_id(focus_id)
1918 })
1919 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
1920
1921 self.window
1922 .rendered_frame
1923 .dispatch_tree
1924 .available_actions(node_id)
1925 }
1926
1927 /// Returns key bindings that invoke the given action on the currently focused element.
1928 pub fn bindings_for_action(&self, action: &dyn Action) -> Vec<KeyBinding> {
1929 self.window
1930 .rendered_frame
1931 .dispatch_tree
1932 .bindings_for_action(
1933 action,
1934 &self.window.rendered_frame.dispatch_tree.context_stack,
1935 )
1936 }
1937
1938 /// Returns any bindings that would invoke the given action on the given focus handle if it were focused.
1939 pub fn bindings_for_action_in(
1940 &self,
1941 action: &dyn Action,
1942 focus_handle: &FocusHandle,
1943 ) -> Vec<KeyBinding> {
1944 let dispatch_tree = &self.window.rendered_frame.dispatch_tree;
1945
1946 let Some(node_id) = dispatch_tree.focusable_node_id(focus_handle.id) else {
1947 return vec![];
1948 };
1949 let context_stack = dispatch_tree
1950 .dispatch_path(node_id)
1951 .into_iter()
1952 .filter_map(|node_id| dispatch_tree.node(node_id).context.clone())
1953 .collect();
1954 dispatch_tree.bindings_for_action(action, &context_stack)
1955 }
1956
1957 /// Returns a generic event listener that invokes the given listener with the view and context associated with the given view handle.
1958 pub fn listener_for<V: Render, E>(
1959 &self,
1960 view: &View<V>,
1961 f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
1962 ) -> impl Fn(&E, &mut WindowContext) + 'static {
1963 let view = view.downgrade();
1964 move |e: &E, cx: &mut WindowContext| {
1965 view.update(cx, |view, cx| f(view, e, cx)).ok();
1966 }
1967 }
1968
1969 /// Returns a generic handler that invokes the given handler with the view and context associated with the given view handle.
1970 pub fn handler_for<V: Render>(
1971 &self,
1972 view: &View<V>,
1973 f: impl Fn(&mut V, &mut ViewContext<V>) + 'static,
1974 ) -> impl Fn(&mut WindowContext) {
1975 let view = view.downgrade();
1976 move |cx: &mut WindowContext| {
1977 view.update(cx, |view, cx| f(view, cx)).ok();
1978 }
1979 }
1980
1981 /// Invoke the given function with the given focus handle present on the key dispatch stack.
1982 /// If you want an element to participate in key dispatch, use this method to push its key context and focus handle into the stack during paint.
1983 pub fn with_key_dispatch<R>(
1984 &mut self,
1985 context: Option<KeyContext>,
1986 focus_handle: Option<FocusHandle>,
1987 f: impl FnOnce(Option<FocusHandle>, &mut Self) -> R,
1988 ) -> R {
1989 let window = &mut self.window;
1990 let focus_id = focus_handle.as_ref().map(|handle| handle.id);
1991 window
1992 .next_frame
1993 .dispatch_tree
1994 .push_node(context.clone(), focus_id, None);
1995
1996 let result = f(focus_handle, self);
1997
1998 self.window.next_frame.dispatch_tree.pop_node();
1999
2000 result
2001 }
2002
2003 pub(crate) fn with_view_id<R>(
2004 &mut self,
2005 view_id: EntityId,
2006 f: impl FnOnce(&mut Self) -> R,
2007 ) -> R {
2008 self.window.next_frame.view_stack.push(view_id);
2009 let result = f(self);
2010 self.window.next_frame.view_stack.pop();
2011 result
2012 }
2013
2014 pub(crate) fn paint_view<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
2015 self.with_view_id(view_id, |cx| {
2016 cx.window
2017 .next_frame
2018 .dispatch_tree
2019 .push_node(None, None, Some(view_id));
2020 let result = f(cx);
2021 cx.window.next_frame.dispatch_tree.pop_node();
2022 result
2023 })
2024 }
2025
2026 /// Update or initialize state for an element with the given id that lives across multiple
2027 /// frames. If an element with this id existed in the rendered frame, its state will be passed
2028 /// to the given closure. The state returned by the closure will be stored so it can be referenced
2029 /// when drawing the next frame.
2030 pub(crate) fn with_element_state<S, R>(
2031 &mut self,
2032 id: ElementId,
2033 f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
2034 ) -> R
2035 where
2036 S: 'static,
2037 {
2038 self.with_element_id(Some(id), |cx| {
2039 let global_id = cx.window().element_id_stack.clone();
2040
2041 if let Some(any) = cx
2042 .window_mut()
2043 .next_frame
2044 .element_states
2045 .remove(&global_id)
2046 .or_else(|| {
2047 cx.window_mut()
2048 .rendered_frame
2049 .element_states
2050 .remove(&global_id)
2051 })
2052 {
2053 let ElementStateBox {
2054 inner,
2055 parent_view_id,
2056 #[cfg(debug_assertions)]
2057 type_name
2058 } = any;
2059 // Using the extra inner option to avoid needing to reallocate a new box.
2060 let mut state_box = inner
2061 .downcast::<Option<S>>()
2062 .map_err(|_| {
2063 #[cfg(debug_assertions)]
2064 {
2065 anyhow!(
2066 "invalid element state type for id, requested_type {:?}, actual type: {:?}",
2067 std::any::type_name::<S>(),
2068 type_name
2069 )
2070 }
2071
2072 #[cfg(not(debug_assertions))]
2073 {
2074 anyhow!(
2075 "invalid element state type for id, requested_type {:?}",
2076 std::any::type_name::<S>(),
2077 )
2078 }
2079 })
2080 .unwrap();
2081
2082 // Actual: Option<AnyElement> <- View
2083 // Requested: () <- AnyElemet
2084 let state = state_box
2085 .take()
2086 .expect("element state is already on the stack");
2087 let (result, state) = f(Some(state), cx);
2088 state_box.replace(state);
2089 cx.window_mut()
2090 .next_frame
2091 .element_states
2092 .insert(global_id, ElementStateBox {
2093 inner: state_box,
2094 parent_view_id,
2095 #[cfg(debug_assertions)]
2096 type_name
2097 });
2098 result
2099 } else {
2100 let (result, state) = f(None, cx);
2101 let parent_view_id = cx.parent_view_id();
2102 cx.window_mut()
2103 .next_frame
2104 .element_states
2105 .insert(global_id,
2106 ElementStateBox {
2107 inner: Box::new(Some(state)),
2108 parent_view_id,
2109 #[cfg(debug_assertions)]
2110 type_name: std::any::type_name::<S>()
2111 }
2112
2113 );
2114 result
2115 }
2116 })
2117 }
2118
2119 fn parent_view_id(&self) -> EntityId {
2120 *self
2121 .window
2122 .next_frame
2123 .view_stack
2124 .last()
2125 .expect("a view should always be on the stack while drawing")
2126 }
2127
2128 /// Set an input handler, such as [`ElementInputHandler`][element_input_handler], which interfaces with the
2129 /// platform to receive textual input with proper integration with concerns such
2130 /// as IME interactions.
2131 ///
2132 /// [element_input_handler]: crate::ElementInputHandler
2133 pub fn handle_input(
2134 &mut self,
2135 focus_handle: &FocusHandle,
2136 input_handler: impl PlatformInputHandler,
2137 ) {
2138 if focus_handle.is_focused(self) {
2139 let view_id = self.parent_view_id();
2140 self.window.next_frame.requested_input_handler = Some(RequestedInputHandler {
2141 view_id,
2142 handler: Some(Box::new(input_handler)),
2143 })
2144 }
2145 }
2146
2147 /// Register a callback that can interrupt the closing of the current window based the returned boolean.
2148 /// If the callback returns false, the window won't be closed.
2149 pub fn on_window_should_close(&mut self, f: impl Fn(&mut WindowContext) -> bool + 'static) {
2150 let mut this = self.to_async();
2151 self.window
2152 .platform_window
2153 .on_should_close(Box::new(move || this.update(|_, cx| f(cx)).unwrap_or(true)))
2154 }
2155}
2156
2157impl Context for WindowContext<'_> {
2158 type Result<T> = T;
2159
2160 fn new_model<T>(&mut self, build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T) -> Model<T>
2161 where
2162 T: 'static,
2163 {
2164 let slot = self.app.entities.reserve();
2165 let model = build_model(&mut ModelContext::new(&mut *self.app, slot.downgrade()));
2166 self.entities.insert(slot, model)
2167 }
2168
2169 fn update_model<T: 'static, R>(
2170 &mut self,
2171 model: &Model<T>,
2172 update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
2173 ) -> R {
2174 let mut entity = self.entities.lease(model);
2175 let result = update(
2176 &mut *entity,
2177 &mut ModelContext::new(&mut *self.app, model.downgrade()),
2178 );
2179 self.entities.end_lease(entity);
2180 result
2181 }
2182
2183 fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
2184 where
2185 F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
2186 {
2187 if window == self.window.handle {
2188 let root_view = self.window.root_view.clone().unwrap();
2189 Ok(update(root_view, self))
2190 } else {
2191 window.update(self.app, update)
2192 }
2193 }
2194
2195 fn read_model<T, R>(
2196 &self,
2197 handle: &Model<T>,
2198 read: impl FnOnce(&T, &AppContext) -> R,
2199 ) -> Self::Result<R>
2200 where
2201 T: 'static,
2202 {
2203 let entity = self.entities.read(handle);
2204 read(entity, &*self.app)
2205 }
2206
2207 fn read_window<T, R>(
2208 &self,
2209 window: &WindowHandle<T>,
2210 read: impl FnOnce(View<T>, &AppContext) -> R,
2211 ) -> Result<R>
2212 where
2213 T: 'static,
2214 {
2215 if window.any_handle == self.window.handle {
2216 let root_view = self
2217 .window
2218 .root_view
2219 .clone()
2220 .unwrap()
2221 .downcast::<T>()
2222 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
2223 Ok(read(root_view, self))
2224 } else {
2225 self.app.read_window(window, read)
2226 }
2227 }
2228}
2229
2230impl VisualContext for WindowContext<'_> {
2231 fn new_view<V>(
2232 &mut self,
2233 build_view_state: impl FnOnce(&mut ViewContext<'_, V>) -> V,
2234 ) -> Self::Result<View<V>>
2235 where
2236 V: 'static + Render,
2237 {
2238 let slot = self.app.entities.reserve();
2239 let view = View {
2240 model: slot.clone(),
2241 };
2242 let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view);
2243 let entity = build_view_state(&mut cx);
2244 cx.entities.insert(slot, entity);
2245
2246 cx.new_view_observers
2247 .clone()
2248 .retain(&TypeId::of::<V>(), |observer| {
2249 let any_view = AnyView::from(view.clone());
2250 (observer)(any_view, self);
2251 true
2252 });
2253
2254 view
2255 }
2256
2257 /// Update the given view. Prefer calling `View::update` instead, which calls this method.
2258 fn update_view<T: 'static, R>(
2259 &mut self,
2260 view: &View<T>,
2261 update: impl FnOnce(&mut T, &mut ViewContext<'_, T>) -> R,
2262 ) -> Self::Result<R> {
2263 let mut lease = self.app.entities.lease(&view.model);
2264 let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, view);
2265 let result = update(&mut *lease, &mut cx);
2266 cx.app.entities.end_lease(lease);
2267 result
2268 }
2269
2270 fn replace_root_view<V>(
2271 &mut self,
2272 build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V,
2273 ) -> Self::Result<View<V>>
2274 where
2275 V: 'static + Render,
2276 {
2277 let view = self.new_view(build_view);
2278 self.window.root_view = Some(view.clone().into());
2279 self.refresh();
2280 view
2281 }
2282
2283 fn focus_view<V: crate::FocusableView>(&mut self, view: &View<V>) -> Self::Result<()> {
2284 self.update_view(view, |view, cx| {
2285 view.focus_handle(cx).clone().focus(cx);
2286 })
2287 }
2288
2289 fn dismiss_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
2290 where
2291 V: ManagedView,
2292 {
2293 self.update_view(view, |_, cx| cx.emit(DismissEvent))
2294 }
2295}
2296
2297impl<'a> std::ops::Deref for WindowContext<'a> {
2298 type Target = AppContext;
2299
2300 fn deref(&self) -> &Self::Target {
2301 self.app
2302 }
2303}
2304
2305impl<'a> std::ops::DerefMut for WindowContext<'a> {
2306 fn deref_mut(&mut self) -> &mut Self::Target {
2307 self.app
2308 }
2309}
2310
2311impl<'a> Borrow<AppContext> for WindowContext<'a> {
2312 fn borrow(&self) -> &AppContext {
2313 self.app
2314 }
2315}
2316
2317impl<'a> BorrowMut<AppContext> for WindowContext<'a> {
2318 fn borrow_mut(&mut self) -> &mut AppContext {
2319 self.app
2320 }
2321}
2322
2323/// This trait contains functionality that is shared across [`ViewContext`] and [`WindowContext`]
2324pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
2325 #[doc(hidden)]
2326 fn app_mut(&mut self) -> &mut AppContext {
2327 self.borrow_mut()
2328 }
2329
2330 #[doc(hidden)]
2331 fn app(&self) -> &AppContext {
2332 self.borrow()
2333 }
2334
2335 #[doc(hidden)]
2336 fn window(&self) -> &Window {
2337 self.borrow()
2338 }
2339
2340 #[doc(hidden)]
2341 fn window_mut(&mut self) -> &mut Window {
2342 self.borrow_mut()
2343 }
2344
2345 /// Pushes the given element id onto the global stack and invokes the given closure
2346 /// with a `GlobalElementId`, which disambiguates the given id in the context of its ancestor
2347 /// ids. Because elements are discarded and recreated on each frame, the `GlobalElementId` is
2348 /// used to associate state with identified elements across separate frames.
2349 fn with_element_id<R>(
2350 &mut self,
2351 id: Option<impl Into<ElementId>>,
2352 f: impl FnOnce(&mut Self) -> R,
2353 ) -> R {
2354 if let Some(id) = id.map(Into::into) {
2355 let window = self.window_mut();
2356 window.element_id_stack.push(id);
2357 let result = f(self);
2358 let window: &mut Window = self.borrow_mut();
2359 window.element_id_stack.pop();
2360 result
2361 } else {
2362 f(self)
2363 }
2364 }
2365
2366 /// Invoke the given function with the given content mask after intersecting it
2367 /// with the current mask.
2368 fn with_content_mask<R>(
2369 &mut self,
2370 mask: Option<ContentMask<Pixels>>,
2371 f: impl FnOnce(&mut Self) -> R,
2372 ) -> R {
2373 if let Some(mask) = mask {
2374 let mask = mask.intersect(&self.content_mask());
2375 self.window_mut().next_frame.content_mask_stack.push(mask);
2376 let result = f(self);
2377 self.window_mut().next_frame.content_mask_stack.pop();
2378 result
2379 } else {
2380 f(self)
2381 }
2382 }
2383
2384 /// Invoke the given function with the content mask reset to that
2385 /// of the window.
2386 fn break_content_mask<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
2387 let mask = ContentMask {
2388 bounds: Bounds {
2389 origin: Point::default(),
2390 size: self.window().viewport_size,
2391 },
2392 };
2393 let new_stacking_order_id =
2394 post_inc(&mut self.window_mut().next_frame.next_stacking_order_id);
2395 let old_stacking_order = mem::take(&mut self.window_mut().next_frame.z_index_stack);
2396 self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id;
2397 self.window_mut().next_frame.content_mask_stack.push(mask);
2398 let result = f(self);
2399 self.window_mut().next_frame.content_mask_stack.pop();
2400 self.window_mut().next_frame.z_index_stack = old_stacking_order;
2401 result
2402 }
2403
2404 /// Called during painting to invoke the given closure in a new stacking context. The given
2405 /// z-index is interpreted relative to the previous call to `stack`.
2406 fn with_z_index<R>(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R {
2407 let new_stacking_order_id =
2408 post_inc(&mut self.window_mut().next_frame.next_stacking_order_id);
2409 let old_stacking_order_id = mem::replace(
2410 &mut self.window_mut().next_frame.z_index_stack.id,
2411 new_stacking_order_id,
2412 );
2413 self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id;
2414 self.window_mut().next_frame.z_index_stack.push(z_index);
2415 let result = f(self);
2416 self.window_mut().next_frame.z_index_stack.id = old_stacking_order_id;
2417 self.window_mut().next_frame.z_index_stack.pop();
2418 result
2419 }
2420
2421 /// Update the global element offset relative to the current offset. This is used to implement
2422 /// scrolling.
2423 fn with_element_offset<R>(
2424 &mut self,
2425 offset: Point<Pixels>,
2426 f: impl FnOnce(&mut Self) -> R,
2427 ) -> R {
2428 if offset.is_zero() {
2429 return f(self);
2430 };
2431
2432 let abs_offset = self.element_offset() + offset;
2433 self.with_absolute_element_offset(abs_offset, f)
2434 }
2435
2436 /// Update the global element offset based on the given offset. This is used to implement
2437 /// drag handles and other manual painting of elements.
2438 fn with_absolute_element_offset<R>(
2439 &mut self,
2440 offset: Point<Pixels>,
2441 f: impl FnOnce(&mut Self) -> R,
2442 ) -> R {
2443 self.window_mut()
2444 .next_frame
2445 .element_offset_stack
2446 .push(offset);
2447 let result = f(self);
2448 self.window_mut().next_frame.element_offset_stack.pop();
2449 result
2450 }
2451
2452 /// Obtain the current element offset.
2453 fn element_offset(&self) -> Point<Pixels> {
2454 self.window()
2455 .next_frame
2456 .element_offset_stack
2457 .last()
2458 .copied()
2459 .unwrap_or_default()
2460 }
2461
2462 /// Obtain the current content mask.
2463 fn content_mask(&self) -> ContentMask<Pixels> {
2464 self.window()
2465 .next_frame
2466 .content_mask_stack
2467 .last()
2468 .cloned()
2469 .unwrap_or_else(|| ContentMask {
2470 bounds: Bounds {
2471 origin: Point::default(),
2472 size: self.window().viewport_size,
2473 },
2474 })
2475 }
2476
2477 /// The size of an em for the base font of the application. Adjusting this value allows the
2478 /// UI to scale, just like zooming a web page.
2479 fn rem_size(&self) -> Pixels {
2480 self.window().rem_size
2481 }
2482}
2483
2484impl Borrow<Window> for WindowContext<'_> {
2485 fn borrow(&self) -> &Window {
2486 self.window
2487 }
2488}
2489
2490impl BorrowMut<Window> for WindowContext<'_> {
2491 fn borrow_mut(&mut self) -> &mut Window {
2492 self.window
2493 }
2494}
2495
2496impl<T> BorrowWindow for T where T: BorrowMut<AppContext> + BorrowMut<Window> {}
2497
2498/// Provides access to application state that is specialized for a particular [`View`].
2499/// Allows you to interact with focus, emit events, etc.
2500/// ViewContext also derefs to [`WindowContext`], giving you access to all of its methods as well.
2501/// When you call [`View::update`], you're passed a `&mut V` and an `&mut ViewContext<V>`.
2502pub struct ViewContext<'a, V> {
2503 window_cx: WindowContext<'a>,
2504 view: &'a View<V>,
2505}
2506
2507impl<V> Borrow<AppContext> for ViewContext<'_, V> {
2508 fn borrow(&self) -> &AppContext {
2509 &*self.window_cx.app
2510 }
2511}
2512
2513impl<V> BorrowMut<AppContext> for ViewContext<'_, V> {
2514 fn borrow_mut(&mut self) -> &mut AppContext {
2515 &mut *self.window_cx.app
2516 }
2517}
2518
2519impl<V> Borrow<Window> for ViewContext<'_, V> {
2520 fn borrow(&self) -> &Window {
2521 &*self.window_cx.window
2522 }
2523}
2524
2525impl<V> BorrowMut<Window> for ViewContext<'_, V> {
2526 fn borrow_mut(&mut self) -> &mut Window {
2527 &mut *self.window_cx.window
2528 }
2529}
2530
2531impl<'a, V: 'static> ViewContext<'a, V> {
2532 pub(crate) fn new(app: &'a mut AppContext, window: &'a mut Window, view: &'a View<V>) -> Self {
2533 Self {
2534 window_cx: WindowContext::new(app, window),
2535 view,
2536 }
2537 }
2538
2539 /// Get the entity_id of this view.
2540 pub fn entity_id(&self) -> EntityId {
2541 self.view.entity_id()
2542 }
2543
2544 /// Get the view pointer underlying this context.
2545 pub fn view(&self) -> &View<V> {
2546 self.view
2547 }
2548
2549 /// Get the model underlying this view.
2550 pub fn model(&self) -> &Model<V> {
2551 &self.view.model
2552 }
2553
2554 /// Access the underlying window context.
2555 pub fn window_context(&mut self) -> &mut WindowContext<'a> {
2556 &mut self.window_cx
2557 }
2558
2559 /// Set a given callback to be run on the next frame.
2560 pub fn on_next_frame(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + 'static)
2561 where
2562 V: 'static,
2563 {
2564 let view = self.view().clone();
2565 self.window_cx.on_next_frame(move |cx| view.update(cx, f));
2566 }
2567
2568 /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
2569 /// that are currently on the stack to be returned to the app.
2570 pub fn defer(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + 'static) {
2571 let view = self.view().downgrade();
2572 self.window_cx.defer(move |cx| {
2573 view.update(cx, f).ok();
2574 });
2575 }
2576
2577 /// Observe another model or view for changes to its state, as tracked by [`ModelContext::notify`].
2578 pub fn observe<V2, E>(
2579 &mut self,
2580 entity: &E,
2581 mut on_notify: impl FnMut(&mut V, E, &mut ViewContext<'_, V>) + 'static,
2582 ) -> Subscription
2583 where
2584 V2: 'static,
2585 V: 'static,
2586 E: Entity<V2>,
2587 {
2588 let view = self.view().downgrade();
2589 let entity_id = entity.entity_id();
2590 let entity = entity.downgrade();
2591 let window_handle = self.window.handle;
2592 let (subscription, activate) = self.app.observers.insert(
2593 entity_id,
2594 Box::new(move |cx| {
2595 window_handle
2596 .update(cx, |_, cx| {
2597 if let Some(handle) = E::upgrade_from(&entity) {
2598 view.update(cx, |this, cx| on_notify(this, handle, cx))
2599 .is_ok()
2600 } else {
2601 false
2602 }
2603 })
2604 .unwrap_or(false)
2605 }),
2606 );
2607 self.app.defer(move |_| activate());
2608 subscription
2609 }
2610
2611 /// Subscribe to events emitted by another model or view.
2612 /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
2613 /// 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.
2614 pub fn subscribe<V2, E, Evt>(
2615 &mut self,
2616 entity: &E,
2617 mut on_event: impl FnMut(&mut V, E, &Evt, &mut ViewContext<'_, V>) + 'static,
2618 ) -> Subscription
2619 where
2620 V2: EventEmitter<Evt>,
2621 E: Entity<V2>,
2622 Evt: 'static,
2623 {
2624 let view = self.view().downgrade();
2625 let entity_id = entity.entity_id();
2626 let handle = entity.downgrade();
2627 let window_handle = self.window.handle;
2628 let (subscription, activate) = self.app.event_listeners.insert(
2629 entity_id,
2630 (
2631 TypeId::of::<Evt>(),
2632 Box::new(move |event, cx| {
2633 window_handle
2634 .update(cx, |_, cx| {
2635 if let Some(handle) = E::upgrade_from(&handle) {
2636 let event = event.downcast_ref().expect("invalid event type");
2637 view.update(cx, |this, cx| on_event(this, handle, event, cx))
2638 .is_ok()
2639 } else {
2640 false
2641 }
2642 })
2643 .unwrap_or(false)
2644 }),
2645 ),
2646 );
2647 self.app.defer(move |_| activate());
2648 subscription
2649 }
2650
2651 /// Register a callback to be invoked when the view is released.
2652 ///
2653 /// The callback receives a handle to the view's window. This handle may be
2654 /// invalid, if the window was closed before the view was released.
2655 pub fn on_release(
2656 &mut self,
2657 on_release: impl FnOnce(&mut V, AnyWindowHandle, &mut AppContext) + 'static,
2658 ) -> Subscription {
2659 let window_handle = self.window.handle;
2660 let (subscription, activate) = self.app.release_listeners.insert(
2661 self.view.model.entity_id,
2662 Box::new(move |this, cx| {
2663 let this = this.downcast_mut().expect("invalid entity type");
2664 on_release(this, window_handle, cx)
2665 }),
2666 );
2667 activate();
2668 subscription
2669 }
2670
2671 /// Register a callback to be invoked when the given Model or View is released.
2672 pub fn observe_release<V2, E>(
2673 &mut self,
2674 entity: &E,
2675 mut on_release: impl FnMut(&mut V, &mut V2, &mut ViewContext<'_, V>) + 'static,
2676 ) -> Subscription
2677 where
2678 V: 'static,
2679 V2: 'static,
2680 E: Entity<V2>,
2681 {
2682 let view = self.view().downgrade();
2683 let entity_id = entity.entity_id();
2684 let window_handle = self.window.handle;
2685 let (subscription, activate) = self.app.release_listeners.insert(
2686 entity_id,
2687 Box::new(move |entity, cx| {
2688 let entity = entity.downcast_mut().expect("invalid entity type");
2689 let _ = window_handle.update(cx, |_, cx| {
2690 view.update(cx, |this, cx| on_release(this, entity, cx))
2691 });
2692 }),
2693 );
2694 activate();
2695 subscription
2696 }
2697
2698 /// Indicate that this view has changed, which will invoke any observers and also mark the window as dirty.
2699 /// If this view or any of its ancestors are *cached*, notifying it will cause it or its ancestors to be redrawn.
2700 pub fn notify(&mut self) {
2701 for view_id in self
2702 .window
2703 .rendered_frame
2704 .dispatch_tree
2705 .view_path(self.view.entity_id())
2706 {
2707 if !self.window.dirty_views.insert(view_id) {
2708 break;
2709 }
2710 }
2711
2712 if !self.window.drawing {
2713 self.window_cx.window.dirty = true;
2714 self.window_cx.app.push_effect(Effect::Notify {
2715 emitter: self.view.model.entity_id,
2716 });
2717 }
2718 }
2719
2720 /// Register a callback to be invoked when the window is resized.
2721 pub fn observe_window_bounds(
2722 &mut self,
2723 mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2724 ) -> Subscription {
2725 let view = self.view.downgrade();
2726 let (subscription, activate) = self.window.bounds_observers.insert(
2727 (),
2728 Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
2729 );
2730 activate();
2731 subscription
2732 }
2733
2734 /// Register a callback to be invoked when the window is activated or deactivated.
2735 pub fn observe_window_activation(
2736 &mut self,
2737 mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2738 ) -> Subscription {
2739 let view = self.view.downgrade();
2740 let (subscription, activate) = self.window.activation_observers.insert(
2741 (),
2742 Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
2743 );
2744 activate();
2745 subscription
2746 }
2747
2748 /// Register a listener to be called when the given focus handle receives focus.
2749 /// Returns a subscription and persists until the subscription is dropped.
2750 pub fn on_focus(
2751 &mut self,
2752 handle: &FocusHandle,
2753 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2754 ) -> Subscription {
2755 let view = self.view.downgrade();
2756 let focus_id = handle.id;
2757 let (subscription, activate) = self.window.focus_listeners.insert(
2758 (),
2759 Box::new(move |event, cx| {
2760 view.update(cx, |view, cx| {
2761 if event.previous_focus_path.last() != Some(&focus_id)
2762 && event.current_focus_path.last() == Some(&focus_id)
2763 {
2764 listener(view, cx)
2765 }
2766 })
2767 .is_ok()
2768 }),
2769 );
2770 self.app.defer(move |_| activate());
2771 subscription
2772 }
2773
2774 /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
2775 /// Returns a subscription and persists until the subscription is dropped.
2776 pub fn on_focus_in(
2777 &mut self,
2778 handle: &FocusHandle,
2779 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2780 ) -> Subscription {
2781 let view = self.view.downgrade();
2782 let focus_id = handle.id;
2783 let (subscription, activate) = self.window.focus_listeners.insert(
2784 (),
2785 Box::new(move |event, cx| {
2786 view.update(cx, |view, cx| {
2787 if !event.previous_focus_path.contains(&focus_id)
2788 && event.current_focus_path.contains(&focus_id)
2789 {
2790 listener(view, cx)
2791 }
2792 })
2793 .is_ok()
2794 }),
2795 );
2796 self.app.defer(move |_| activate());
2797 subscription
2798 }
2799
2800 /// Register a listener to be called when the given focus handle loses focus.
2801 /// Returns a subscription and persists until the subscription is dropped.
2802 pub fn on_blur(
2803 &mut self,
2804 handle: &FocusHandle,
2805 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2806 ) -> Subscription {
2807 let view = self.view.downgrade();
2808 let focus_id = handle.id;
2809 let (subscription, activate) = self.window.focus_listeners.insert(
2810 (),
2811 Box::new(move |event, cx| {
2812 view.update(cx, |view, cx| {
2813 if event.previous_focus_path.last() == Some(&focus_id)
2814 && event.current_focus_path.last() != Some(&focus_id)
2815 {
2816 listener(view, cx)
2817 }
2818 })
2819 .is_ok()
2820 }),
2821 );
2822 self.app.defer(move |_| activate());
2823 subscription
2824 }
2825
2826 /// Register a listener to be called when nothing in the window has focus.
2827 /// This typically happens when the node that was focused is removed from the tree,
2828 /// and this callback lets you chose a default place to restore the users focus.
2829 /// Returns a subscription and persists until the subscription is dropped.
2830 pub fn on_focus_lost(
2831 &mut self,
2832 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2833 ) -> Subscription {
2834 let view = self.view.downgrade();
2835 let (subscription, activate) = self.window.focus_lost_listeners.insert(
2836 (),
2837 Box::new(move |cx| view.update(cx, |view, cx| listener(view, cx)).is_ok()),
2838 );
2839 activate();
2840 subscription
2841 }
2842
2843 /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
2844 /// Returns a subscription and persists until the subscription is dropped.
2845 pub fn on_focus_out(
2846 &mut self,
2847 handle: &FocusHandle,
2848 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2849 ) -> Subscription {
2850 let view = self.view.downgrade();
2851 let focus_id = handle.id;
2852 let (subscription, activate) = self.window.focus_listeners.insert(
2853 (),
2854 Box::new(move |event, cx| {
2855 view.update(cx, |view, cx| {
2856 if event.previous_focus_path.contains(&focus_id)
2857 && !event.current_focus_path.contains(&focus_id)
2858 {
2859 listener(view, cx)
2860 }
2861 })
2862 .is_ok()
2863 }),
2864 );
2865 self.app.defer(move |_| activate());
2866 subscription
2867 }
2868
2869 /// Schedule a future to be run asynchronously.
2870 /// The given callback is invoked with a [`WeakView<V>`] to avoid leaking the view for a long-running process.
2871 /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the view across await points.
2872 /// The returned future will be polled on the main thread.
2873 pub fn spawn<Fut, R>(
2874 &mut self,
2875 f: impl FnOnce(WeakView<V>, AsyncWindowContext) -> Fut,
2876 ) -> Task<R>
2877 where
2878 R: 'static,
2879 Fut: Future<Output = R> + 'static,
2880 {
2881 let view = self.view().downgrade();
2882 self.window_cx.spawn(|cx| f(view, cx))
2883 }
2884
2885 /// Update the global state of the given type.
2886 pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
2887 where
2888 G: 'static,
2889 {
2890 let mut global = self.app.lease_global::<G>();
2891 let result = f(&mut global, self);
2892 self.app.end_global_lease(global);
2893 result
2894 }
2895
2896 /// Register a callback to be invoked when the given global state changes.
2897 pub fn observe_global<G: 'static>(
2898 &mut self,
2899 mut f: impl FnMut(&mut V, &mut ViewContext<'_, V>) + 'static,
2900 ) -> Subscription {
2901 let window_handle = self.window.handle;
2902 let view = self.view().downgrade();
2903 let (subscription, activate) = self.global_observers.insert(
2904 TypeId::of::<G>(),
2905 Box::new(move |cx| {
2906 window_handle
2907 .update(cx, |_, cx| view.update(cx, |view, cx| f(view, cx)).is_ok())
2908 .unwrap_or(false)
2909 }),
2910 );
2911 self.app.defer(move |_| activate());
2912 subscription
2913 }
2914
2915 /// Add a listener for any mouse event that occurs in the window.
2916 /// This is a fairly low level method.
2917 /// Typically, you'll want to use methods on UI elements, which perform bounds checking etc.
2918 pub fn on_mouse_event<Event: 'static>(
2919 &mut self,
2920 handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + 'static,
2921 ) {
2922 let handle = self.view().clone();
2923 self.window_cx.on_mouse_event(move |event, phase, cx| {
2924 handle.update(cx, |view, cx| {
2925 handler(view, event, phase, cx);
2926 })
2927 });
2928 }
2929
2930 /// Register a callback to be invoked when the given Key Event is dispatched to the window.
2931 pub fn on_key_event<Event: 'static>(
2932 &mut self,
2933 handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + 'static,
2934 ) {
2935 let handle = self.view().clone();
2936 self.window_cx.on_key_event(move |event, phase, cx| {
2937 handle.update(cx, |view, cx| {
2938 handler(view, event, phase, cx);
2939 })
2940 });
2941 }
2942
2943 /// Register a callback to be invoked when the given Action type is dispatched to the window.
2944 pub fn on_action(
2945 &mut self,
2946 action_type: TypeId,
2947 listener: impl Fn(&mut V, &dyn Any, DispatchPhase, &mut ViewContext<V>) + 'static,
2948 ) {
2949 let handle = self.view().clone();
2950 self.window_cx
2951 .on_action(action_type, move |action, phase, cx| {
2952 handle.update(cx, |view, cx| {
2953 listener(view, action, phase, cx);
2954 })
2955 });
2956 }
2957
2958 /// Emit an event to be handled any other views that have subscribed via [ViewContext::subscribe].
2959 pub fn emit<Evt>(&mut self, event: Evt)
2960 where
2961 Evt: 'static,
2962 V: EventEmitter<Evt>,
2963 {
2964 let emitter = self.view.model.entity_id;
2965 self.app.push_effect(Effect::Emit {
2966 emitter,
2967 event_type: TypeId::of::<Evt>(),
2968 event: Box::new(event),
2969 });
2970 }
2971
2972 /// Move focus to the current view, assuming it implements [`FocusableView`].
2973 pub fn focus_self(&mut self)
2974 where
2975 V: FocusableView,
2976 {
2977 self.defer(|view, cx| view.focus_handle(cx).focus(cx))
2978 }
2979
2980 /// Convenience method for accessing view state in an event callback.
2981 ///
2982 /// Many GPUI callbacks take the form of `Fn(&E, &mut WindowContext)`,
2983 /// but it's often useful to be able to access view state in these
2984 /// callbacks. This method provides a convenient way to do so.
2985 pub fn listener<E>(
2986 &self,
2987 f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
2988 ) -> impl Fn(&E, &mut WindowContext) + 'static {
2989 let view = self.view().downgrade();
2990 move |e: &E, cx: &mut WindowContext| {
2991 view.update(cx, |view, cx| f(view, e, cx)).ok();
2992 }
2993 }
2994}
2995
2996impl<V> Context for ViewContext<'_, V> {
2997 type Result<U> = U;
2998
2999 fn new_model<T: 'static>(
3000 &mut self,
3001 build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
3002 ) -> Model<T> {
3003 self.window_cx.new_model(build_model)
3004 }
3005
3006 fn update_model<T: 'static, R>(
3007 &mut self,
3008 model: &Model<T>,
3009 update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
3010 ) -> R {
3011 self.window_cx.update_model(model, update)
3012 }
3013
3014 fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
3015 where
3016 F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
3017 {
3018 self.window_cx.update_window(window, update)
3019 }
3020
3021 fn read_model<T, R>(
3022 &self,
3023 handle: &Model<T>,
3024 read: impl FnOnce(&T, &AppContext) -> R,
3025 ) -> Self::Result<R>
3026 where
3027 T: 'static,
3028 {
3029 self.window_cx.read_model(handle, read)
3030 }
3031
3032 fn read_window<T, R>(
3033 &self,
3034 window: &WindowHandle<T>,
3035 read: impl FnOnce(View<T>, &AppContext) -> R,
3036 ) -> Result<R>
3037 where
3038 T: 'static,
3039 {
3040 self.window_cx.read_window(window, read)
3041 }
3042}
3043
3044impl<V: 'static> VisualContext for ViewContext<'_, V> {
3045 fn new_view<W: Render + 'static>(
3046 &mut self,
3047 build_view_state: impl FnOnce(&mut ViewContext<'_, W>) -> W,
3048 ) -> Self::Result<View<W>> {
3049 self.window_cx.new_view(build_view_state)
3050 }
3051
3052 fn update_view<V2: 'static, R>(
3053 &mut self,
3054 view: &View<V2>,
3055 update: impl FnOnce(&mut V2, &mut ViewContext<'_, V2>) -> R,
3056 ) -> Self::Result<R> {
3057 self.window_cx.update_view(view, update)
3058 }
3059
3060 fn replace_root_view<W>(
3061 &mut self,
3062 build_view: impl FnOnce(&mut ViewContext<'_, W>) -> W,
3063 ) -> Self::Result<View<W>>
3064 where
3065 W: 'static + Render,
3066 {
3067 self.window_cx.replace_root_view(build_view)
3068 }
3069
3070 fn focus_view<W: FocusableView>(&mut self, view: &View<W>) -> Self::Result<()> {
3071 self.window_cx.focus_view(view)
3072 }
3073
3074 fn dismiss_view<W: ManagedView>(&mut self, view: &View<W>) -> Self::Result<()> {
3075 self.window_cx.dismiss_view(view)
3076 }
3077}
3078
3079impl<'a, V> std::ops::Deref for ViewContext<'a, V> {
3080 type Target = WindowContext<'a>;
3081
3082 fn deref(&self) -> &Self::Target {
3083 &self.window_cx
3084 }
3085}
3086
3087impl<'a, V> std::ops::DerefMut for ViewContext<'a, V> {
3088 fn deref_mut(&mut self) -> &mut Self::Target {
3089 &mut self.window_cx
3090 }
3091}
3092
3093// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
3094slotmap::new_key_type! {
3095 /// A unique identifier for a window.
3096 pub struct WindowId;
3097}
3098
3099impl WindowId {
3100 /// Converts this window ID to a `u64`.
3101 pub fn as_u64(&self) -> u64 {
3102 self.0.as_ffi()
3103 }
3104}
3105
3106/// A handle to a window with a specific root view type.
3107/// Note that this does not keep the window alive on its own.
3108#[derive(Deref, DerefMut)]
3109pub struct WindowHandle<V> {
3110 #[deref]
3111 #[deref_mut]
3112 pub(crate) any_handle: AnyWindowHandle,
3113 state_type: PhantomData<V>,
3114}
3115
3116impl<V: 'static + Render> WindowHandle<V> {
3117 /// Create a new handle from a window ID.
3118 /// This does not check if the root type of the window is `V`.
3119 pub fn new(id: WindowId) -> Self {
3120 WindowHandle {
3121 any_handle: AnyWindowHandle {
3122 id,
3123 state_type: TypeId::of::<V>(),
3124 },
3125 state_type: PhantomData,
3126 }
3127 }
3128
3129 /// Get the root view out of this window.
3130 ///
3131 /// This will fail if the window is closed or if the root view's type does not match `V`.
3132 pub fn root<C>(&self, cx: &mut C) -> Result<View<V>>
3133 where
3134 C: Context,
3135 {
3136 Flatten::flatten(cx.update_window(self.any_handle, |root_view, _| {
3137 root_view
3138 .downcast::<V>()
3139 .map_err(|_| anyhow!("the type of the window's root view has changed"))
3140 }))
3141 }
3142
3143 /// Update the root view of this window.
3144 ///
3145 /// This will fail if the window has been closed or if the root view's type does not match
3146 pub fn update<C, R>(
3147 &self,
3148 cx: &mut C,
3149 update: impl FnOnce(&mut V, &mut ViewContext<'_, V>) -> R,
3150 ) -> Result<R>
3151 where
3152 C: Context,
3153 {
3154 cx.update_window(self.any_handle, |root_view, cx| {
3155 let view = root_view
3156 .downcast::<V>()
3157 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
3158 Ok(cx.update_view(&view, update))
3159 })?
3160 }
3161
3162 /// Read the root view out of this window.
3163 ///
3164 /// This will fail if the window is closed or if the root view's type does not match `V`.
3165 pub fn read<'a>(&self, cx: &'a AppContext) -> Result<&'a V> {
3166 let x = cx
3167 .windows
3168 .get(self.id)
3169 .and_then(|window| {
3170 window
3171 .as_ref()
3172 .and_then(|window| window.root_view.clone())
3173 .map(|root_view| root_view.downcast::<V>())
3174 })
3175 .ok_or_else(|| anyhow!("window not found"))?
3176 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
3177
3178 Ok(x.read(cx))
3179 }
3180
3181 /// Read the root view out of this window, with a callback
3182 ///
3183 /// This will fail if the window is closed or if the root view's type does not match `V`.
3184 pub fn read_with<C, R>(&self, cx: &C, read_with: impl FnOnce(&V, &AppContext) -> R) -> Result<R>
3185 where
3186 C: Context,
3187 {
3188 cx.read_window(self, |root_view, cx| read_with(root_view.read(cx), cx))
3189 }
3190
3191 /// Read the root view pointer off of this window.
3192 ///
3193 /// This will fail if the window is closed or if the root view's type does not match `V`.
3194 pub fn root_view<C>(&self, cx: &C) -> Result<View<V>>
3195 where
3196 C: Context,
3197 {
3198 cx.read_window(self, |root_view, _cx| root_view.clone())
3199 }
3200
3201 /// Check if this window is 'active'.
3202 ///
3203 /// Will return `None` if the window is closed.
3204 pub fn is_active(&self, cx: &AppContext) -> Option<bool> {
3205 cx.windows
3206 .get(self.id)
3207 .and_then(|window| window.as_ref().map(|window| window.active))
3208 }
3209}
3210
3211impl<V> Copy for WindowHandle<V> {}
3212
3213impl<V> Clone for WindowHandle<V> {
3214 fn clone(&self) -> Self {
3215 *self
3216 }
3217}
3218
3219impl<V> PartialEq for WindowHandle<V> {
3220 fn eq(&self, other: &Self) -> bool {
3221 self.any_handle == other.any_handle
3222 }
3223}
3224
3225impl<V> Eq for WindowHandle<V> {}
3226
3227impl<V> Hash for WindowHandle<V> {
3228 fn hash<H: Hasher>(&self, state: &mut H) {
3229 self.any_handle.hash(state);
3230 }
3231}
3232
3233impl<V: 'static> From<WindowHandle<V>> for AnyWindowHandle {
3234 fn from(val: WindowHandle<V>) -> Self {
3235 val.any_handle
3236 }
3237}
3238
3239/// A handle to a window with any root view type, which can be downcast to a window with a specific root view type.
3240#[derive(Copy, Clone, PartialEq, Eq, Hash)]
3241pub struct AnyWindowHandle {
3242 pub(crate) id: WindowId,
3243 state_type: TypeId,
3244}
3245
3246impl AnyWindowHandle {
3247 /// Get the ID of this window.
3248 pub fn window_id(&self) -> WindowId {
3249 self.id
3250 }
3251
3252 /// Attempt to convert this handle to a window handle with a specific root view type.
3253 /// If the types do not match, this will return `None`.
3254 pub fn downcast<T: 'static>(&self) -> Option<WindowHandle<T>> {
3255 if TypeId::of::<T>() == self.state_type {
3256 Some(WindowHandle {
3257 any_handle: *self,
3258 state_type: PhantomData,
3259 })
3260 } else {
3261 None
3262 }
3263 }
3264
3265 /// Update the state of the root view of this window.
3266 ///
3267 /// This will fail if the window has been closed.
3268 pub fn update<C, R>(
3269 self,
3270 cx: &mut C,
3271 update: impl FnOnce(AnyView, &mut WindowContext<'_>) -> R,
3272 ) -> Result<R>
3273 where
3274 C: Context,
3275 {
3276 cx.update_window(self, update)
3277 }
3278
3279 /// Read the state of the root view of this window.
3280 ///
3281 /// This will fail if the window has been closed.
3282 pub fn read<T, C, R>(self, cx: &C, read: impl FnOnce(View<T>, &AppContext) -> R) -> Result<R>
3283 where
3284 C: Context,
3285 T: 'static,
3286 {
3287 let view = self
3288 .downcast::<T>()
3289 .context("the type of the window's root view has changed")?;
3290
3291 cx.read_window(&view, read)
3292 }
3293}
3294
3295// #[cfg(any(test, feature = "test-support"))]
3296// impl From<SmallVec<[u32; 16]>> for StackingOrder {
3297// fn from(small_vec: SmallVec<[u32; 16]>) -> Self {
3298// StackingOrder(small_vec)
3299// }
3300// }
3301
3302/// An identifier for an [`Element`](crate::Element).
3303///
3304/// Can be constructed with a string, a number, or both, as well
3305/// as other internal representations.
3306#[derive(Clone, Debug, Eq, PartialEq, Hash)]
3307pub enum ElementId {
3308 /// The ID of a View element
3309 View(EntityId),
3310 /// An integer ID.
3311 Integer(usize),
3312 /// A string based ID.
3313 Name(SharedString),
3314 /// An ID that's equated with a focus handle.
3315 FocusHandle(FocusId),
3316 /// A combination of a name and an integer.
3317 NamedInteger(SharedString, usize),
3318}
3319
3320impl ElementId {
3321 pub(crate) fn from_entity_id(entity_id: EntityId) -> Self {
3322 ElementId::View(entity_id)
3323 }
3324}
3325
3326impl TryInto<SharedString> for ElementId {
3327 type Error = anyhow::Error;
3328
3329 fn try_into(self) -> anyhow::Result<SharedString> {
3330 if let ElementId::Name(name) = self {
3331 Ok(name)
3332 } else {
3333 Err(anyhow!("element id is not string"))
3334 }
3335 }
3336}
3337
3338impl From<usize> for ElementId {
3339 fn from(id: usize) -> Self {
3340 ElementId::Integer(id)
3341 }
3342}
3343
3344impl From<i32> for ElementId {
3345 fn from(id: i32) -> Self {
3346 Self::Integer(id as usize)
3347 }
3348}
3349
3350impl From<SharedString> for ElementId {
3351 fn from(name: SharedString) -> Self {
3352 ElementId::Name(name)
3353 }
3354}
3355
3356impl From<&'static str> for ElementId {
3357 fn from(name: &'static str) -> Self {
3358 ElementId::Name(name.into())
3359 }
3360}
3361
3362impl<'a> From<&'a FocusHandle> for ElementId {
3363 fn from(handle: &'a FocusHandle) -> Self {
3364 ElementId::FocusHandle(handle.id)
3365 }
3366}
3367
3368impl From<(&'static str, EntityId)> for ElementId {
3369 fn from((name, id): (&'static str, EntityId)) -> Self {
3370 ElementId::NamedInteger(name.into(), id.as_u64() as usize)
3371 }
3372}
3373
3374impl From<(&'static str, usize)> for ElementId {
3375 fn from((name, id): (&'static str, usize)) -> Self {
3376 ElementId::NamedInteger(name.into(), id)
3377 }
3378}
3379
3380impl From<(&'static str, u64)> for ElementId {
3381 fn from((name, id): (&'static str, u64)) -> Self {
3382 ElementId::NamedInteger(name.into(), id as usize)
3383 }
3384}
3385
3386/// A rectangle to be rendered in the window at the given position and size.
3387/// Passed as an argument [`WindowContext::paint_quad`].
3388#[derive(Clone)]
3389pub struct PaintQuad {
3390 bounds: Bounds<Pixels>,
3391 corner_radii: Corners<Pixels>,
3392 background: Hsla,
3393 border_widths: Edges<Pixels>,
3394 border_color: Hsla,
3395}
3396
3397impl PaintQuad {
3398 /// Set the corner radii of the quad.
3399 pub fn corner_radii(self, corner_radii: impl Into<Corners<Pixels>>) -> Self {
3400 PaintQuad {
3401 corner_radii: corner_radii.into(),
3402 ..self
3403 }
3404 }
3405
3406 /// Set the border widths of the quad.
3407 pub fn border_widths(self, border_widths: impl Into<Edges<Pixels>>) -> Self {
3408 PaintQuad {
3409 border_widths: border_widths.into(),
3410 ..self
3411 }
3412 }
3413
3414 /// Set the border color of the quad.
3415 pub fn border_color(self, border_color: impl Into<Hsla>) -> Self {
3416 PaintQuad {
3417 border_color: border_color.into(),
3418 ..self
3419 }
3420 }
3421
3422 /// Set the background color of the quad.
3423 pub fn background(self, background: impl Into<Hsla>) -> Self {
3424 PaintQuad {
3425 background: background.into(),
3426 ..self
3427 }
3428 }
3429}
3430
3431/// Create a quad with the given parameters.
3432pub fn quad(
3433 bounds: Bounds<Pixels>,
3434 corner_radii: impl Into<Corners<Pixels>>,
3435 background: impl Into<Hsla>,
3436 border_widths: impl Into<Edges<Pixels>>,
3437 border_color: impl Into<Hsla>,
3438) -> PaintQuad {
3439 PaintQuad {
3440 bounds,
3441 corner_radii: corner_radii.into(),
3442 background: background.into(),
3443 border_widths: border_widths.into(),
3444 border_color: border_color.into(),
3445 }
3446}
3447
3448/// Create a filled quad with the given bounds and background color.
3449pub fn fill(bounds: impl Into<Bounds<Pixels>>, background: impl Into<Hsla>) -> PaintQuad {
3450 PaintQuad {
3451 bounds: bounds.into(),
3452 corner_radii: (0.).into(),
3453 background: background.into(),
3454 border_widths: (0.).into(),
3455 border_color: transparent_black(),
3456 }
3457}
3458
3459/// Create a rectangle outline with the given bounds, border color, and a 1px border width
3460pub fn outline(bounds: impl Into<Bounds<Pixels>>, border_color: impl Into<Hsla>) -> PaintQuad {
3461 PaintQuad {
3462 bounds: bounds.into(),
3463 corner_radii: (0.).into(),
3464 background: transparent_black(),
3465 border_widths: (1.).into(),
3466 border_color: border_color.into(),
3467 }
3468}