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 if let Some(requested_handler) = self.window.rendered_frame.requested_input_handler.as_mut()
1465 {
1466 requested_handler.handler = self.window.platform_window.take_input_handler();
1467 }
1468
1469 let root_view = self.window.root_view.take().unwrap();
1470
1471 self.with_z_index(0, |cx| {
1472 cx.with_key_dispatch(Some(KeyContext::default()), None, |_, cx| {
1473 for (action_type, action_listeners) in &cx.app.global_action_listeners {
1474 for action_listener in action_listeners.iter().cloned() {
1475 cx.window.next_frame.dispatch_tree.on_action(
1476 *action_type,
1477 Rc::new(move |action: &dyn Any, phase, cx: &mut WindowContext<'_>| {
1478 action_listener(action, phase, cx)
1479 }),
1480 )
1481 }
1482 }
1483
1484 let available_space = cx.window.viewport_size.map(Into::into);
1485 root_view.draw(Point::default(), available_space, cx);
1486 })
1487 });
1488
1489 if let Some(active_drag) = self.app.active_drag.take() {
1490 self.with_z_index(ACTIVE_DRAG_Z_INDEX, |cx| {
1491 let offset = cx.mouse_position() - active_drag.cursor_offset;
1492 let available_space = size(AvailableSpace::MinContent, AvailableSpace::MinContent);
1493 active_drag.view.draw(offset, available_space, cx);
1494 });
1495 self.active_drag = Some(active_drag);
1496 } else if let Some(active_tooltip) = self.app.active_tooltip.take() {
1497 self.with_z_index(1, |cx| {
1498 let available_space = size(AvailableSpace::MinContent, AvailableSpace::MinContent);
1499 active_tooltip
1500 .view
1501 .draw(active_tooltip.cursor_offset, available_space, cx);
1502 });
1503 }
1504 self.window.dirty_views.clear();
1505
1506 self.window
1507 .next_frame
1508 .dispatch_tree
1509 .preserve_pending_keystrokes(
1510 &mut self.window.rendered_frame.dispatch_tree,
1511 self.window.focus,
1512 );
1513 self.window.next_frame.focus = self.window.focus;
1514 self.window.next_frame.window_active = self.window.active;
1515 self.window.root_view = Some(root_view);
1516
1517 // Set the cursor only if we're the active window.
1518 let cursor_style = self
1519 .window
1520 .next_frame
1521 .requested_cursor_style
1522 .take()
1523 .unwrap_or(CursorStyle::Arrow);
1524 if self.is_window_active() {
1525 self.platform.set_cursor_style(cursor_style);
1526 }
1527
1528 // Register requested input handler with the platform window.
1529 if let Some(requested_input) = self.window.next_frame.requested_input_handler.as_mut() {
1530 if let Some(handler) = requested_input.handler.take() {
1531 self.window.platform_window.set_input_handler(handler);
1532 }
1533 }
1534
1535 self.window
1536 .next_frame
1537 .reuse_views(&mut self.window.rendered_frame);
1538 self.window.next_frame.scene.finish();
1539 self.window.layout_engine.as_mut().unwrap().clear();
1540 self.text_system()
1541 .end_frame(&self.window.next_frame.reused_views);
1542 ELEMENT_ARENA.with_borrow_mut(|element_arena| element_arena.clear());
1543
1544 self.window.refreshing = false;
1545 self.window.drawing = false;
1546
1547 let previous_focus_path = self.window.rendered_frame.focus_path();
1548 let previous_window_active = self.window.rendered_frame.window_active;
1549 mem::swap(&mut self.window.rendered_frame, &mut self.window.next_frame);
1550 self.window.next_frame.clear();
1551 let current_focus_path = self.window.rendered_frame.focus_path();
1552 let current_window_active = self.window.rendered_frame.window_active;
1553
1554 if previous_focus_path != current_focus_path
1555 || previous_window_active != current_window_active
1556 {
1557 if !previous_focus_path.is_empty() && current_focus_path.is_empty() {
1558 self.window
1559 .focus_lost_listeners
1560 .clone()
1561 .retain(&(), |listener| listener(self));
1562 }
1563
1564 let event = FocusEvent {
1565 previous_focus_path: if previous_window_active {
1566 previous_focus_path
1567 } else {
1568 Default::default()
1569 },
1570 current_focus_path: if current_window_active {
1571 current_focus_path
1572 } else {
1573 Default::default()
1574 },
1575 };
1576 self.window
1577 .focus_listeners
1578 .clone()
1579 .retain(&(), |listener| listener(&event, self));
1580 }
1581
1582 self.window
1583 .platform_window
1584 .draw(&self.window.rendered_frame.scene);
1585 }
1586
1587 /// Dispatch a mouse or keyboard event on the window.
1588 pub fn dispatch_event(&mut self, event: InputEvent) -> bool {
1589 // Handlers may set this to false by calling `stop_propagation`.
1590 self.app.propagate_event = true;
1591 // Handlers may set this to true by calling `prevent_default`.
1592 self.window.default_prevented = false;
1593
1594 let event = match event {
1595 // Track the mouse position with our own state, since accessing the platform
1596 // API for the mouse position can only occur on the main thread.
1597 InputEvent::MouseMove(mouse_move) => {
1598 self.window.mouse_position = mouse_move.position;
1599 self.window.modifiers = mouse_move.modifiers;
1600 InputEvent::MouseMove(mouse_move)
1601 }
1602 InputEvent::MouseDown(mouse_down) => {
1603 self.window.mouse_position = mouse_down.position;
1604 self.window.modifiers = mouse_down.modifiers;
1605 InputEvent::MouseDown(mouse_down)
1606 }
1607 InputEvent::MouseUp(mouse_up) => {
1608 self.window.mouse_position = mouse_up.position;
1609 self.window.modifiers = mouse_up.modifiers;
1610 InputEvent::MouseUp(mouse_up)
1611 }
1612 InputEvent::MouseExited(mouse_exited) => {
1613 self.window.modifiers = mouse_exited.modifiers;
1614 InputEvent::MouseExited(mouse_exited)
1615 }
1616 InputEvent::ModifiersChanged(modifiers_changed) => {
1617 self.window.modifiers = modifiers_changed.modifiers;
1618 InputEvent::ModifiersChanged(modifiers_changed)
1619 }
1620 InputEvent::ScrollWheel(scroll_wheel) => {
1621 self.window.mouse_position = scroll_wheel.position;
1622 self.window.modifiers = scroll_wheel.modifiers;
1623 InputEvent::ScrollWheel(scroll_wheel)
1624 }
1625 // Translate dragging and dropping of external files from the operating system
1626 // to internal drag and drop events.
1627 InputEvent::FileDrop(file_drop) => match file_drop {
1628 FileDropEvent::Entered { position, paths } => {
1629 self.window.mouse_position = position;
1630 if self.active_drag.is_none() {
1631 self.active_drag = Some(AnyDrag {
1632 value: Box::new(paths.clone()),
1633 view: self.new_view(|_| paths).into(),
1634 cursor_offset: position,
1635 });
1636 }
1637 InputEvent::MouseMove(MouseMoveEvent {
1638 position,
1639 pressed_button: Some(MouseButton::Left),
1640 modifiers: Modifiers::default(),
1641 })
1642 }
1643 FileDropEvent::Pending { position } => {
1644 self.window.mouse_position = position;
1645 InputEvent::MouseMove(MouseMoveEvent {
1646 position,
1647 pressed_button: Some(MouseButton::Left),
1648 modifiers: Modifiers::default(),
1649 })
1650 }
1651 FileDropEvent::Submit { position } => {
1652 self.activate(true);
1653 self.window.mouse_position = position;
1654 InputEvent::MouseUp(MouseUpEvent {
1655 button: MouseButton::Left,
1656 position,
1657 modifiers: Modifiers::default(),
1658 click_count: 1,
1659 })
1660 }
1661 FileDropEvent::Exited => InputEvent::MouseUp(MouseUpEvent {
1662 button: MouseButton::Left,
1663 position: Point::default(),
1664 modifiers: Modifiers::default(),
1665 click_count: 1,
1666 }),
1667 },
1668 InputEvent::KeyDown(_) | InputEvent::KeyUp(_) => event,
1669 };
1670
1671 if let Some(any_mouse_event) = event.mouse_event() {
1672 self.dispatch_mouse_event(any_mouse_event);
1673 } else if let Some(any_key_event) = event.keyboard_event() {
1674 self.dispatch_key_event(any_key_event);
1675 }
1676
1677 !self.app.propagate_event
1678 }
1679
1680 fn dispatch_mouse_event(&mut self, event: &dyn Any) {
1681 if let Some(mut handlers) = self
1682 .window
1683 .rendered_frame
1684 .mouse_listeners
1685 .remove(&event.type_id())
1686 {
1687 // Because handlers may add other handlers, we sort every time.
1688 handlers.sort_by(|(a, _, _), (b, _, _)| a.cmp(b));
1689
1690 // Capture phase, events bubble from back to front. Handlers for this phase are used for
1691 // special purposes, such as detecting events outside of a given Bounds.
1692 for (_, _, handler) in &mut handlers {
1693 handler(event, DispatchPhase::Capture, self);
1694 if !self.app.propagate_event {
1695 break;
1696 }
1697 }
1698
1699 // Bubble phase, where most normal handlers do their work.
1700 if self.app.propagate_event {
1701 for (_, _, handler) in handlers.iter_mut().rev() {
1702 handler(event, DispatchPhase::Bubble, self);
1703 if !self.app.propagate_event {
1704 break;
1705 }
1706 }
1707 }
1708
1709 self.window
1710 .rendered_frame
1711 .mouse_listeners
1712 .insert(event.type_id(), handlers);
1713 }
1714
1715 if self.app.propagate_event && self.has_active_drag() {
1716 if event.is::<MouseMoveEvent>() {
1717 // If this was a mouse move event, redraw the window so that the
1718 // active drag can follow the mouse cursor.
1719 self.refresh();
1720 } else if event.is::<MouseUpEvent>() {
1721 // If this was a mouse up event, cancel the active drag and redraw
1722 // the window.
1723 self.active_drag = None;
1724 self.refresh();
1725 }
1726 }
1727 }
1728
1729 fn dispatch_key_event(&mut self, event: &dyn Any) {
1730 let node_id = self
1731 .window
1732 .focus
1733 .and_then(|focus_id| {
1734 self.window
1735 .rendered_frame
1736 .dispatch_tree
1737 .focusable_node_id(focus_id)
1738 })
1739 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
1740
1741 let dispatch_path = self
1742 .window
1743 .rendered_frame
1744 .dispatch_tree
1745 .dispatch_path(node_id);
1746
1747 let mut actions: Vec<Box<dyn Action>> = Vec::new();
1748
1749 let mut context_stack: SmallVec<[KeyContext; 16]> = SmallVec::new();
1750 for node_id in &dispatch_path {
1751 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1752
1753 if let Some(context) = node.context.clone() {
1754 context_stack.push(context);
1755 }
1756 }
1757
1758 for node_id in dispatch_path.iter().rev() {
1759 // Match keystrokes
1760 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1761 if node.context.is_some() {
1762 if let Some(key_down_event) = event.downcast_ref::<KeyDownEvent>() {
1763 let mut new_actions = self
1764 .window
1765 .rendered_frame
1766 .dispatch_tree
1767 .dispatch_key(&key_down_event.keystroke, &context_stack);
1768 actions.append(&mut new_actions);
1769 }
1770
1771 context_stack.pop();
1772 }
1773 }
1774
1775 if !actions.is_empty() {
1776 self.clear_pending_keystrokes();
1777 }
1778
1779 self.propagate_event = true;
1780 for action in actions {
1781 self.dispatch_action_on_node(node_id, action.boxed_clone());
1782 if !self.propagate_event {
1783 self.dispatch_keystroke_observers(event, Some(action));
1784 return;
1785 }
1786 }
1787
1788 // Capture phase
1789 for node_id in &dispatch_path {
1790 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1791
1792 for key_listener in node.key_listeners.clone() {
1793 key_listener(event, DispatchPhase::Capture, self);
1794 if !self.propagate_event {
1795 return;
1796 }
1797 }
1798 }
1799
1800 // Bubble phase
1801 for node_id in dispatch_path.iter().rev() {
1802 // Handle low level key events
1803 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1804 for key_listener in node.key_listeners.clone() {
1805 key_listener(event, DispatchPhase::Bubble, self);
1806 if !self.propagate_event {
1807 return;
1808 }
1809 }
1810 }
1811
1812 self.dispatch_keystroke_observers(event, None);
1813 }
1814
1815 /// Determine whether a potential multi-stroke key binding is in progress on this window.
1816 pub fn has_pending_keystrokes(&self) -> bool {
1817 self.window
1818 .rendered_frame
1819 .dispatch_tree
1820 .has_pending_keystrokes()
1821 }
1822
1823 fn dispatch_action_on_node(&mut self, node_id: DispatchNodeId, action: Box<dyn Action>) {
1824 let dispatch_path = self
1825 .window
1826 .rendered_frame
1827 .dispatch_tree
1828 .dispatch_path(node_id);
1829
1830 // Capture phase
1831 for node_id in &dispatch_path {
1832 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1833 for DispatchActionListener {
1834 action_type,
1835 listener,
1836 } in node.action_listeners.clone()
1837 {
1838 let any_action = action.as_any();
1839 if action_type == any_action.type_id() {
1840 listener(any_action, DispatchPhase::Capture, self);
1841 if !self.propagate_event {
1842 return;
1843 }
1844 }
1845 }
1846 }
1847 // Bubble phase
1848 for node_id in dispatch_path.iter().rev() {
1849 let node = self.window.rendered_frame.dispatch_tree.node(*node_id);
1850 for DispatchActionListener {
1851 action_type,
1852 listener,
1853 } in node.action_listeners.clone()
1854 {
1855 let any_action = action.as_any();
1856 if action_type == any_action.type_id() {
1857 self.propagate_event = false; // Actions stop propagation by default during the bubble phase
1858 listener(any_action, DispatchPhase::Bubble, self);
1859 if !self.propagate_event {
1860 return;
1861 }
1862 }
1863 }
1864 }
1865 }
1866
1867 /// Register the given handler to be invoked whenever the global of the given type
1868 /// is updated.
1869 pub fn observe_global<G: 'static>(
1870 &mut self,
1871 f: impl Fn(&mut WindowContext<'_>) + 'static,
1872 ) -> Subscription {
1873 let window_handle = self.window.handle;
1874 let (subscription, activate) = self.global_observers.insert(
1875 TypeId::of::<G>(),
1876 Box::new(move |cx| window_handle.update(cx, |_, cx| f(cx)).is_ok()),
1877 );
1878 self.app.defer(move |_| activate());
1879 subscription
1880 }
1881
1882 /// Focus the current window and bring it to the foreground at the platform level.
1883 pub fn activate_window(&self) {
1884 self.window.platform_window.activate();
1885 }
1886
1887 /// Minimize the current window at the platform level.
1888 pub fn minimize_window(&self) {
1889 self.window.platform_window.minimize();
1890 }
1891
1892 /// Toggle full screen status on the current window at the platform level.
1893 pub fn toggle_full_screen(&self) {
1894 self.window.platform_window.toggle_full_screen();
1895 }
1896
1897 /// Present a platform dialog.
1898 /// The provided message will be presented, along with buttons for each answer.
1899 /// When a button is clicked, the returned Receiver will receive the index of the clicked button.
1900 pub fn prompt(
1901 &self,
1902 level: PromptLevel,
1903 message: &str,
1904 answers: &[&str],
1905 ) -> oneshot::Receiver<usize> {
1906 self.window.platform_window.prompt(level, message, answers)
1907 }
1908
1909 /// Returns all available actions for the focused element.
1910 pub fn available_actions(&self) -> Vec<Box<dyn Action>> {
1911 let node_id = self
1912 .window
1913 .focus
1914 .and_then(|focus_id| {
1915 self.window
1916 .rendered_frame
1917 .dispatch_tree
1918 .focusable_node_id(focus_id)
1919 })
1920 .unwrap_or_else(|| self.window.rendered_frame.dispatch_tree.root_node_id());
1921
1922 self.window
1923 .rendered_frame
1924 .dispatch_tree
1925 .available_actions(node_id)
1926 }
1927
1928 /// Returns key bindings that invoke the given action on the currently focused element.
1929 pub fn bindings_for_action(&self, action: &dyn Action) -> Vec<KeyBinding> {
1930 self.window
1931 .rendered_frame
1932 .dispatch_tree
1933 .bindings_for_action(
1934 action,
1935 &self.window.rendered_frame.dispatch_tree.context_stack,
1936 )
1937 }
1938
1939 /// Returns any bindings that would invoke the given action on the given focus handle if it were focused.
1940 pub fn bindings_for_action_in(
1941 &self,
1942 action: &dyn Action,
1943 focus_handle: &FocusHandle,
1944 ) -> Vec<KeyBinding> {
1945 let dispatch_tree = &self.window.rendered_frame.dispatch_tree;
1946
1947 let Some(node_id) = dispatch_tree.focusable_node_id(focus_handle.id) else {
1948 return vec![];
1949 };
1950 let context_stack = dispatch_tree
1951 .dispatch_path(node_id)
1952 .into_iter()
1953 .filter_map(|node_id| dispatch_tree.node(node_id).context.clone())
1954 .collect();
1955 dispatch_tree.bindings_for_action(action, &context_stack)
1956 }
1957
1958 /// Returns a generic event listener that invokes the given listener with the view and context associated with the given view handle.
1959 pub fn listener_for<V: Render, E>(
1960 &self,
1961 view: &View<V>,
1962 f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
1963 ) -> impl Fn(&E, &mut WindowContext) + 'static {
1964 let view = view.downgrade();
1965 move |e: &E, cx: &mut WindowContext| {
1966 view.update(cx, |view, cx| f(view, e, cx)).ok();
1967 }
1968 }
1969
1970 /// Returns a generic handler that invokes the given handler with the view and context associated with the given view handle.
1971 pub fn handler_for<V: Render>(
1972 &self,
1973 view: &View<V>,
1974 f: impl Fn(&mut V, &mut ViewContext<V>) + 'static,
1975 ) -> impl Fn(&mut WindowContext) {
1976 let view = view.downgrade();
1977 move |cx: &mut WindowContext| {
1978 view.update(cx, |view, cx| f(view, cx)).ok();
1979 }
1980 }
1981
1982 /// Invoke the given function with the given focus handle present on the key dispatch stack.
1983 /// 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.
1984 pub fn with_key_dispatch<R>(
1985 &mut self,
1986 context: Option<KeyContext>,
1987 focus_handle: Option<FocusHandle>,
1988 f: impl FnOnce(Option<FocusHandle>, &mut Self) -> R,
1989 ) -> R {
1990 let window = &mut self.window;
1991 let focus_id = focus_handle.as_ref().map(|handle| handle.id);
1992 window
1993 .next_frame
1994 .dispatch_tree
1995 .push_node(context.clone(), focus_id, None);
1996
1997 let result = f(focus_handle, self);
1998
1999 self.window.next_frame.dispatch_tree.pop_node();
2000
2001 result
2002 }
2003
2004 pub(crate) fn with_view_id<R>(
2005 &mut self,
2006 view_id: EntityId,
2007 f: impl FnOnce(&mut Self) -> R,
2008 ) -> R {
2009 let text_system = self.text_system().clone();
2010 text_system.with_view(view_id, || {
2011 self.window.next_frame.view_stack.push(view_id);
2012 let result = f(self);
2013 self.window.next_frame.view_stack.pop();
2014 result
2015 })
2016 }
2017
2018 pub(crate) fn paint_view<R>(&mut self, view_id: EntityId, f: impl FnOnce(&mut Self) -> R) -> R {
2019 self.with_view_id(view_id, |cx| {
2020 cx.window
2021 .next_frame
2022 .dispatch_tree
2023 .push_node(None, None, Some(view_id));
2024 let result = f(cx);
2025 cx.window.next_frame.dispatch_tree.pop_node();
2026 result
2027 })
2028 }
2029
2030 /// Update or initialize state for an element with the given id that lives across multiple
2031 /// frames. If an element with this id existed in the rendered frame, its state will be passed
2032 /// to the given closure. The state returned by the closure will be stored so it can be referenced
2033 /// when drawing the next frame.
2034 pub(crate) fn with_element_state<S, R>(
2035 &mut self,
2036 id: ElementId,
2037 f: impl FnOnce(Option<S>, &mut Self) -> (R, S),
2038 ) -> R
2039 where
2040 S: 'static,
2041 {
2042 self.with_element_id(Some(id), |cx| {
2043 let global_id = cx.window().element_id_stack.clone();
2044
2045 if let Some(any) = cx
2046 .window_mut()
2047 .next_frame
2048 .element_states
2049 .remove(&global_id)
2050 .or_else(|| {
2051 cx.window_mut()
2052 .rendered_frame
2053 .element_states
2054 .remove(&global_id)
2055 })
2056 {
2057 let ElementStateBox {
2058 inner,
2059 parent_view_id,
2060 #[cfg(debug_assertions)]
2061 type_name
2062 } = any;
2063 // Using the extra inner option to avoid needing to reallocate a new box.
2064 let mut state_box = inner
2065 .downcast::<Option<S>>()
2066 .map_err(|_| {
2067 #[cfg(debug_assertions)]
2068 {
2069 anyhow!(
2070 "invalid element state type for id, requested_type {:?}, actual type: {:?}",
2071 std::any::type_name::<S>(),
2072 type_name
2073 )
2074 }
2075
2076 #[cfg(not(debug_assertions))]
2077 {
2078 anyhow!(
2079 "invalid element state type for id, requested_type {:?}",
2080 std::any::type_name::<S>(),
2081 )
2082 }
2083 })
2084 .unwrap();
2085
2086 // Actual: Option<AnyElement> <- View
2087 // Requested: () <- AnyElemet
2088 let state = state_box
2089 .take()
2090 .expect("element state is already on the stack");
2091 let (result, state) = f(Some(state), cx);
2092 state_box.replace(state);
2093 cx.window_mut()
2094 .next_frame
2095 .element_states
2096 .insert(global_id, ElementStateBox {
2097 inner: state_box,
2098 parent_view_id,
2099 #[cfg(debug_assertions)]
2100 type_name
2101 });
2102 result
2103 } else {
2104 let (result, state) = f(None, cx);
2105 let parent_view_id = cx.parent_view_id();
2106 cx.window_mut()
2107 .next_frame
2108 .element_states
2109 .insert(global_id,
2110 ElementStateBox {
2111 inner: Box::new(Some(state)),
2112 parent_view_id,
2113 #[cfg(debug_assertions)]
2114 type_name: std::any::type_name::<S>()
2115 }
2116
2117 );
2118 result
2119 }
2120 })
2121 }
2122
2123 fn parent_view_id(&self) -> EntityId {
2124 *self
2125 .window
2126 .next_frame
2127 .view_stack
2128 .last()
2129 .expect("a view should always be on the stack while drawing")
2130 }
2131
2132 /// Set an input handler, such as [`ElementInputHandler`][element_input_handler], which interfaces with the
2133 /// platform to receive textual input with proper integration with concerns such
2134 /// as IME interactions.
2135 ///
2136 /// [element_input_handler]: crate::ElementInputHandler
2137 pub fn handle_input(
2138 &mut self,
2139 focus_handle: &FocusHandle,
2140 input_handler: impl PlatformInputHandler,
2141 ) {
2142 if focus_handle.is_focused(self) {
2143 let view_id = self.parent_view_id();
2144 self.window.next_frame.requested_input_handler = Some(RequestedInputHandler {
2145 view_id,
2146 handler: Some(Box::new(input_handler)),
2147 })
2148 }
2149 }
2150
2151 /// Register a callback that can interrupt the closing of the current window based the returned boolean.
2152 /// If the callback returns false, the window won't be closed.
2153 pub fn on_window_should_close(&mut self, f: impl Fn(&mut WindowContext) -> bool + 'static) {
2154 let mut this = self.to_async();
2155 self.window
2156 .platform_window
2157 .on_should_close(Box::new(move || this.update(|_, cx| f(cx)).unwrap_or(true)))
2158 }
2159}
2160
2161impl Context for WindowContext<'_> {
2162 type Result<T> = T;
2163
2164 fn new_model<T>(&mut self, build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T) -> Model<T>
2165 where
2166 T: 'static,
2167 {
2168 let slot = self.app.entities.reserve();
2169 let model = build_model(&mut ModelContext::new(&mut *self.app, slot.downgrade()));
2170 self.entities.insert(slot, model)
2171 }
2172
2173 fn update_model<T: 'static, R>(
2174 &mut self,
2175 model: &Model<T>,
2176 update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
2177 ) -> R {
2178 let mut entity = self.entities.lease(model);
2179 let result = update(
2180 &mut *entity,
2181 &mut ModelContext::new(&mut *self.app, model.downgrade()),
2182 );
2183 self.entities.end_lease(entity);
2184 result
2185 }
2186
2187 fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
2188 where
2189 F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
2190 {
2191 if window == self.window.handle {
2192 let root_view = self.window.root_view.clone().unwrap();
2193 Ok(update(root_view, self))
2194 } else {
2195 window.update(self.app, update)
2196 }
2197 }
2198
2199 fn read_model<T, R>(
2200 &self,
2201 handle: &Model<T>,
2202 read: impl FnOnce(&T, &AppContext) -> R,
2203 ) -> Self::Result<R>
2204 where
2205 T: 'static,
2206 {
2207 let entity = self.entities.read(handle);
2208 read(entity, &*self.app)
2209 }
2210
2211 fn read_window<T, R>(
2212 &self,
2213 window: &WindowHandle<T>,
2214 read: impl FnOnce(View<T>, &AppContext) -> R,
2215 ) -> Result<R>
2216 where
2217 T: 'static,
2218 {
2219 if window.any_handle == self.window.handle {
2220 let root_view = self
2221 .window
2222 .root_view
2223 .clone()
2224 .unwrap()
2225 .downcast::<T>()
2226 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
2227 Ok(read(root_view, self))
2228 } else {
2229 self.app.read_window(window, read)
2230 }
2231 }
2232}
2233
2234impl VisualContext for WindowContext<'_> {
2235 fn new_view<V>(
2236 &mut self,
2237 build_view_state: impl FnOnce(&mut ViewContext<'_, V>) -> V,
2238 ) -> Self::Result<View<V>>
2239 where
2240 V: 'static + Render,
2241 {
2242 let slot = self.app.entities.reserve();
2243 let view = View {
2244 model: slot.clone(),
2245 };
2246 let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, &view);
2247 let entity = build_view_state(&mut cx);
2248 cx.entities.insert(slot, entity);
2249
2250 cx.new_view_observers
2251 .clone()
2252 .retain(&TypeId::of::<V>(), |observer| {
2253 let any_view = AnyView::from(view.clone());
2254 (observer)(any_view, self);
2255 true
2256 });
2257
2258 view
2259 }
2260
2261 /// Update the given view. Prefer calling `View::update` instead, which calls this method.
2262 fn update_view<T: 'static, R>(
2263 &mut self,
2264 view: &View<T>,
2265 update: impl FnOnce(&mut T, &mut ViewContext<'_, T>) -> R,
2266 ) -> Self::Result<R> {
2267 let mut lease = self.app.entities.lease(&view.model);
2268 let mut cx = ViewContext::new(&mut *self.app, &mut *self.window, view);
2269 let result = update(&mut *lease, &mut cx);
2270 cx.app.entities.end_lease(lease);
2271 result
2272 }
2273
2274 fn replace_root_view<V>(
2275 &mut self,
2276 build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V,
2277 ) -> Self::Result<View<V>>
2278 where
2279 V: 'static + Render,
2280 {
2281 let view = self.new_view(build_view);
2282 self.window.root_view = Some(view.clone().into());
2283 self.refresh();
2284 view
2285 }
2286
2287 fn focus_view<V: crate::FocusableView>(&mut self, view: &View<V>) -> Self::Result<()> {
2288 self.update_view(view, |view, cx| {
2289 view.focus_handle(cx).clone().focus(cx);
2290 })
2291 }
2292
2293 fn dismiss_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
2294 where
2295 V: ManagedView,
2296 {
2297 self.update_view(view, |_, cx| cx.emit(DismissEvent))
2298 }
2299}
2300
2301impl<'a> std::ops::Deref for WindowContext<'a> {
2302 type Target = AppContext;
2303
2304 fn deref(&self) -> &Self::Target {
2305 self.app
2306 }
2307}
2308
2309impl<'a> std::ops::DerefMut for WindowContext<'a> {
2310 fn deref_mut(&mut self) -> &mut Self::Target {
2311 self.app
2312 }
2313}
2314
2315impl<'a> Borrow<AppContext> for WindowContext<'a> {
2316 fn borrow(&self) -> &AppContext {
2317 self.app
2318 }
2319}
2320
2321impl<'a> BorrowMut<AppContext> for WindowContext<'a> {
2322 fn borrow_mut(&mut self) -> &mut AppContext {
2323 self.app
2324 }
2325}
2326
2327/// This trait contains functionality that is shared across [`ViewContext`] and [`WindowContext`]
2328pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
2329 #[doc(hidden)]
2330 fn app_mut(&mut self) -> &mut AppContext {
2331 self.borrow_mut()
2332 }
2333
2334 #[doc(hidden)]
2335 fn app(&self) -> &AppContext {
2336 self.borrow()
2337 }
2338
2339 #[doc(hidden)]
2340 fn window(&self) -> &Window {
2341 self.borrow()
2342 }
2343
2344 #[doc(hidden)]
2345 fn window_mut(&mut self) -> &mut Window {
2346 self.borrow_mut()
2347 }
2348
2349 /// Pushes the given element id onto the global stack and invokes the given closure
2350 /// with a `GlobalElementId`, which disambiguates the given id in the context of its ancestor
2351 /// ids. Because elements are discarded and recreated on each frame, the `GlobalElementId` is
2352 /// used to associate state with identified elements across separate frames.
2353 fn with_element_id<R>(
2354 &mut self,
2355 id: Option<impl Into<ElementId>>,
2356 f: impl FnOnce(&mut Self) -> R,
2357 ) -> R {
2358 if let Some(id) = id.map(Into::into) {
2359 let window = self.window_mut();
2360 window.element_id_stack.push(id);
2361 let result = f(self);
2362 let window: &mut Window = self.borrow_mut();
2363 window.element_id_stack.pop();
2364 result
2365 } else {
2366 f(self)
2367 }
2368 }
2369
2370 /// Invoke the given function with the given content mask after intersecting it
2371 /// with the current mask.
2372 fn with_content_mask<R>(
2373 &mut self,
2374 mask: Option<ContentMask<Pixels>>,
2375 f: impl FnOnce(&mut Self) -> R,
2376 ) -> R {
2377 if let Some(mask) = mask {
2378 let mask = mask.intersect(&self.content_mask());
2379 self.window_mut().next_frame.content_mask_stack.push(mask);
2380 let result = f(self);
2381 self.window_mut().next_frame.content_mask_stack.pop();
2382 result
2383 } else {
2384 f(self)
2385 }
2386 }
2387
2388 /// Invoke the given function with the content mask reset to that
2389 /// of the window.
2390 fn break_content_mask<R>(&mut self, f: impl FnOnce(&mut Self) -> R) -> R {
2391 let mask = ContentMask {
2392 bounds: Bounds {
2393 origin: Point::default(),
2394 size: self.window().viewport_size,
2395 },
2396 };
2397 let new_stacking_order_id =
2398 post_inc(&mut self.window_mut().next_frame.next_stacking_order_id);
2399 let old_stacking_order = mem::take(&mut self.window_mut().next_frame.z_index_stack);
2400 self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id;
2401 self.window_mut().next_frame.content_mask_stack.push(mask);
2402 let result = f(self);
2403 self.window_mut().next_frame.content_mask_stack.pop();
2404 self.window_mut().next_frame.z_index_stack = old_stacking_order;
2405 result
2406 }
2407
2408 /// Called during painting to invoke the given closure in a new stacking context. The given
2409 /// z-index is interpreted relative to the previous call to `stack`.
2410 fn with_z_index<R>(&mut self, z_index: u8, f: impl FnOnce(&mut Self) -> R) -> R {
2411 let new_stacking_order_id =
2412 post_inc(&mut self.window_mut().next_frame.next_stacking_order_id);
2413 let old_stacking_order_id = mem::replace(
2414 &mut self.window_mut().next_frame.z_index_stack.id,
2415 new_stacking_order_id,
2416 );
2417 self.window_mut().next_frame.z_index_stack.id = new_stacking_order_id;
2418 self.window_mut().next_frame.z_index_stack.push(z_index);
2419 let result = f(self);
2420 self.window_mut().next_frame.z_index_stack.id = old_stacking_order_id;
2421 self.window_mut().next_frame.z_index_stack.pop();
2422 result
2423 }
2424
2425 /// Update the global element offset relative to the current offset. This is used to implement
2426 /// scrolling.
2427 fn with_element_offset<R>(
2428 &mut self,
2429 offset: Point<Pixels>,
2430 f: impl FnOnce(&mut Self) -> R,
2431 ) -> R {
2432 if offset.is_zero() {
2433 return f(self);
2434 };
2435
2436 let abs_offset = self.element_offset() + offset;
2437 self.with_absolute_element_offset(abs_offset, f)
2438 }
2439
2440 /// Update the global element offset based on the given offset. This is used to implement
2441 /// drag handles and other manual painting of elements.
2442 fn with_absolute_element_offset<R>(
2443 &mut self,
2444 offset: Point<Pixels>,
2445 f: impl FnOnce(&mut Self) -> R,
2446 ) -> R {
2447 self.window_mut()
2448 .next_frame
2449 .element_offset_stack
2450 .push(offset);
2451 let result = f(self);
2452 self.window_mut().next_frame.element_offset_stack.pop();
2453 result
2454 }
2455
2456 /// Obtain the current element offset.
2457 fn element_offset(&self) -> Point<Pixels> {
2458 self.window()
2459 .next_frame
2460 .element_offset_stack
2461 .last()
2462 .copied()
2463 .unwrap_or_default()
2464 }
2465
2466 /// Obtain the current content mask.
2467 fn content_mask(&self) -> ContentMask<Pixels> {
2468 self.window()
2469 .next_frame
2470 .content_mask_stack
2471 .last()
2472 .cloned()
2473 .unwrap_or_else(|| ContentMask {
2474 bounds: Bounds {
2475 origin: Point::default(),
2476 size: self.window().viewport_size,
2477 },
2478 })
2479 }
2480
2481 /// The size of an em for the base font of the application. Adjusting this value allows the
2482 /// UI to scale, just like zooming a web page.
2483 fn rem_size(&self) -> Pixels {
2484 self.window().rem_size
2485 }
2486}
2487
2488impl Borrow<Window> for WindowContext<'_> {
2489 fn borrow(&self) -> &Window {
2490 self.window
2491 }
2492}
2493
2494impl BorrowMut<Window> for WindowContext<'_> {
2495 fn borrow_mut(&mut self) -> &mut Window {
2496 self.window
2497 }
2498}
2499
2500impl<T> BorrowWindow for T where T: BorrowMut<AppContext> + BorrowMut<Window> {}
2501
2502/// Provides access to application state that is specialized for a particular [`View`].
2503/// Allows you to interact with focus, emit events, etc.
2504/// ViewContext also derefs to [`WindowContext`], giving you access to all of its methods as well.
2505/// When you call [`View::update`], you're passed a `&mut V` and an `&mut ViewContext<V>`.
2506pub struct ViewContext<'a, V> {
2507 window_cx: WindowContext<'a>,
2508 view: &'a View<V>,
2509}
2510
2511impl<V> Borrow<AppContext> for ViewContext<'_, V> {
2512 fn borrow(&self) -> &AppContext {
2513 &*self.window_cx.app
2514 }
2515}
2516
2517impl<V> BorrowMut<AppContext> for ViewContext<'_, V> {
2518 fn borrow_mut(&mut self) -> &mut AppContext {
2519 &mut *self.window_cx.app
2520 }
2521}
2522
2523impl<V> Borrow<Window> for ViewContext<'_, V> {
2524 fn borrow(&self) -> &Window {
2525 &*self.window_cx.window
2526 }
2527}
2528
2529impl<V> BorrowMut<Window> for ViewContext<'_, V> {
2530 fn borrow_mut(&mut self) -> &mut Window {
2531 &mut *self.window_cx.window
2532 }
2533}
2534
2535impl<'a, V: 'static> ViewContext<'a, V> {
2536 pub(crate) fn new(app: &'a mut AppContext, window: &'a mut Window, view: &'a View<V>) -> Self {
2537 Self {
2538 window_cx: WindowContext::new(app, window),
2539 view,
2540 }
2541 }
2542
2543 /// Get the entity_id of this view.
2544 pub fn entity_id(&self) -> EntityId {
2545 self.view.entity_id()
2546 }
2547
2548 /// Get the view pointer underlying this context.
2549 pub fn view(&self) -> &View<V> {
2550 self.view
2551 }
2552
2553 /// Get the model underlying this view.
2554 pub fn model(&self) -> &Model<V> {
2555 &self.view.model
2556 }
2557
2558 /// Access the underlying window context.
2559 pub fn window_context(&mut self) -> &mut WindowContext<'a> {
2560 &mut self.window_cx
2561 }
2562
2563 /// Set a given callback to be run on the next frame.
2564 pub fn on_next_frame(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + 'static)
2565 where
2566 V: 'static,
2567 {
2568 let view = self.view().clone();
2569 self.window_cx.on_next_frame(move |cx| view.update(cx, f));
2570 }
2571
2572 /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
2573 /// that are currently on the stack to be returned to the app.
2574 pub fn defer(&mut self, f: impl FnOnce(&mut V, &mut ViewContext<V>) + 'static) {
2575 let view = self.view().downgrade();
2576 self.window_cx.defer(move |cx| {
2577 view.update(cx, f).ok();
2578 });
2579 }
2580
2581 /// Observe another model or view for changes to its state, as tracked by [`ModelContext::notify`].
2582 pub fn observe<V2, E>(
2583 &mut self,
2584 entity: &E,
2585 mut on_notify: impl FnMut(&mut V, E, &mut ViewContext<'_, V>) + 'static,
2586 ) -> Subscription
2587 where
2588 V2: 'static,
2589 V: 'static,
2590 E: Entity<V2>,
2591 {
2592 let view = self.view().downgrade();
2593 let entity_id = entity.entity_id();
2594 let entity = entity.downgrade();
2595 let window_handle = self.window.handle;
2596 let (subscription, activate) = self.app.observers.insert(
2597 entity_id,
2598 Box::new(move |cx| {
2599 window_handle
2600 .update(cx, |_, cx| {
2601 if let Some(handle) = E::upgrade_from(&entity) {
2602 view.update(cx, |this, cx| on_notify(this, handle, cx))
2603 .is_ok()
2604 } else {
2605 false
2606 }
2607 })
2608 .unwrap_or(false)
2609 }),
2610 );
2611 self.app.defer(move |_| activate());
2612 subscription
2613 }
2614
2615 /// Subscribe to events emitted by another model or view.
2616 /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
2617 /// 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.
2618 pub fn subscribe<V2, E, Evt>(
2619 &mut self,
2620 entity: &E,
2621 mut on_event: impl FnMut(&mut V, E, &Evt, &mut ViewContext<'_, V>) + 'static,
2622 ) -> Subscription
2623 where
2624 V2: EventEmitter<Evt>,
2625 E: Entity<V2>,
2626 Evt: 'static,
2627 {
2628 let view = self.view().downgrade();
2629 let entity_id = entity.entity_id();
2630 let handle = entity.downgrade();
2631 let window_handle = self.window.handle;
2632 let (subscription, activate) = self.app.event_listeners.insert(
2633 entity_id,
2634 (
2635 TypeId::of::<Evt>(),
2636 Box::new(move |event, cx| {
2637 window_handle
2638 .update(cx, |_, cx| {
2639 if let Some(handle) = E::upgrade_from(&handle) {
2640 let event = event.downcast_ref().expect("invalid event type");
2641 view.update(cx, |this, cx| on_event(this, handle, event, cx))
2642 .is_ok()
2643 } else {
2644 false
2645 }
2646 })
2647 .unwrap_or(false)
2648 }),
2649 ),
2650 );
2651 self.app.defer(move |_| activate());
2652 subscription
2653 }
2654
2655 /// Register a callback to be invoked when the view is released.
2656 ///
2657 /// The callback receives a handle to the view's window. This handle may be
2658 /// invalid, if the window was closed before the view was released.
2659 pub fn on_release(
2660 &mut self,
2661 on_release: impl FnOnce(&mut V, AnyWindowHandle, &mut AppContext) + 'static,
2662 ) -> Subscription {
2663 let window_handle = self.window.handle;
2664 let (subscription, activate) = self.app.release_listeners.insert(
2665 self.view.model.entity_id,
2666 Box::new(move |this, cx| {
2667 let this = this.downcast_mut().expect("invalid entity type");
2668 on_release(this, window_handle, cx)
2669 }),
2670 );
2671 activate();
2672 subscription
2673 }
2674
2675 /// Register a callback to be invoked when the given Model or View is released.
2676 pub fn observe_release<V2, E>(
2677 &mut self,
2678 entity: &E,
2679 mut on_release: impl FnMut(&mut V, &mut V2, &mut ViewContext<'_, V>) + 'static,
2680 ) -> Subscription
2681 where
2682 V: 'static,
2683 V2: 'static,
2684 E: Entity<V2>,
2685 {
2686 let view = self.view().downgrade();
2687 let entity_id = entity.entity_id();
2688 let window_handle = self.window.handle;
2689 let (subscription, activate) = self.app.release_listeners.insert(
2690 entity_id,
2691 Box::new(move |entity, cx| {
2692 let entity = entity.downcast_mut().expect("invalid entity type");
2693 let _ = window_handle.update(cx, |_, cx| {
2694 view.update(cx, |this, cx| on_release(this, entity, cx))
2695 });
2696 }),
2697 );
2698 activate();
2699 subscription
2700 }
2701
2702 /// Indicate that this view has changed, which will invoke any observers and also mark the window as dirty.
2703 /// If this view or any of its ancestors are *cached*, notifying it will cause it or its ancestors to be redrawn.
2704 pub fn notify(&mut self) {
2705 for view_id in self
2706 .window
2707 .rendered_frame
2708 .dispatch_tree
2709 .view_path(self.view.entity_id())
2710 {
2711 if !self.window.dirty_views.insert(view_id) {
2712 break;
2713 }
2714 }
2715
2716 if !self.window.drawing {
2717 self.window_cx.window.dirty = true;
2718 self.window_cx.app.push_effect(Effect::Notify {
2719 emitter: self.view.model.entity_id,
2720 });
2721 }
2722 }
2723
2724 /// Register a callback to be invoked when the window is resized.
2725 pub fn observe_window_bounds(
2726 &mut self,
2727 mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2728 ) -> Subscription {
2729 let view = self.view.downgrade();
2730 let (subscription, activate) = self.window.bounds_observers.insert(
2731 (),
2732 Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
2733 );
2734 activate();
2735 subscription
2736 }
2737
2738 /// Register a callback to be invoked when the window is activated or deactivated.
2739 pub fn observe_window_activation(
2740 &mut self,
2741 mut callback: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2742 ) -> Subscription {
2743 let view = self.view.downgrade();
2744 let (subscription, activate) = self.window.activation_observers.insert(
2745 (),
2746 Box::new(move |cx| view.update(cx, |view, cx| callback(view, cx)).is_ok()),
2747 );
2748 activate();
2749 subscription
2750 }
2751
2752 /// Register a listener to be called when the given focus handle receives focus.
2753 /// Returns a subscription and persists until the subscription is dropped.
2754 pub fn on_focus(
2755 &mut self,
2756 handle: &FocusHandle,
2757 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2758 ) -> Subscription {
2759 let view = self.view.downgrade();
2760 let focus_id = handle.id;
2761 let (subscription, activate) = self.window.focus_listeners.insert(
2762 (),
2763 Box::new(move |event, cx| {
2764 view.update(cx, |view, cx| {
2765 if event.previous_focus_path.last() != Some(&focus_id)
2766 && event.current_focus_path.last() == Some(&focus_id)
2767 {
2768 listener(view, cx)
2769 }
2770 })
2771 .is_ok()
2772 }),
2773 );
2774 self.app.defer(move |_| activate());
2775 subscription
2776 }
2777
2778 /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
2779 /// Returns a subscription and persists until the subscription is dropped.
2780 pub fn on_focus_in(
2781 &mut self,
2782 handle: &FocusHandle,
2783 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2784 ) -> Subscription {
2785 let view = self.view.downgrade();
2786 let focus_id = handle.id;
2787 let (subscription, activate) = self.window.focus_listeners.insert(
2788 (),
2789 Box::new(move |event, cx| {
2790 view.update(cx, |view, cx| {
2791 if !event.previous_focus_path.contains(&focus_id)
2792 && event.current_focus_path.contains(&focus_id)
2793 {
2794 listener(view, cx)
2795 }
2796 })
2797 .is_ok()
2798 }),
2799 );
2800 self.app.defer(move |_| activate());
2801 subscription
2802 }
2803
2804 /// Register a listener to be called when the given focus handle loses focus.
2805 /// Returns a subscription and persists until the subscription is dropped.
2806 pub fn on_blur(
2807 &mut self,
2808 handle: &FocusHandle,
2809 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2810 ) -> Subscription {
2811 let view = self.view.downgrade();
2812 let focus_id = handle.id;
2813 let (subscription, activate) = self.window.focus_listeners.insert(
2814 (),
2815 Box::new(move |event, cx| {
2816 view.update(cx, |view, cx| {
2817 if event.previous_focus_path.last() == Some(&focus_id)
2818 && event.current_focus_path.last() != Some(&focus_id)
2819 {
2820 listener(view, cx)
2821 }
2822 })
2823 .is_ok()
2824 }),
2825 );
2826 self.app.defer(move |_| activate());
2827 subscription
2828 }
2829
2830 /// Register a listener to be called when nothing in the window has focus.
2831 /// This typically happens when the node that was focused is removed from the tree,
2832 /// and this callback lets you chose a default place to restore the users focus.
2833 /// Returns a subscription and persists until the subscription is dropped.
2834 pub fn on_focus_lost(
2835 &mut self,
2836 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2837 ) -> Subscription {
2838 let view = self.view.downgrade();
2839 let (subscription, activate) = self.window.focus_lost_listeners.insert(
2840 (),
2841 Box::new(move |cx| view.update(cx, |view, cx| listener(view, cx)).is_ok()),
2842 );
2843 activate();
2844 subscription
2845 }
2846
2847 /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
2848 /// Returns a subscription and persists until the subscription is dropped.
2849 pub fn on_focus_out(
2850 &mut self,
2851 handle: &FocusHandle,
2852 mut listener: impl FnMut(&mut V, &mut ViewContext<V>) + 'static,
2853 ) -> Subscription {
2854 let view = self.view.downgrade();
2855 let focus_id = handle.id;
2856 let (subscription, activate) = self.window.focus_listeners.insert(
2857 (),
2858 Box::new(move |event, cx| {
2859 view.update(cx, |view, cx| {
2860 if event.previous_focus_path.contains(&focus_id)
2861 && !event.current_focus_path.contains(&focus_id)
2862 {
2863 listener(view, cx)
2864 }
2865 })
2866 .is_ok()
2867 }),
2868 );
2869 self.app.defer(move |_| activate());
2870 subscription
2871 }
2872
2873 /// Schedule a future to be run asynchronously.
2874 /// The given callback is invoked with a [`WeakView<V>`] to avoid leaking the view for a long-running process.
2875 /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the view across await points.
2876 /// The returned future will be polled on the main thread.
2877 pub fn spawn<Fut, R>(
2878 &mut self,
2879 f: impl FnOnce(WeakView<V>, AsyncWindowContext) -> Fut,
2880 ) -> Task<R>
2881 where
2882 R: 'static,
2883 Fut: Future<Output = R> + 'static,
2884 {
2885 let view = self.view().downgrade();
2886 self.window_cx.spawn(|cx| f(view, cx))
2887 }
2888
2889 /// Update the global state of the given type.
2890 pub fn update_global<G, R>(&mut self, f: impl FnOnce(&mut G, &mut Self) -> R) -> R
2891 where
2892 G: 'static,
2893 {
2894 let mut global = self.app.lease_global::<G>();
2895 let result = f(&mut global, self);
2896 self.app.end_global_lease(global);
2897 result
2898 }
2899
2900 /// Register a callback to be invoked when the given global state changes.
2901 pub fn observe_global<G: 'static>(
2902 &mut self,
2903 mut f: impl FnMut(&mut V, &mut ViewContext<'_, V>) + 'static,
2904 ) -> Subscription {
2905 let window_handle = self.window.handle;
2906 let view = self.view().downgrade();
2907 let (subscription, activate) = self.global_observers.insert(
2908 TypeId::of::<G>(),
2909 Box::new(move |cx| {
2910 window_handle
2911 .update(cx, |_, cx| view.update(cx, |view, cx| f(view, cx)).is_ok())
2912 .unwrap_or(false)
2913 }),
2914 );
2915 self.app.defer(move |_| activate());
2916 subscription
2917 }
2918
2919 /// Add a listener for any mouse event that occurs in the window.
2920 /// This is a fairly low level method.
2921 /// Typically, you'll want to use methods on UI elements, which perform bounds checking etc.
2922 pub fn on_mouse_event<Event: 'static>(
2923 &mut self,
2924 handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + 'static,
2925 ) {
2926 let handle = self.view().clone();
2927 self.window_cx.on_mouse_event(move |event, phase, cx| {
2928 handle.update(cx, |view, cx| {
2929 handler(view, event, phase, cx);
2930 })
2931 });
2932 }
2933
2934 /// Register a callback to be invoked when the given Key Event is dispatched to the window.
2935 pub fn on_key_event<Event: 'static>(
2936 &mut self,
2937 handler: impl Fn(&mut V, &Event, DispatchPhase, &mut ViewContext<V>) + 'static,
2938 ) {
2939 let handle = self.view().clone();
2940 self.window_cx.on_key_event(move |event, phase, cx| {
2941 handle.update(cx, |view, cx| {
2942 handler(view, event, phase, cx);
2943 })
2944 });
2945 }
2946
2947 /// Register a callback to be invoked when the given Action type is dispatched to the window.
2948 pub fn on_action(
2949 &mut self,
2950 action_type: TypeId,
2951 listener: impl Fn(&mut V, &dyn Any, DispatchPhase, &mut ViewContext<V>) + 'static,
2952 ) {
2953 let handle = self.view().clone();
2954 self.window_cx
2955 .on_action(action_type, move |action, phase, cx| {
2956 handle.update(cx, |view, cx| {
2957 listener(view, action, phase, cx);
2958 })
2959 });
2960 }
2961
2962 /// Emit an event to be handled any other views that have subscribed via [ViewContext::subscribe].
2963 pub fn emit<Evt>(&mut self, event: Evt)
2964 where
2965 Evt: 'static,
2966 V: EventEmitter<Evt>,
2967 {
2968 let emitter = self.view.model.entity_id;
2969 self.app.push_effect(Effect::Emit {
2970 emitter,
2971 event_type: TypeId::of::<Evt>(),
2972 event: Box::new(event),
2973 });
2974 }
2975
2976 /// Move focus to the current view, assuming it implements [`FocusableView`].
2977 pub fn focus_self(&mut self)
2978 where
2979 V: FocusableView,
2980 {
2981 self.defer(|view, cx| view.focus_handle(cx).focus(cx))
2982 }
2983
2984 /// Convenience method for accessing view state in an event callback.
2985 ///
2986 /// Many GPUI callbacks take the form of `Fn(&E, &mut WindowContext)`,
2987 /// but it's often useful to be able to access view state in these
2988 /// callbacks. This method provides a convenient way to do so.
2989 pub fn listener<E>(
2990 &self,
2991 f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
2992 ) -> impl Fn(&E, &mut WindowContext) + 'static {
2993 let view = self.view().downgrade();
2994 move |e: &E, cx: &mut WindowContext| {
2995 view.update(cx, |view, cx| f(view, e, cx)).ok();
2996 }
2997 }
2998}
2999
3000impl<V> Context for ViewContext<'_, V> {
3001 type Result<U> = U;
3002
3003 fn new_model<T: 'static>(
3004 &mut self,
3005 build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
3006 ) -> Model<T> {
3007 self.window_cx.new_model(build_model)
3008 }
3009
3010 fn update_model<T: 'static, R>(
3011 &mut self,
3012 model: &Model<T>,
3013 update: impl FnOnce(&mut T, &mut ModelContext<'_, T>) -> R,
3014 ) -> R {
3015 self.window_cx.update_model(model, update)
3016 }
3017
3018 fn update_window<T, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<T>
3019 where
3020 F: FnOnce(AnyView, &mut WindowContext<'_>) -> T,
3021 {
3022 self.window_cx.update_window(window, update)
3023 }
3024
3025 fn read_model<T, R>(
3026 &self,
3027 handle: &Model<T>,
3028 read: impl FnOnce(&T, &AppContext) -> R,
3029 ) -> Self::Result<R>
3030 where
3031 T: 'static,
3032 {
3033 self.window_cx.read_model(handle, read)
3034 }
3035
3036 fn read_window<T, R>(
3037 &self,
3038 window: &WindowHandle<T>,
3039 read: impl FnOnce(View<T>, &AppContext) -> R,
3040 ) -> Result<R>
3041 where
3042 T: 'static,
3043 {
3044 self.window_cx.read_window(window, read)
3045 }
3046}
3047
3048impl<V: 'static> VisualContext for ViewContext<'_, V> {
3049 fn new_view<W: Render + 'static>(
3050 &mut self,
3051 build_view_state: impl FnOnce(&mut ViewContext<'_, W>) -> W,
3052 ) -> Self::Result<View<W>> {
3053 self.window_cx.new_view(build_view_state)
3054 }
3055
3056 fn update_view<V2: 'static, R>(
3057 &mut self,
3058 view: &View<V2>,
3059 update: impl FnOnce(&mut V2, &mut ViewContext<'_, V2>) -> R,
3060 ) -> Self::Result<R> {
3061 self.window_cx.update_view(view, update)
3062 }
3063
3064 fn replace_root_view<W>(
3065 &mut self,
3066 build_view: impl FnOnce(&mut ViewContext<'_, W>) -> W,
3067 ) -> Self::Result<View<W>>
3068 where
3069 W: 'static + Render,
3070 {
3071 self.window_cx.replace_root_view(build_view)
3072 }
3073
3074 fn focus_view<W: FocusableView>(&mut self, view: &View<W>) -> Self::Result<()> {
3075 self.window_cx.focus_view(view)
3076 }
3077
3078 fn dismiss_view<W: ManagedView>(&mut self, view: &View<W>) -> Self::Result<()> {
3079 self.window_cx.dismiss_view(view)
3080 }
3081}
3082
3083impl<'a, V> std::ops::Deref for ViewContext<'a, V> {
3084 type Target = WindowContext<'a>;
3085
3086 fn deref(&self) -> &Self::Target {
3087 &self.window_cx
3088 }
3089}
3090
3091impl<'a, V> std::ops::DerefMut for ViewContext<'a, V> {
3092 fn deref_mut(&mut self) -> &mut Self::Target {
3093 &mut self.window_cx
3094 }
3095}
3096
3097// #[derive(Clone, Copy, Eq, PartialEq, Hash)]
3098slotmap::new_key_type! {
3099 /// A unique identifier for a window.
3100 pub struct WindowId;
3101}
3102
3103impl WindowId {
3104 /// Converts this window ID to a `u64`.
3105 pub fn as_u64(&self) -> u64 {
3106 self.0.as_ffi()
3107 }
3108}
3109
3110/// A handle to a window with a specific root view type.
3111/// Note that this does not keep the window alive on its own.
3112#[derive(Deref, DerefMut)]
3113pub struct WindowHandle<V> {
3114 #[deref]
3115 #[deref_mut]
3116 pub(crate) any_handle: AnyWindowHandle,
3117 state_type: PhantomData<V>,
3118}
3119
3120impl<V: 'static + Render> WindowHandle<V> {
3121 /// Create a new handle from a window ID.
3122 /// This does not check if the root type of the window is `V`.
3123 pub fn new(id: WindowId) -> Self {
3124 WindowHandle {
3125 any_handle: AnyWindowHandle {
3126 id,
3127 state_type: TypeId::of::<V>(),
3128 },
3129 state_type: PhantomData,
3130 }
3131 }
3132
3133 /// Get the root view out of this window.
3134 ///
3135 /// This will fail if the window is closed or if the root view's type does not match `V`.
3136 pub fn root<C>(&self, cx: &mut C) -> Result<View<V>>
3137 where
3138 C: Context,
3139 {
3140 Flatten::flatten(cx.update_window(self.any_handle, |root_view, _| {
3141 root_view
3142 .downcast::<V>()
3143 .map_err(|_| anyhow!("the type of the window's root view has changed"))
3144 }))
3145 }
3146
3147 /// Update the root view of this window.
3148 ///
3149 /// This will fail if the window has been closed or if the root view's type does not match
3150 pub fn update<C, R>(
3151 &self,
3152 cx: &mut C,
3153 update: impl FnOnce(&mut V, &mut ViewContext<'_, V>) -> R,
3154 ) -> Result<R>
3155 where
3156 C: Context,
3157 {
3158 cx.update_window(self.any_handle, |root_view, cx| {
3159 let view = root_view
3160 .downcast::<V>()
3161 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
3162 Ok(cx.update_view(&view, update))
3163 })?
3164 }
3165
3166 /// Read the root view out of this window.
3167 ///
3168 /// This will fail if the window is closed or if the root view's type does not match `V`.
3169 pub fn read<'a>(&self, cx: &'a AppContext) -> Result<&'a V> {
3170 let x = cx
3171 .windows
3172 .get(self.id)
3173 .and_then(|window| {
3174 window
3175 .as_ref()
3176 .and_then(|window| window.root_view.clone())
3177 .map(|root_view| root_view.downcast::<V>())
3178 })
3179 .ok_or_else(|| anyhow!("window not found"))?
3180 .map_err(|_| anyhow!("the type of the window's root view has changed"))?;
3181
3182 Ok(x.read(cx))
3183 }
3184
3185 /// Read the root view out of this window, with a callback
3186 ///
3187 /// This will fail if the window is closed or if the root view's type does not match `V`.
3188 pub fn read_with<C, R>(&self, cx: &C, read_with: impl FnOnce(&V, &AppContext) -> R) -> Result<R>
3189 where
3190 C: Context,
3191 {
3192 cx.read_window(self, |root_view, cx| read_with(root_view.read(cx), cx))
3193 }
3194
3195 /// Read the root view pointer off of this window.
3196 ///
3197 /// This will fail if the window is closed or if the root view's type does not match `V`.
3198 pub fn root_view<C>(&self, cx: &C) -> Result<View<V>>
3199 where
3200 C: Context,
3201 {
3202 cx.read_window(self, |root_view, _cx| root_view.clone())
3203 }
3204
3205 /// Check if this window is 'active'.
3206 ///
3207 /// Will return `None` if the window is closed.
3208 pub fn is_active(&self, cx: &AppContext) -> Option<bool> {
3209 cx.windows
3210 .get(self.id)
3211 .and_then(|window| window.as_ref().map(|window| window.active))
3212 }
3213}
3214
3215impl<V> Copy for WindowHandle<V> {}
3216
3217impl<V> Clone for WindowHandle<V> {
3218 fn clone(&self) -> Self {
3219 *self
3220 }
3221}
3222
3223impl<V> PartialEq for WindowHandle<V> {
3224 fn eq(&self, other: &Self) -> bool {
3225 self.any_handle == other.any_handle
3226 }
3227}
3228
3229impl<V> Eq for WindowHandle<V> {}
3230
3231impl<V> Hash for WindowHandle<V> {
3232 fn hash<H: Hasher>(&self, state: &mut H) {
3233 self.any_handle.hash(state);
3234 }
3235}
3236
3237impl<V: 'static> From<WindowHandle<V>> for AnyWindowHandle {
3238 fn from(val: WindowHandle<V>) -> Self {
3239 val.any_handle
3240 }
3241}
3242
3243/// A handle to a window with any root view type, which can be downcast to a window with a specific root view type.
3244#[derive(Copy, Clone, PartialEq, Eq, Hash)]
3245pub struct AnyWindowHandle {
3246 pub(crate) id: WindowId,
3247 state_type: TypeId,
3248}
3249
3250impl AnyWindowHandle {
3251 /// Get the ID of this window.
3252 pub fn window_id(&self) -> WindowId {
3253 self.id
3254 }
3255
3256 /// Attempt to convert this handle to a window handle with a specific root view type.
3257 /// If the types do not match, this will return `None`.
3258 pub fn downcast<T: 'static>(&self) -> Option<WindowHandle<T>> {
3259 if TypeId::of::<T>() == self.state_type {
3260 Some(WindowHandle {
3261 any_handle: *self,
3262 state_type: PhantomData,
3263 })
3264 } else {
3265 None
3266 }
3267 }
3268
3269 /// Update the state of the root view of this window.
3270 ///
3271 /// This will fail if the window has been closed.
3272 pub fn update<C, R>(
3273 self,
3274 cx: &mut C,
3275 update: impl FnOnce(AnyView, &mut WindowContext<'_>) -> R,
3276 ) -> Result<R>
3277 where
3278 C: Context,
3279 {
3280 cx.update_window(self, update)
3281 }
3282
3283 /// Read the state of the root view of this window.
3284 ///
3285 /// This will fail if the window has been closed.
3286 pub fn read<T, C, R>(self, cx: &C, read: impl FnOnce(View<T>, &AppContext) -> R) -> Result<R>
3287 where
3288 C: Context,
3289 T: 'static,
3290 {
3291 let view = self
3292 .downcast::<T>()
3293 .context("the type of the window's root view has changed")?;
3294
3295 cx.read_window(&view, read)
3296 }
3297}
3298
3299// #[cfg(any(test, feature = "test-support"))]
3300// impl From<SmallVec<[u32; 16]>> for StackingOrder {
3301// fn from(small_vec: SmallVec<[u32; 16]>) -> Self {
3302// StackingOrder(small_vec)
3303// }
3304// }
3305
3306/// An identifier for an [`Element`](crate::Element).
3307///
3308/// Can be constructed with a string, a number, or both, as well
3309/// as other internal representations.
3310#[derive(Clone, Debug, Eq, PartialEq, Hash)]
3311pub enum ElementId {
3312 /// The ID of a View element
3313 View(EntityId),
3314 /// An integer ID.
3315 Integer(usize),
3316 /// A string based ID.
3317 Name(SharedString),
3318 /// An ID that's equated with a focus handle.
3319 FocusHandle(FocusId),
3320 /// A combination of a name and an integer.
3321 NamedInteger(SharedString, usize),
3322}
3323
3324impl ElementId {
3325 pub(crate) fn from_entity_id(entity_id: EntityId) -> Self {
3326 ElementId::View(entity_id)
3327 }
3328}
3329
3330impl TryInto<SharedString> for ElementId {
3331 type Error = anyhow::Error;
3332
3333 fn try_into(self) -> anyhow::Result<SharedString> {
3334 if let ElementId::Name(name) = self {
3335 Ok(name)
3336 } else {
3337 Err(anyhow!("element id is not string"))
3338 }
3339 }
3340}
3341
3342impl From<usize> for ElementId {
3343 fn from(id: usize) -> Self {
3344 ElementId::Integer(id)
3345 }
3346}
3347
3348impl From<i32> for ElementId {
3349 fn from(id: i32) -> Self {
3350 Self::Integer(id as usize)
3351 }
3352}
3353
3354impl From<SharedString> for ElementId {
3355 fn from(name: SharedString) -> Self {
3356 ElementId::Name(name)
3357 }
3358}
3359
3360impl From<&'static str> for ElementId {
3361 fn from(name: &'static str) -> Self {
3362 ElementId::Name(name.into())
3363 }
3364}
3365
3366impl<'a> From<&'a FocusHandle> for ElementId {
3367 fn from(handle: &'a FocusHandle) -> Self {
3368 ElementId::FocusHandle(handle.id)
3369 }
3370}
3371
3372impl From<(&'static str, EntityId)> for ElementId {
3373 fn from((name, id): (&'static str, EntityId)) -> Self {
3374 ElementId::NamedInteger(name.into(), id.as_u64() as usize)
3375 }
3376}
3377
3378impl From<(&'static str, usize)> for ElementId {
3379 fn from((name, id): (&'static str, usize)) -> Self {
3380 ElementId::NamedInteger(name.into(), id)
3381 }
3382}
3383
3384impl From<(&'static str, u64)> for ElementId {
3385 fn from((name, id): (&'static str, u64)) -> Self {
3386 ElementId::NamedInteger(name.into(), id as usize)
3387 }
3388}
3389
3390/// A rectangle to be rendered in the window at the given position and size.
3391/// Passed as an argument [`WindowContext::paint_quad`].
3392#[derive(Clone)]
3393pub struct PaintQuad {
3394 bounds: Bounds<Pixels>,
3395 corner_radii: Corners<Pixels>,
3396 background: Hsla,
3397 border_widths: Edges<Pixels>,
3398 border_color: Hsla,
3399}
3400
3401impl PaintQuad {
3402 /// Set the corner radii of the quad.
3403 pub fn corner_radii(self, corner_radii: impl Into<Corners<Pixels>>) -> Self {
3404 PaintQuad {
3405 corner_radii: corner_radii.into(),
3406 ..self
3407 }
3408 }
3409
3410 /// Set the border widths of the quad.
3411 pub fn border_widths(self, border_widths: impl Into<Edges<Pixels>>) -> Self {
3412 PaintQuad {
3413 border_widths: border_widths.into(),
3414 ..self
3415 }
3416 }
3417
3418 /// Set the border color of the quad.
3419 pub fn border_color(self, border_color: impl Into<Hsla>) -> Self {
3420 PaintQuad {
3421 border_color: border_color.into(),
3422 ..self
3423 }
3424 }
3425
3426 /// Set the background color of the quad.
3427 pub fn background(self, background: impl Into<Hsla>) -> Self {
3428 PaintQuad {
3429 background: background.into(),
3430 ..self
3431 }
3432 }
3433}
3434
3435/// Create a quad with the given parameters.
3436pub fn quad(
3437 bounds: Bounds<Pixels>,
3438 corner_radii: impl Into<Corners<Pixels>>,
3439 background: impl Into<Hsla>,
3440 border_widths: impl Into<Edges<Pixels>>,
3441 border_color: impl Into<Hsla>,
3442) -> PaintQuad {
3443 PaintQuad {
3444 bounds,
3445 corner_radii: corner_radii.into(),
3446 background: background.into(),
3447 border_widths: border_widths.into(),
3448 border_color: border_color.into(),
3449 }
3450}
3451
3452/// Create a filled quad with the given bounds and background color.
3453pub fn fill(bounds: impl Into<Bounds<Pixels>>, background: impl Into<Hsla>) -> PaintQuad {
3454 PaintQuad {
3455 bounds: bounds.into(),
3456 corner_radii: (0.).into(),
3457 background: background.into(),
3458 border_widths: (0.).into(),
3459 border_color: transparent_black(),
3460 }
3461}
3462
3463/// Create a rectangle outline with the given bounds, border color, and a 1px border width
3464pub fn outline(bounds: impl Into<Bounds<Pixels>>, border_color: impl Into<Hsla>) -> PaintQuad {
3465 PaintQuad {
3466 bounds: bounds.into(),
3467 corner_radii: (0.).into(),
3468 background: transparent_black(),
3469 border_widths: (1.).into(),
3470 border_color: border_color.into(),
3471 }
3472}