1pub mod action;
2mod callback_collection;
3mod menu;
4pub(crate) mod ref_counts;
5#[cfg(any(test, feature = "test-support"))]
6pub mod test_app_context;
7pub(crate) mod window;
8mod window_input_handler;
9
10use std::{
11 any::{type_name, Any, TypeId},
12 cell::RefCell,
13 fmt::{self, Debug},
14 hash::{Hash, Hasher},
15 marker::PhantomData,
16 mem,
17 ops::{Deref, DerefMut, Range},
18 path::{Path, PathBuf},
19 pin::Pin,
20 rc::{self, Rc},
21 sync::{Arc, Weak},
22 time::Duration,
23};
24
25use anyhow::{anyhow, Context, Result};
26
27use derive_more::Deref;
28use parking_lot::Mutex;
29use postage::oneshot;
30use smallvec::SmallVec;
31use smol::prelude::*;
32use util::ResultExt;
33use uuid::Uuid;
34
35pub use action::*;
36use callback_collection::CallbackCollection;
37use collections::{hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque};
38pub use menu::*;
39use platform::Event;
40#[cfg(any(test, feature = "test-support"))]
41use ref_counts::LeakDetector;
42#[cfg(any(test, feature = "test-support"))]
43pub use test_app_context::{ContextHandle, TestAppContext};
44use window_input_handler::WindowInputHandler;
45
46use crate::{
47 elements::{AnyElement, AnyRootElement, RootElement},
48 executor::{self, Task},
49 json,
50 keymap_matcher::{self, Binding, KeymapContext, KeymapMatcher, Keystroke, MatchResult},
51 platform::{
52 self, FontSystem, KeyDownEvent, KeyUpEvent, ModifiersChangedEvent, MouseButton,
53 PathPromptOptions, Platform, PromptLevel, WindowBounds, WindowOptions,
54 },
55 util::post_inc,
56 window::{Window, WindowContext},
57 AssetCache, AssetSource, ClipboardItem, FontCache, MouseRegionId,
58};
59
60use self::ref_counts::RefCounts;
61
62pub trait Entity: 'static {
63 type Event;
64
65 fn release(&mut self, _: &mut AppContext) {}
66 fn app_will_quit(
67 &mut self,
68 _: &mut AppContext,
69 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
70 None
71 }
72}
73
74pub trait View: Entity + Sized {
75 fn ui_name() -> &'static str;
76 fn render(&mut self, cx: &mut ViewContext<'_, '_, Self>) -> AnyElement<Self>;
77 fn focus_in(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
78 fn focus_out(&mut self, _: AnyViewHandle, _: &mut ViewContext<Self>) {}
79 fn key_down(&mut self, _: &KeyDownEvent, _: &mut ViewContext<Self>) -> bool {
80 false
81 }
82 fn key_up(&mut self, _: &KeyUpEvent, _: &mut ViewContext<Self>) -> bool {
83 false
84 }
85 fn modifiers_changed(&mut self, _: &ModifiersChangedEvent, _: &mut ViewContext<Self>) -> bool {
86 false
87 }
88
89 fn update_keymap_context(&self, keymap: &mut keymap_matcher::KeymapContext, _: &AppContext) {
90 Self::reset_to_default_keymap_context(keymap);
91 }
92
93 fn reset_to_default_keymap_context(keymap: &mut keymap_matcher::KeymapContext) {
94 keymap.clear();
95 keymap.add_identifier(Self::ui_name());
96 }
97
98 fn debug_json(&self, _: &AppContext) -> serde_json::Value {
99 serde_json::Value::Null
100 }
101
102 fn text_for_range(&self, _: Range<usize>, _: &AppContext) -> Option<String> {
103 None
104 }
105 fn selected_text_range(&self, _: &AppContext) -> Option<Range<usize>> {
106 None
107 }
108 fn marked_text_range(&self, _: &AppContext) -> Option<Range<usize>> {
109 None
110 }
111 fn unmark_text(&mut self, _: &mut ViewContext<Self>) {}
112 fn replace_text_in_range(
113 &mut self,
114 _: Option<Range<usize>>,
115 _: &str,
116 _: &mut ViewContext<Self>,
117 ) {
118 }
119 fn replace_and_mark_text_in_range(
120 &mut self,
121 _: Option<Range<usize>>,
122 _: &str,
123 _: Option<Range<usize>>,
124 _: &mut ViewContext<Self>,
125 ) {
126 }
127}
128
129pub trait BorrowAppContext {
130 fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T;
131 fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T;
132}
133
134pub trait BorrowWindowContext {
135 type Result<T>;
136
137 fn read_window<T, F>(&self, window: AnyWindowHandle, f: F) -> Self::Result<T>
138 where
139 F: FnOnce(&WindowContext) -> T;
140 fn read_window_optional<T, F>(&self, window: AnyWindowHandle, f: F) -> Option<T>
141 where
142 F: FnOnce(&WindowContext) -> Option<T>;
143 fn update_window<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Self::Result<T>
144 where
145 F: FnOnce(&mut WindowContext) -> T;
146 fn update_window_optional<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Option<T>
147 where
148 F: FnOnce(&mut WindowContext) -> Option<T>;
149}
150
151#[derive(Clone)]
152pub struct App(Rc<RefCell<AppContext>>);
153
154impl App {
155 pub fn new(asset_source: impl AssetSource) -> Result<Self> {
156 let platform = platform::current::platform();
157 let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
158 let foreground_platform = platform::current::foreground_platform(foreground.clone());
159 let app = Self(Rc::new(RefCell::new(AppContext::new(
160 foreground,
161 Arc::new(executor::Background::new()),
162 platform.clone(),
163 foreground_platform.clone(),
164 Arc::new(FontCache::new(platform.fonts())),
165 Default::default(),
166 asset_source,
167 ))));
168
169 foreground_platform.on_event(Box::new({
170 let cx = app.0.clone();
171 move |event| {
172 if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event {
173 // Allow system menu "cmd-?" shortcut to be overridden
174 if keystroke.cmd
175 && !keystroke.shift
176 && !keystroke.alt
177 && !keystroke.function
178 && keystroke.key == "?"
179 {
180 if cx
181 .borrow_mut()
182 .update_active_window(|cx| cx.dispatch_keystroke(keystroke))
183 .unwrap_or(false)
184 {
185 return true;
186 }
187 }
188 }
189 false
190 }
191 }));
192 foreground_platform.on_quit(Box::new({
193 let cx = app.0.clone();
194 move || {
195 cx.borrow_mut().quit();
196 }
197 }));
198 setup_menu_handlers(foreground_platform.as_ref(), &app);
199
200 app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
201 Ok(app)
202 }
203
204 pub fn background(&self) -> Arc<executor::Background> {
205 self.0.borrow().background().clone()
206 }
207
208 pub fn on_become_active<F>(self, mut callback: F) -> Self
209 where
210 F: 'static + FnMut(&mut AppContext),
211 {
212 let cx = self.0.clone();
213 self.0
214 .borrow_mut()
215 .foreground_platform
216 .on_become_active(Box::new(move || callback(&mut *cx.borrow_mut())));
217 self
218 }
219
220 pub fn on_resign_active<F>(self, mut callback: F) -> Self
221 where
222 F: 'static + FnMut(&mut AppContext),
223 {
224 let cx = self.0.clone();
225 self.0
226 .borrow_mut()
227 .foreground_platform
228 .on_resign_active(Box::new(move || callback(&mut *cx.borrow_mut())));
229 self
230 }
231
232 pub fn on_quit<F>(&mut self, mut callback: F) -> &mut Self
233 where
234 F: 'static + FnMut(&mut AppContext),
235 {
236 let cx = self.0.clone();
237 self.0
238 .borrow_mut()
239 .foreground_platform
240 .on_quit(Box::new(move || callback(&mut *cx.borrow_mut())));
241 self
242 }
243
244 /// Handle the application being re-activated when no windows are open.
245 pub fn on_reopen<F>(&mut self, mut callback: F) -> &mut Self
246 where
247 F: 'static + FnMut(&mut AppContext),
248 {
249 let cx = self.0.clone();
250 self.0
251 .borrow_mut()
252 .foreground_platform
253 .on_reopen(Box::new(move || callback(&mut *cx.borrow_mut())));
254 self
255 }
256
257 pub fn on_event<F>(&mut self, mut callback: F) -> &mut Self
258 where
259 F: 'static + FnMut(Event, &mut AppContext) -> bool,
260 {
261 let cx = self.0.clone();
262 self.0
263 .borrow_mut()
264 .foreground_platform
265 .on_event(Box::new(move |event| {
266 callback(event, &mut *cx.borrow_mut())
267 }));
268 self
269 }
270
271 pub fn on_open_urls<F>(&mut self, mut callback: F) -> &mut Self
272 where
273 F: 'static + FnMut(Vec<String>, &mut AppContext),
274 {
275 let cx = self.0.clone();
276 self.0
277 .borrow_mut()
278 .foreground_platform
279 .on_open_urls(Box::new(move |urls| callback(urls, &mut *cx.borrow_mut())));
280 self
281 }
282
283 pub fn run<F>(self, on_finish_launching: F)
284 where
285 F: 'static + FnOnce(&mut AppContext),
286 {
287 let platform = self.0.borrow().foreground_platform.clone();
288 platform.run(Box::new(move || {
289 let mut cx = self.0.borrow_mut();
290 let cx = &mut *cx;
291 crate::views::init(cx);
292 on_finish_launching(cx);
293 }))
294 }
295
296 pub fn platform(&self) -> Arc<dyn Platform> {
297 self.0.borrow().platform.clone()
298 }
299
300 pub fn font_cache(&self) -> Arc<FontCache> {
301 self.0.borrow().font_cache.clone()
302 }
303
304 fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, callback: F) -> T {
305 let mut state = self.0.borrow_mut();
306 let result = state.update(callback);
307 state.pending_notifications.clear();
308 result
309 }
310
311 fn update_window<T, F>(&mut self, window: AnyWindowHandle, callback: F) -> Option<T>
312 where
313 F: FnOnce(&mut WindowContext) -> T,
314 {
315 let mut state = self.0.borrow_mut();
316 let result = state.update_window(window, callback);
317 state.pending_notifications.clear();
318 result
319 }
320}
321
322#[derive(Clone)]
323pub struct AsyncAppContext(Rc<RefCell<AppContext>>);
324
325impl AsyncAppContext {
326 pub fn spawn<F, Fut, T>(&self, f: F) -> Task<T>
327 where
328 F: FnOnce(AsyncAppContext) -> Fut,
329 Fut: 'static + Future<Output = T>,
330 T: 'static,
331 {
332 self.0.borrow().foreground.spawn(f(self.clone()))
333 }
334
335 pub fn read<T, F: FnOnce(&AppContext) -> T>(&self, callback: F) -> T {
336 callback(&*self.0.borrow())
337 }
338
339 pub fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, callback: F) -> T {
340 self.0.borrow_mut().update(callback)
341 }
342
343 pub fn windows(&self) -> Vec<AnyWindowHandle> {
344 self.0.borrow().windows().collect()
345 }
346
347 pub fn read_window<T, F: FnOnce(&WindowContext) -> T>(
348 &self,
349 window: AnyWindowHandle,
350 callback: F,
351 ) -> Option<T> {
352 self.0.borrow_mut().read_window(window, callback)
353 }
354
355 pub fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
356 &mut self,
357 window: AnyWindowHandle,
358 callback: F,
359 ) -> Option<T> {
360 self.0.borrow_mut().update_window(window, callback)
361 }
362
363 pub fn debug_elements(&self, window: AnyWindowHandle) -> Option<json::Value> {
364 self.0.borrow().read_window(window, |cx| {
365 let root_view = cx.window.root_view();
366 let root_element = cx.window.rendered_views.get(&root_view.id())?;
367 root_element.debug(cx).log_err()
368 })?
369 }
370
371 pub fn dispatch_action(
372 &mut self,
373 window: AnyWindowHandle,
374 view_id: usize,
375 action: &dyn Action,
376 ) -> Result<()> {
377 self.0
378 .borrow_mut()
379 .update_window(window, |cx| {
380 cx.dispatch_action(Some(view_id), action);
381 })
382 .ok_or_else(|| anyhow!("window not found"))
383 }
384
385 pub fn available_actions(
386 &self,
387 window: AnyWindowHandle,
388 view_id: usize,
389 ) -> Vec<(&'static str, Box<dyn Action>, SmallVec<[Binding; 1]>)> {
390 self.read_window(window, |cx| cx.available_actions(view_id))
391 .unwrap_or_default()
392 }
393
394 pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
395 where
396 T: Entity,
397 F: FnOnce(&mut ModelContext<T>) -> T,
398 {
399 self.update(|cx| cx.add_model(build_model))
400 }
401
402 pub fn add_window<T, F>(
403 &mut self,
404 window_options: WindowOptions,
405 build_root_view: F,
406 ) -> WindowHandle<T>
407 where
408 T: View,
409 F: FnOnce(&mut ViewContext<T>) -> T,
410 {
411 self.update(|cx| cx.add_window(window_options, build_root_view))
412 }
413
414 pub fn activate_window(&mut self, window: AnyWindowHandle) {
415 self.update_window(window, |cx| cx.activate_window());
416 }
417
418 // TODO: Can we eliminate this method and move it to WindowContext then call it with update_window?s
419 pub fn prompt(
420 &mut self,
421 window: AnyWindowHandle,
422 level: PromptLevel,
423 msg: &str,
424 answers: &[&str],
425 ) -> Option<oneshot::Receiver<usize>> {
426 self.update_window(window, |cx| cx.prompt(level, msg, answers))
427 }
428
429 pub fn platform(&self) -> Arc<dyn Platform> {
430 self.0.borrow().platform().clone()
431 }
432
433 pub fn foreground(&self) -> Rc<executor::Foreground> {
434 self.0.borrow().foreground.clone()
435 }
436
437 pub fn background(&self) -> Arc<executor::Background> {
438 self.0.borrow().background.clone()
439 }
440}
441
442impl BorrowAppContext for AsyncAppContext {
443 fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
444 self.0.borrow().read_with(f)
445 }
446
447 fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T {
448 self.0.borrow_mut().update(f)
449 }
450}
451
452impl BorrowWindowContext for AsyncAppContext {
453 type Result<T> = Option<T>;
454
455 fn read_window<T, F>(&self, window: AnyWindowHandle, f: F) -> Self::Result<T>
456 where
457 F: FnOnce(&WindowContext) -> T,
458 {
459 self.0.borrow().read_with(|cx| cx.read_window(window, f))
460 }
461
462 fn read_window_optional<T, F>(&self, window: AnyWindowHandle, f: F) -> Option<T>
463 where
464 F: FnOnce(&WindowContext) -> Option<T>,
465 {
466 self.0
467 .borrow_mut()
468 .update(|cx| cx.read_window_optional(window, f))
469 }
470
471 fn update_window<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Self::Result<T>
472 where
473 F: FnOnce(&mut WindowContext) -> T,
474 {
475 self.0.borrow_mut().update(|cx| cx.update_window(window, f))
476 }
477
478 fn update_window_optional<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Option<T>
479 where
480 F: FnOnce(&mut WindowContext) -> Option<T>,
481 {
482 self.0
483 .borrow_mut()
484 .update(|cx| cx.update_window_optional(window, f))
485 }
486}
487
488type ActionCallback = dyn FnMut(&mut dyn AnyView, &dyn Action, &mut WindowContext, usize);
489type GlobalActionCallback = dyn FnMut(&dyn Action, &mut AppContext);
490
491type SubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut AppContext) -> bool>;
492type GlobalSubscriptionCallback = Box<dyn FnMut(&dyn Any, &mut AppContext)>;
493type ObservationCallback = Box<dyn FnMut(&mut AppContext) -> bool>;
494type GlobalObservationCallback = Box<dyn FnMut(&mut AppContext)>;
495type FocusObservationCallback = Box<dyn FnMut(bool, &mut WindowContext) -> bool>;
496type ReleaseObservationCallback = Box<dyn FnMut(&dyn Any, &mut AppContext)>;
497type ActionObservationCallback = Box<dyn FnMut(TypeId, &mut AppContext)>;
498type WindowActivationCallback = Box<dyn FnMut(bool, &mut WindowContext) -> bool>;
499type WindowFullscreenCallback = Box<dyn FnMut(bool, &mut WindowContext) -> bool>;
500type WindowBoundsCallback = Box<dyn FnMut(WindowBounds, Uuid, &mut WindowContext) -> bool>;
501type KeystrokeCallback =
502 Box<dyn FnMut(&Keystroke, &MatchResult, Option<&Box<dyn Action>>, &mut WindowContext) -> bool>;
503type ActiveLabeledTasksCallback = Box<dyn FnMut(&mut AppContext) -> bool>;
504type DeserializeActionCallback = fn(json: serde_json::Value) -> anyhow::Result<Box<dyn Action>>;
505type WindowShouldCloseSubscriptionCallback = Box<dyn FnMut(&mut AppContext) -> bool>;
506
507pub struct AppContext {
508 models: HashMap<usize, Box<dyn AnyModel>>,
509 views: HashMap<(usize, usize), Box<dyn AnyView>>,
510 views_metadata: HashMap<(usize, usize), ViewMetadata>,
511 windows: HashMap<usize, Window>,
512 globals: HashMap<TypeId, Box<dyn Any>>,
513 element_states: HashMap<ElementStateId, Box<dyn Any>>,
514 background: Arc<executor::Background>,
515 ref_counts: Arc<Mutex<RefCounts>>,
516
517 weak_self: Option<rc::Weak<RefCell<Self>>>,
518 platform: Arc<dyn Platform>,
519 foreground_platform: Rc<dyn platform::ForegroundPlatform>,
520 pub asset_cache: Arc<AssetCache>,
521 font_system: Arc<dyn FontSystem>,
522 pub font_cache: Arc<FontCache>,
523 action_deserializers: HashMap<&'static str, (TypeId, DeserializeActionCallback)>,
524 capture_actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
525 // Entity Types -> { Action Types -> Action Handlers }
526 actions: HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>>,
527 // Action Types -> Action Handlers
528 global_actions: HashMap<TypeId, Box<GlobalActionCallback>>,
529 keystroke_matcher: KeymapMatcher,
530 next_id: usize,
531 // next_window: AnyWindowHandle,
532 next_subscription_id: usize,
533 frame_count: usize,
534
535 subscriptions: CallbackCollection<usize, SubscriptionCallback>,
536 global_subscriptions: CallbackCollection<TypeId, GlobalSubscriptionCallback>,
537 observations: CallbackCollection<usize, ObservationCallback>,
538 global_observations: CallbackCollection<TypeId, GlobalObservationCallback>,
539 focus_observations: CallbackCollection<usize, FocusObservationCallback>,
540 release_observations: CallbackCollection<usize, ReleaseObservationCallback>,
541 action_dispatch_observations: CallbackCollection<(), ActionObservationCallback>,
542 window_activation_observations: CallbackCollection<usize, WindowActivationCallback>,
543 window_fullscreen_observations: CallbackCollection<usize, WindowFullscreenCallback>,
544 window_bounds_observations: CallbackCollection<usize, WindowBoundsCallback>,
545 keystroke_observations: CallbackCollection<usize, KeystrokeCallback>,
546 active_labeled_task_observations: CallbackCollection<(), ActiveLabeledTasksCallback>,
547
548 foreground: Rc<executor::Foreground>,
549 pending_effects: VecDeque<Effect>,
550 pending_notifications: HashSet<usize>,
551 pending_global_notifications: HashSet<TypeId>,
552 pending_flushes: usize,
553 flushing_effects: bool,
554 halt_action_dispatch: bool,
555 next_labeled_task_id: usize,
556 active_labeled_tasks: BTreeMap<usize, &'static str>,
557}
558
559impl AppContext {
560 fn new(
561 foreground: Rc<executor::Foreground>,
562 background: Arc<executor::Background>,
563 platform: Arc<dyn platform::Platform>,
564 foreground_platform: Rc<dyn platform::ForegroundPlatform>,
565 font_cache: Arc<FontCache>,
566 ref_counts: RefCounts,
567 asset_source: impl AssetSource,
568 ) -> Self {
569 Self {
570 models: Default::default(),
571 views: Default::default(),
572 views_metadata: Default::default(),
573 windows: Default::default(),
574 globals: Default::default(),
575 element_states: Default::default(),
576 ref_counts: Arc::new(Mutex::new(ref_counts)),
577 background,
578
579 weak_self: None,
580 font_system: platform.fonts(),
581 platform,
582 foreground_platform,
583 font_cache,
584 asset_cache: Arc::new(AssetCache::new(asset_source)),
585 action_deserializers: Default::default(),
586 capture_actions: Default::default(),
587 actions: Default::default(),
588 global_actions: Default::default(),
589 keystroke_matcher: KeymapMatcher::default(),
590 next_id: 0,
591 next_subscription_id: 0,
592 frame_count: 0,
593 subscriptions: Default::default(),
594 global_subscriptions: Default::default(),
595 observations: Default::default(),
596 focus_observations: Default::default(),
597 release_observations: Default::default(),
598 global_observations: Default::default(),
599 window_activation_observations: Default::default(),
600 window_fullscreen_observations: Default::default(),
601 window_bounds_observations: Default::default(),
602 keystroke_observations: Default::default(),
603 action_dispatch_observations: Default::default(),
604 active_labeled_task_observations: Default::default(),
605 foreground,
606 pending_effects: VecDeque::new(),
607 pending_notifications: Default::default(),
608 pending_global_notifications: Default::default(),
609 pending_flushes: 0,
610 flushing_effects: false,
611 halt_action_dispatch: false,
612 next_labeled_task_id: 0,
613 active_labeled_tasks: Default::default(),
614 }
615 }
616
617 pub fn background(&self) -> &Arc<executor::Background> {
618 &self.background
619 }
620
621 pub fn font_cache(&self) -> &Arc<FontCache> {
622 &self.font_cache
623 }
624
625 pub fn platform(&self) -> &Arc<dyn Platform> {
626 &self.platform
627 }
628
629 pub fn has_global<T: 'static>(&self) -> bool {
630 self.globals.contains_key(&TypeId::of::<T>())
631 }
632
633 pub fn global<T: 'static>(&self) -> &T {
634 if let Some(global) = self.globals.get(&TypeId::of::<T>()) {
635 global.downcast_ref().unwrap()
636 } else {
637 panic!("no global has been added for {}", type_name::<T>());
638 }
639 }
640
641 pub fn upgrade(&self) -> App {
642 App(self.weak_self.as_ref().unwrap().upgrade().unwrap())
643 }
644
645 fn quit(&mut self) {
646 let mut futures = Vec::new();
647
648 self.update(|cx| {
649 for model_id in cx.models.keys().copied().collect::<Vec<_>>() {
650 let mut model = cx.models.remove(&model_id).unwrap();
651 futures.extend(model.app_will_quit(cx));
652 cx.models.insert(model_id, model);
653 }
654
655 for view_id in cx.views.keys().copied().collect::<Vec<_>>() {
656 let mut view = cx.views.remove(&view_id).unwrap();
657 futures.extend(view.app_will_quit(cx));
658 cx.views.insert(view_id, view);
659 }
660 });
661
662 self.windows.clear();
663 self.flush_effects();
664
665 let futures = futures::future::join_all(futures);
666 if self
667 .background
668 .block_with_timeout(Duration::from_millis(100), futures)
669 .is_err()
670 {
671 log::error!("timed out waiting on app_will_quit");
672 }
673 }
674
675 pub fn foreground(&self) -> &Rc<executor::Foreground> {
676 &self.foreground
677 }
678
679 pub fn deserialize_action(
680 &self,
681 name: &str,
682 argument: Option<serde_json::Value>,
683 ) -> Result<Box<dyn Action>> {
684 let callback = self
685 .action_deserializers
686 .get(name)
687 .ok_or_else(|| anyhow!("unknown action {}", name))?
688 .1;
689 callback(argument.unwrap_or_else(|| serde_json::Value::Object(Default::default())))
690 .with_context(|| format!("invalid data for action {}", name))
691 }
692
693 pub fn add_action<A, V, F, R>(&mut self, handler: F)
694 where
695 A: Action,
696 V: View,
697 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> R,
698 {
699 self.add_action_internal(handler, false)
700 }
701
702 pub fn capture_action<A, V, F>(&mut self, handler: F)
703 where
704 A: Action,
705 V: View,
706 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>),
707 {
708 self.add_action_internal(handler, true)
709 }
710
711 fn add_action_internal<A, V, F, R>(&mut self, mut handler: F, capture: bool)
712 where
713 A: Action,
714 V: View,
715 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> R,
716 {
717 let handler = Box::new(
718 move |view: &mut dyn AnyView,
719 action: &dyn Action,
720 cx: &mut WindowContext,
721 view_id: usize| {
722 let action = action.as_any().downcast_ref().unwrap();
723 let mut cx = ViewContext::mutable(cx, view_id);
724 handler(
725 view.as_any_mut()
726 .downcast_mut()
727 .expect("downcast is type safe"),
728 action,
729 &mut cx,
730 );
731 },
732 );
733
734 self.action_deserializers
735 .entry(A::qualified_name())
736 .or_insert((TypeId::of::<A>(), A::from_json_str));
737
738 let actions = if capture {
739 &mut self.capture_actions
740 } else {
741 &mut self.actions
742 };
743
744 actions
745 .entry(TypeId::of::<V>())
746 .or_default()
747 .entry(TypeId::of::<A>())
748 .or_default()
749 .push(handler);
750 }
751
752 pub fn add_async_action<A, V, F>(&mut self, mut handler: F)
753 where
754 A: Action,
755 V: View,
756 F: 'static + FnMut(&mut V, &A, &mut ViewContext<V>) -> Option<Task<Result<()>>>,
757 {
758 self.add_action(move |view, action, cx| {
759 if let Some(task) = handler(view, action, cx) {
760 task.detach_and_log_err(cx);
761 }
762 })
763 }
764
765 pub fn add_global_action<A, F>(&mut self, mut handler: F)
766 where
767 A: Action,
768 F: 'static + FnMut(&A, &mut AppContext),
769 {
770 let handler = Box::new(move |action: &dyn Action, cx: &mut AppContext| {
771 let action = action.as_any().downcast_ref().unwrap();
772 handler(action, cx);
773 });
774
775 self.action_deserializers
776 .entry(A::qualified_name())
777 .or_insert((TypeId::of::<A>(), A::from_json_str));
778
779 if self
780 .global_actions
781 .insert(TypeId::of::<A>(), handler)
782 .is_some()
783 {
784 panic!(
785 "registered multiple global handlers for {}",
786 type_name::<A>()
787 );
788 }
789 }
790
791 pub fn view_ui_name(&self, window: AnyWindowHandle, view_id: usize) -> Option<&'static str> {
792 Some(self.views.get(&(window.id(), view_id))?.ui_name())
793 }
794
795 pub fn view_type_id(&self, window: AnyWindowHandle, view_id: usize) -> Option<TypeId> {
796 self.views_metadata
797 .get(&(window.id(), view_id))
798 .map(|metadata| metadata.type_id)
799 }
800
801 pub fn active_labeled_tasks<'a>(
802 &'a self,
803 ) -> impl DoubleEndedIterator<Item = &'static str> + 'a {
804 self.active_labeled_tasks.values().cloned()
805 }
806
807 pub(crate) fn start_frame(&mut self) {
808 self.frame_count += 1;
809 }
810
811 pub fn update<T, F: FnOnce(&mut Self) -> T>(&mut self, callback: F) -> T {
812 self.pending_flushes += 1;
813 let result = callback(self);
814 self.flush_effects();
815 result
816 }
817
818 fn read_window<T, F: FnOnce(&WindowContext) -> T>(
819 &self,
820 handle: AnyWindowHandle,
821 callback: F,
822 ) -> Option<T> {
823 let window = self.windows.get(&handle.id())?;
824 let window_context = WindowContext::immutable(self, &window, handle);
825 Some(callback(&window_context))
826 }
827
828 pub fn update_active_window<T, F: FnOnce(&mut WindowContext) -> T>(
829 &mut self,
830 callback: F,
831 ) -> Option<T> {
832 self.active_window()
833 .and_then(|window| window.update(self, callback))
834 }
835
836 pub fn prompt_for_paths(
837 &self,
838 options: PathPromptOptions,
839 ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
840 self.foreground_platform.prompt_for_paths(options)
841 }
842
843 pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
844 self.foreground_platform.prompt_for_new_path(directory)
845 }
846
847 pub fn reveal_path(&self, path: &Path) {
848 self.foreground_platform.reveal_path(path)
849 }
850
851 pub fn emit_global<E: Any>(&mut self, payload: E) {
852 self.pending_effects.push_back(Effect::GlobalEvent {
853 payload: Box::new(payload),
854 });
855 }
856
857 pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
858 where
859 E: Entity,
860 E::Event: 'static,
861 H: Handle<E>,
862 F: 'static + FnMut(H, &E::Event, &mut Self),
863 {
864 self.subscribe_internal(handle, move |handle, event, cx| {
865 callback(handle, event, cx);
866 true
867 })
868 }
869
870 pub fn subscribe_global<E, F>(&mut self, mut callback: F) -> Subscription
871 where
872 E: Any,
873 F: 'static + FnMut(&E, &mut Self),
874 {
875 let subscription_id = post_inc(&mut self.next_subscription_id);
876 let type_id = TypeId::of::<E>();
877 self.pending_effects.push_back(Effect::GlobalSubscription {
878 type_id,
879 subscription_id,
880 callback: Box::new(move |payload, cx| {
881 let payload = payload.downcast_ref().expect("downcast is type safe");
882 callback(payload, cx)
883 }),
884 });
885 Subscription::GlobalSubscription(
886 self.global_subscriptions
887 .subscribe(type_id, subscription_id),
888 )
889 }
890
891 pub fn observe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
892 where
893 E: Entity,
894 E::Event: 'static,
895 H: Handle<E>,
896 F: 'static + FnMut(H, &mut Self),
897 {
898 self.observe_internal(handle, move |handle, cx| {
899 callback(handle, cx);
900 true
901 })
902 }
903
904 fn subscribe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
905 where
906 E: Entity,
907 E::Event: 'static,
908 H: Handle<E>,
909 F: 'static + FnMut(H, &E::Event, &mut Self) -> bool,
910 {
911 let subscription_id = post_inc(&mut self.next_subscription_id);
912 let emitter = handle.downgrade();
913 self.pending_effects.push_back(Effect::Subscription {
914 entity_id: handle.id(),
915 subscription_id,
916 callback: Box::new(move |payload, cx| {
917 if let Some(emitter) = H::upgrade_from(&emitter, cx) {
918 let payload = payload.downcast_ref().expect("downcast is type safe");
919 callback(emitter, payload, cx)
920 } else {
921 false
922 }
923 }),
924 });
925 Subscription::Subscription(self.subscriptions.subscribe(handle.id(), subscription_id))
926 }
927
928 fn observe_internal<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
929 where
930 E: Entity,
931 E::Event: 'static,
932 H: Handle<E>,
933 F: 'static + FnMut(H, &mut Self) -> bool,
934 {
935 let subscription_id = post_inc(&mut self.next_subscription_id);
936 let observed = handle.downgrade();
937 let entity_id = handle.id();
938 self.pending_effects.push_back(Effect::Observation {
939 entity_id,
940 subscription_id,
941 callback: Box::new(move |cx| {
942 if let Some(observed) = H::upgrade_from(&observed, cx) {
943 callback(observed, cx)
944 } else {
945 false
946 }
947 }),
948 });
949 Subscription::Observation(self.observations.subscribe(entity_id, subscription_id))
950 }
951
952 fn observe_focus<F, V>(&mut self, handle: &ViewHandle<V>, mut callback: F) -> Subscription
953 where
954 F: 'static + FnMut(ViewHandle<V>, bool, &mut WindowContext) -> bool,
955 V: View,
956 {
957 let subscription_id = post_inc(&mut self.next_subscription_id);
958 let observed = handle.downgrade();
959 let view_id = handle.id();
960
961 self.pending_effects.push_back(Effect::FocusObservation {
962 view_id,
963 subscription_id,
964 callback: Box::new(move |focused, cx| {
965 if let Some(observed) = observed.upgrade(cx) {
966 callback(observed, focused, cx)
967 } else {
968 false
969 }
970 }),
971 });
972 Subscription::FocusObservation(self.focus_observations.subscribe(view_id, subscription_id))
973 }
974
975 pub fn observe_global<G, F>(&mut self, mut observe: F) -> Subscription
976 where
977 G: Any,
978 F: 'static + FnMut(&mut AppContext),
979 {
980 let type_id = TypeId::of::<G>();
981 let id = post_inc(&mut self.next_subscription_id);
982
983 self.global_observations.add_callback(
984 type_id,
985 id,
986 Box::new(move |cx: &mut AppContext| observe(cx)),
987 );
988 Subscription::GlobalObservation(self.global_observations.subscribe(type_id, id))
989 }
990
991 pub fn observe_default_global<G, F>(&mut self, observe: F) -> Subscription
992 where
993 G: Any + Default,
994 F: 'static + FnMut(&mut AppContext),
995 {
996 if !self.has_global::<G>() {
997 self.set_global(G::default());
998 }
999 self.observe_global::<G, F>(observe)
1000 }
1001
1002 pub fn observe_release<E, H, F>(&mut self, handle: &H, callback: F) -> Subscription
1003 where
1004 E: Entity,
1005 E::Event: 'static,
1006 H: Handle<E>,
1007 F: 'static + FnOnce(&E, &mut Self),
1008 {
1009 let id = post_inc(&mut self.next_subscription_id);
1010 let mut callback = Some(callback);
1011 self.release_observations.add_callback(
1012 handle.id(),
1013 id,
1014 Box::new(move |released, cx| {
1015 let released = released.downcast_ref().unwrap();
1016 if let Some(callback) = callback.take() {
1017 callback(released, cx)
1018 }
1019 }),
1020 );
1021 Subscription::ReleaseObservation(self.release_observations.subscribe(handle.id(), id))
1022 }
1023
1024 pub fn observe_actions<F>(&mut self, callback: F) -> Subscription
1025 where
1026 F: 'static + FnMut(TypeId, &mut AppContext),
1027 {
1028 let subscription_id = post_inc(&mut self.next_subscription_id);
1029 self.action_dispatch_observations
1030 .add_callback((), subscription_id, Box::new(callback));
1031 Subscription::ActionObservation(
1032 self.action_dispatch_observations
1033 .subscribe((), subscription_id),
1034 )
1035 }
1036
1037 fn observe_active_labeled_tasks<F>(&mut self, callback: F) -> Subscription
1038 where
1039 F: 'static + FnMut(&mut AppContext) -> bool,
1040 {
1041 let subscription_id = post_inc(&mut self.next_subscription_id);
1042 self.active_labeled_task_observations
1043 .add_callback((), subscription_id, Box::new(callback));
1044 Subscription::ActiveLabeledTasksObservation(
1045 self.active_labeled_task_observations
1046 .subscribe((), subscription_id),
1047 )
1048 }
1049
1050 pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut AppContext)) {
1051 self.pending_effects.push_back(Effect::Deferred {
1052 callback: Box::new(callback),
1053 after_window_update: false,
1054 })
1055 }
1056
1057 pub fn after_window_update(&mut self, callback: impl 'static + FnOnce(&mut AppContext)) {
1058 self.pending_effects.push_back(Effect::Deferred {
1059 callback: Box::new(callback),
1060 after_window_update: true,
1061 })
1062 }
1063
1064 fn notify_model(&mut self, model_id: usize) {
1065 if self.pending_notifications.insert(model_id) {
1066 self.pending_effects
1067 .push_back(Effect::ModelNotification { model_id });
1068 }
1069 }
1070
1071 fn notify_view(&mut self, window: AnyWindowHandle, view_id: usize) {
1072 if self.pending_notifications.insert(view_id) {
1073 self.pending_effects
1074 .push_back(Effect::ViewNotification { window, view_id });
1075 }
1076 }
1077
1078 fn notify_global(&mut self, type_id: TypeId) {
1079 if self.pending_global_notifications.insert(type_id) {
1080 self.pending_effects
1081 .push_back(Effect::GlobalNotification { type_id });
1082 }
1083 }
1084
1085 pub fn all_action_names<'a>(&'a self) -> impl Iterator<Item = &'static str> + 'a {
1086 self.action_deserializers.keys().copied()
1087 }
1088
1089 pub fn is_action_available(&self, action: &dyn Action) -> bool {
1090 let mut available_in_window = false;
1091 let action_id = action.id();
1092 if let Some(window) = self.active_window() {
1093 available_in_window = self
1094 .read_window(window, |cx| {
1095 if let Some(focused_view_id) = cx.focused_view_id() {
1096 for view_id in cx.ancestors(focused_view_id) {
1097 if let Some(view_metadata) =
1098 cx.views_metadata.get(&(cx.window_handle.id(), view_id))
1099 {
1100 if let Some(actions) = cx.actions.get(&view_metadata.type_id) {
1101 if actions.contains_key(&action_id) {
1102 return true;
1103 }
1104 }
1105 }
1106 }
1107 }
1108 false
1109 })
1110 .unwrap_or(false);
1111 }
1112 available_in_window || self.global_actions.contains_key(&action_id)
1113 }
1114
1115 fn actions_mut(
1116 &mut self,
1117 capture_phase: bool,
1118 ) -> &mut HashMap<TypeId, HashMap<TypeId, Vec<Box<ActionCallback>>>> {
1119 if capture_phase {
1120 &mut self.capture_actions
1121 } else {
1122 &mut self.actions
1123 }
1124 }
1125
1126 fn dispatch_global_action_any(&mut self, action: &dyn Action) -> bool {
1127 self.update(|this| {
1128 if let Some((name, mut handler)) = this.global_actions.remove_entry(&action.id()) {
1129 handler(action, this);
1130 this.global_actions.insert(name, handler);
1131 true
1132 } else {
1133 false
1134 }
1135 })
1136 }
1137
1138 pub fn add_bindings<T: IntoIterator<Item = Binding>>(&mut self, bindings: T) {
1139 self.keystroke_matcher.add_bindings(bindings);
1140 }
1141
1142 pub fn clear_bindings(&mut self) {
1143 self.keystroke_matcher.clear_bindings();
1144 }
1145
1146 pub fn binding_for_action(&self, action: &dyn Action) -> Option<&Binding> {
1147 self.keystroke_matcher
1148 .bindings_for_action(action.id())
1149 .find(|binding| binding.action().eq(action))
1150 }
1151
1152 pub fn default_global<T: 'static + Default>(&mut self) -> &T {
1153 let type_id = TypeId::of::<T>();
1154 self.update(|this| {
1155 if let Entry::Vacant(entry) = this.globals.entry(type_id) {
1156 entry.insert(Box::new(T::default()));
1157 this.notify_global(type_id);
1158 }
1159 });
1160 self.globals.get(&type_id).unwrap().downcast_ref().unwrap()
1161 }
1162
1163 pub fn set_global<T: 'static>(&mut self, state: T) {
1164 self.update(|this| {
1165 let type_id = TypeId::of::<T>();
1166 this.globals.insert(type_id, Box::new(state));
1167 this.notify_global(type_id);
1168 });
1169 }
1170
1171 pub fn update_default_global<T, F, U>(&mut self, update: F) -> U
1172 where
1173 T: 'static + Default,
1174 F: FnOnce(&mut T, &mut AppContext) -> U,
1175 {
1176 self.update(|mut this| {
1177 Self::update_default_global_internal(&mut this, |global, cx| update(global, cx))
1178 })
1179 }
1180
1181 fn update_default_global_internal<C, T, F, U>(this: &mut C, update: F) -> U
1182 where
1183 C: DerefMut<Target = AppContext>,
1184 T: 'static + Default,
1185 F: FnOnce(&mut T, &mut C) -> U,
1186 {
1187 let type_id = TypeId::of::<T>();
1188 let mut state = this
1189 .globals
1190 .remove(&type_id)
1191 .unwrap_or_else(|| Box::new(T::default()));
1192 let result = update(state.downcast_mut().unwrap(), this);
1193 this.globals.insert(type_id, state);
1194 this.notify_global(type_id);
1195 result
1196 }
1197
1198 pub fn update_global<T, F, U>(&mut self, update: F) -> U
1199 where
1200 T: 'static,
1201 F: FnOnce(&mut T, &mut AppContext) -> U,
1202 {
1203 self.update(|mut this| {
1204 Self::update_global_internal(&mut this, |global, cx| update(global, cx))
1205 })
1206 }
1207
1208 fn update_global_internal<C, T, F, U>(this: &mut C, update: F) -> U
1209 where
1210 C: DerefMut<Target = AppContext>,
1211 T: 'static,
1212 F: FnOnce(&mut T, &mut C) -> U,
1213 {
1214 let type_id = TypeId::of::<T>();
1215 if let Some(mut state) = this.globals.remove(&type_id) {
1216 let result = update(state.downcast_mut().unwrap(), this);
1217 this.globals.insert(type_id, state);
1218 this.notify_global(type_id);
1219 result
1220 } else {
1221 panic!("no global added for {}", std::any::type_name::<T>());
1222 }
1223 }
1224
1225 pub fn clear_globals(&mut self) {
1226 self.globals.clear();
1227 }
1228
1229 pub fn remove_global<T: 'static>(&mut self) -> T {
1230 *self
1231 .globals
1232 .remove(&TypeId::of::<T>())
1233 .unwrap_or_else(|| panic!("no global added for {}", std::any::type_name::<T>()))
1234 .downcast()
1235 .unwrap()
1236 }
1237
1238 pub fn add_model<T, F>(&mut self, build_model: F) -> ModelHandle<T>
1239 where
1240 T: Entity,
1241 F: FnOnce(&mut ModelContext<T>) -> T,
1242 {
1243 self.update(|this| {
1244 let model_id = post_inc(&mut this.next_id);
1245 let handle = ModelHandle::new(model_id, &this.ref_counts);
1246 let mut cx = ModelContext::new(this, model_id);
1247 let model = build_model(&mut cx);
1248 this.models.insert(model_id, Box::new(model));
1249 handle
1250 })
1251 }
1252
1253 pub fn read_model<T: Entity>(&self, handle: &ModelHandle<T>) -> &T {
1254 if let Some(model) = self.models.get(&handle.model_id) {
1255 model
1256 .as_any()
1257 .downcast_ref()
1258 .expect("downcast is type safe")
1259 } else {
1260 panic!("circular model reference");
1261 }
1262 }
1263
1264 fn update_model<T: Entity, V>(
1265 &mut self,
1266 handle: &ModelHandle<T>,
1267 update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> V,
1268 ) -> V {
1269 if let Some(mut model) = self.models.remove(&handle.model_id) {
1270 self.update(|this| {
1271 let mut cx = ModelContext::new(this, handle.model_id);
1272 let result = update(
1273 model
1274 .as_any_mut()
1275 .downcast_mut()
1276 .expect("downcast is type safe"),
1277 &mut cx,
1278 );
1279 this.models.insert(handle.model_id, model);
1280 result
1281 })
1282 } else {
1283 panic!("circular model update");
1284 }
1285 }
1286
1287 fn upgrade_model_handle<T: Entity>(
1288 &self,
1289 handle: &WeakModelHandle<T>,
1290 ) -> Option<ModelHandle<T>> {
1291 if self.ref_counts.lock().is_entity_alive(handle.model_id) {
1292 Some(ModelHandle::new(handle.model_id, &self.ref_counts))
1293 } else {
1294 None
1295 }
1296 }
1297
1298 fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
1299 self.ref_counts.lock().is_entity_alive(handle.model_id)
1300 }
1301
1302 fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
1303 if self.ref_counts.lock().is_entity_alive(handle.model_id) {
1304 Some(AnyModelHandle::new(
1305 handle.model_id,
1306 handle.model_type,
1307 self.ref_counts.clone(),
1308 ))
1309 } else {
1310 None
1311 }
1312 }
1313
1314 pub fn add_window<V, F>(
1315 &mut self,
1316 window_options: WindowOptions,
1317 build_root_view: F,
1318 ) -> WindowHandle<V>
1319 where
1320 V: View,
1321 F: FnOnce(&mut ViewContext<V>) -> V,
1322 {
1323 self.update(|this| {
1324 let window_id = post_inc(&mut this.next_id);
1325 let platform_window =
1326 this.platform
1327 .open_window(window_id, window_options, this.foreground.clone());
1328 let handle = WindowHandle::<V>::new(window_id);
1329 let window = this.build_window(handle, platform_window, build_root_view);
1330 this.windows.insert(window_id, window);
1331 handle
1332 })
1333 }
1334
1335 pub fn add_status_bar_item<V, F>(&mut self, build_root_view: F) -> WindowHandle<V>
1336 where
1337 V: View,
1338 F: FnOnce(&mut ViewContext<V>) -> V,
1339 {
1340 self.update(|this| {
1341 let window_id = post_inc(&mut this.next_id);
1342 let platform_window = this.platform.add_status_item(window_id);
1343 let handle = WindowHandle::<V>::new(window_id);
1344 let window = this.build_window(handle, platform_window, build_root_view);
1345 this.windows.insert(window_id, window);
1346 handle.update_root(this, |view, cx| view.focus_in(cx.handle().into_any(), cx));
1347 handle
1348 })
1349 }
1350
1351 pub fn build_window<H, V, F>(
1352 &mut self,
1353 handle: H,
1354 mut platform_window: Box<dyn platform::Window>,
1355 build_root_view: F,
1356 ) -> Window
1357 where
1358 H: Into<AnyWindowHandle>,
1359 V: View,
1360 F: FnOnce(&mut ViewContext<V>) -> V,
1361 {
1362 let handle: AnyWindowHandle = handle.into();
1363
1364 {
1365 let mut app = self.upgrade();
1366
1367 platform_window.on_event(Box::new(move |event| {
1368 app.update_window(handle, |cx| {
1369 if let Event::KeyDown(KeyDownEvent { keystroke, .. }) = &event {
1370 if cx.dispatch_keystroke(keystroke) {
1371 return true;
1372 }
1373 }
1374
1375 cx.dispatch_event(event, false)
1376 })
1377 .unwrap_or(false)
1378 }));
1379 }
1380
1381 {
1382 let mut app = self.upgrade();
1383 platform_window.on_active_status_change(Box::new(move |is_active| {
1384 app.update(|cx| cx.window_changed_active_status(handle, is_active))
1385 }));
1386 }
1387
1388 {
1389 let mut app = self.upgrade();
1390 platform_window.on_resize(Box::new(move || {
1391 app.update(|cx| cx.window_was_resized(handle))
1392 }));
1393 }
1394
1395 {
1396 let mut app = self.upgrade();
1397 platform_window.on_moved(Box::new(move || {
1398 app.update(|cx| cx.window_was_moved(handle))
1399 }));
1400 }
1401
1402 {
1403 let mut app = self.upgrade();
1404 platform_window.on_fullscreen(Box::new(move |is_fullscreen| {
1405 app.update(|cx| cx.window_was_fullscreen_changed(handle, is_fullscreen))
1406 }));
1407 }
1408
1409 {
1410 let mut app = self.upgrade();
1411 platform_window.on_close(Box::new(move || {
1412 app.update(|cx| cx.update_window(handle, |cx| cx.remove_window()));
1413 }));
1414 }
1415
1416 {
1417 let mut app = self.upgrade();
1418 platform_window
1419 .on_appearance_changed(Box::new(move || app.update(|cx| cx.refresh_windows())));
1420 }
1421
1422 platform_window.set_input_handler(Box::new(WindowInputHandler {
1423 app: self.upgrade().0,
1424 window: handle,
1425 }));
1426
1427 let mut window = Window::new(handle, platform_window, self, build_root_view);
1428 let mut cx = WindowContext::mutable(self, &mut window, handle);
1429 cx.layout(false).expect("initial layout should not error");
1430 let scene = cx.paint().expect("initial paint should not error");
1431 window.platform_window.present_scene(scene);
1432 window
1433 }
1434
1435 pub fn active_window(&self) -> Option<AnyWindowHandle> {
1436 self.platform.main_window_id().and_then(|main_window_id| {
1437 self.windows
1438 .get(&main_window_id)
1439 .map(|window| AnyWindowHandle::new(main_window_id, window.root_view().type_id()))
1440 })
1441 }
1442
1443 pub fn windows(&self) -> impl '_ + Iterator<Item = AnyWindowHandle> {
1444 self.windows.iter().map(|(window_id, window)| {
1445 AnyWindowHandle::new(*window_id, window.root_view().type_id())
1446 })
1447 }
1448
1449 pub fn read_view<T: View>(&self, handle: &ViewHandle<T>) -> &T {
1450 if let Some(view) = self.views.get(&(handle.window.id(), handle.view_id)) {
1451 view.as_any().downcast_ref().expect("downcast is type safe")
1452 } else {
1453 panic!("circular view reference for type {}", type_name::<T>());
1454 }
1455 }
1456
1457 fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
1458 if self.ref_counts.lock().is_entity_alive(handle.view_id) {
1459 Some(ViewHandle::new(
1460 handle.window,
1461 handle.view_id,
1462 &self.ref_counts,
1463 ))
1464 } else {
1465 None
1466 }
1467 }
1468
1469 fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
1470 if self.ref_counts.lock().is_entity_alive(handle.view_id) {
1471 Some(AnyViewHandle::new(
1472 handle.window,
1473 handle.view_id,
1474 handle.view_type,
1475 self.ref_counts.clone(),
1476 ))
1477 } else {
1478 None
1479 }
1480 }
1481
1482 fn remove_dropped_entities(&mut self) {
1483 loop {
1484 let (dropped_models, dropped_views, dropped_element_states) =
1485 self.ref_counts.lock().take_dropped();
1486 if dropped_models.is_empty()
1487 && dropped_views.is_empty()
1488 && dropped_element_states.is_empty()
1489 {
1490 break;
1491 }
1492
1493 for model_id in dropped_models {
1494 self.subscriptions.remove(model_id);
1495 self.observations.remove(model_id);
1496 let mut model = self.models.remove(&model_id).unwrap();
1497 model.release(self);
1498 self.pending_effects
1499 .push_back(Effect::ModelRelease { model_id, model });
1500 }
1501
1502 for (window_id, view_id) in dropped_views {
1503 self.subscriptions.remove(view_id);
1504 self.observations.remove(view_id);
1505 self.views_metadata.remove(&(window_id, view_id));
1506 let mut view = self.views.remove(&(window_id, view_id)).unwrap();
1507 view.release(self);
1508 if let Some(window) = self.windows.get_mut(&window_id) {
1509 window.parents.remove(&view_id);
1510 window
1511 .invalidation
1512 .get_or_insert_with(Default::default)
1513 .removed
1514 .push(view_id);
1515 }
1516
1517 self.pending_effects
1518 .push_back(Effect::ViewRelease { view_id, view });
1519 }
1520
1521 for key in dropped_element_states {
1522 self.element_states.remove(&key);
1523 }
1524 }
1525 }
1526
1527 fn flush_effects(&mut self) {
1528 self.pending_flushes = self.pending_flushes.saturating_sub(1);
1529 let mut after_window_update_callbacks = Vec::new();
1530
1531 if !self.flushing_effects && self.pending_flushes == 0 {
1532 self.flushing_effects = true;
1533
1534 let mut refreshing = false;
1535 let mut updated_windows = HashSet::default();
1536 let mut focus_effects = HashMap::<usize, FocusEffect>::default();
1537 loop {
1538 self.remove_dropped_entities();
1539 if let Some(effect) = self.pending_effects.pop_front() {
1540 match effect {
1541 Effect::Subscription {
1542 entity_id,
1543 subscription_id,
1544 callback,
1545 } => self
1546 .subscriptions
1547 .add_callback(entity_id, subscription_id, callback),
1548
1549 Effect::Event { entity_id, payload } => {
1550 let mut subscriptions = self.subscriptions.clone();
1551 subscriptions
1552 .emit(entity_id, |callback| callback(payload.as_ref(), self))
1553 }
1554
1555 Effect::GlobalSubscription {
1556 type_id,
1557 subscription_id,
1558 callback,
1559 } => self.global_subscriptions.add_callback(
1560 type_id,
1561 subscription_id,
1562 callback,
1563 ),
1564
1565 Effect::GlobalEvent { payload } => self.emit_global_event(payload),
1566
1567 Effect::Observation {
1568 entity_id,
1569 subscription_id,
1570 callback,
1571 } => self
1572 .observations
1573 .add_callback(entity_id, subscription_id, callback),
1574
1575 Effect::ModelNotification { model_id } => {
1576 let mut observations = self.observations.clone();
1577 observations.emit(model_id, |callback| callback(self));
1578 }
1579
1580 Effect::ViewNotification {
1581 window: window_id,
1582 view_id,
1583 } => self.handle_view_notification_effect(window_id, view_id),
1584
1585 Effect::GlobalNotification { type_id } => {
1586 let mut subscriptions = self.global_observations.clone();
1587 subscriptions.emit(type_id, |callback| {
1588 callback(self);
1589 true
1590 });
1591 }
1592
1593 Effect::Deferred {
1594 callback,
1595 after_window_update,
1596 } => {
1597 if after_window_update {
1598 after_window_update_callbacks.push(callback);
1599 } else {
1600 callback(self)
1601 }
1602 }
1603
1604 Effect::ModelRelease { model_id, model } => {
1605 self.handle_entity_release_effect(model_id, model.as_any())
1606 }
1607
1608 Effect::ViewRelease { view_id, view } => {
1609 self.handle_entity_release_effect(view_id, view.as_any())
1610 }
1611
1612 Effect::Focus(mut effect) => {
1613 if focus_effects
1614 .get(&effect.window().id())
1615 .map_or(false, |prev_effect| prev_effect.is_forced())
1616 {
1617 effect.force();
1618 }
1619
1620 focus_effects.insert(effect.window().id(), effect);
1621 }
1622
1623 Effect::FocusObservation {
1624 view_id,
1625 subscription_id,
1626 callback,
1627 } => {
1628 self.focus_observations.add_callback(
1629 view_id,
1630 subscription_id,
1631 callback,
1632 );
1633 }
1634
1635 Effect::ResizeWindow { window } => {
1636 if let Some(window) = self.windows.get_mut(&window.id()) {
1637 window
1638 .invalidation
1639 .get_or_insert(WindowInvalidation::default());
1640 }
1641 self.handle_window_moved(window);
1642 }
1643
1644 Effect::MoveWindow { window } => {
1645 self.handle_window_moved(window);
1646 }
1647
1648 Effect::WindowActivationObservation {
1649 window,
1650 subscription_id,
1651 callback,
1652 } => self.window_activation_observations.add_callback(
1653 window.id(),
1654 subscription_id,
1655 callback,
1656 ),
1657
1658 Effect::ActivateWindow { window, is_active } => {
1659 if self.handle_window_activation_effect(window, is_active) && is_active
1660 {
1661 focus_effects
1662 .entry(window.id())
1663 .or_insert_with(|| FocusEffect::View {
1664 window,
1665 view_id: self
1666 .read_window(window, |cx| cx.focused_view_id())
1667 .flatten(),
1668 is_forced: true,
1669 })
1670 .force();
1671 }
1672 }
1673
1674 Effect::WindowFullscreenObservation {
1675 window,
1676 subscription_id,
1677 callback,
1678 } => self.window_fullscreen_observations.add_callback(
1679 window.id(),
1680 subscription_id,
1681 callback,
1682 ),
1683
1684 Effect::FullscreenWindow {
1685 window,
1686 is_fullscreen,
1687 } => self.handle_fullscreen_effect(window, is_fullscreen),
1688
1689 Effect::WindowBoundsObservation {
1690 window,
1691 subscription_id,
1692 callback,
1693 } => self.window_bounds_observations.add_callback(
1694 window.id(),
1695 subscription_id,
1696 callback,
1697 ),
1698
1699 Effect::RefreshWindows => {
1700 refreshing = true;
1701 }
1702
1703 Effect::ActionDispatchNotification { action_id } => {
1704 self.handle_action_dispatch_notification_effect(action_id)
1705 }
1706 Effect::WindowShouldCloseSubscription { window, callback } => {
1707 self.handle_window_should_close_subscription_effect(window, callback)
1708 }
1709 Effect::Keystroke {
1710 window,
1711 keystroke,
1712 handled_by,
1713 result,
1714 } => self.handle_keystroke_effect(window, keystroke, handled_by, result),
1715 Effect::ActiveLabeledTasksChanged => {
1716 self.handle_active_labeled_tasks_changed_effect()
1717 }
1718 Effect::ActiveLabeledTasksObservation {
1719 subscription_id,
1720 callback,
1721 } => self.active_labeled_task_observations.add_callback(
1722 (),
1723 subscription_id,
1724 callback,
1725 ),
1726 }
1727 self.pending_notifications.clear();
1728 } else {
1729 for window in self.windows().collect::<Vec<_>>() {
1730 self.update_window(window, |cx| {
1731 let invalidation = if refreshing {
1732 let mut invalidation =
1733 cx.window.invalidation.take().unwrap_or_default();
1734 invalidation
1735 .updated
1736 .extend(cx.window.rendered_views.keys().copied());
1737 Some(invalidation)
1738 } else {
1739 cx.window.invalidation.take()
1740 };
1741
1742 if let Some(invalidation) = invalidation {
1743 let appearance = cx.window.platform_window.appearance();
1744 cx.invalidate(invalidation, appearance);
1745 if let Some(old_parents) = cx.layout(refreshing).log_err() {
1746 updated_windows.insert(window);
1747
1748 if let Some(focused_view_id) = cx.focused_view_id() {
1749 let old_ancestors = std::iter::successors(
1750 Some(focused_view_id),
1751 |&view_id| old_parents.get(&view_id).copied(),
1752 )
1753 .collect::<HashSet<_>>();
1754 let new_ancestors =
1755 cx.ancestors(focused_view_id).collect::<HashSet<_>>();
1756
1757 // Notify the old ancestors of the focused view when they don't contain it anymore.
1758 for old_ancestor in old_ancestors.iter().copied() {
1759 if !new_ancestors.contains(&old_ancestor) {
1760 if let Some(mut view) =
1761 cx.views.remove(&(window.id(), old_ancestor))
1762 {
1763 view.focus_out(
1764 focused_view_id,
1765 cx,
1766 old_ancestor,
1767 );
1768 cx.views
1769 .insert((window.id(), old_ancestor), view);
1770 }
1771 }
1772 }
1773
1774 // Notify the new ancestors of the focused view if they contain it now.
1775 for new_ancestor in new_ancestors.iter().copied() {
1776 if !old_ancestors.contains(&new_ancestor) {
1777 if let Some(mut view) =
1778 cx.views.remove(&(window.id(), new_ancestor))
1779 {
1780 view.focus_in(
1781 focused_view_id,
1782 cx,
1783 new_ancestor,
1784 );
1785 cx.views
1786 .insert((window.id(), new_ancestor), view);
1787 }
1788 }
1789 }
1790
1791 // When the previously-focused view has been dropped and
1792 // there isn't any pending focus, focus the root view.
1793 let root_view_id = cx.window.root_view().id();
1794 if focused_view_id != root_view_id
1795 && !cx
1796 .views
1797 .contains_key(&(window.id(), focused_view_id))
1798 && !focus_effects.contains_key(&window.id())
1799 {
1800 focus_effects.insert(
1801 window.id(),
1802 FocusEffect::View {
1803 window,
1804 view_id: Some(root_view_id),
1805 is_forced: false,
1806 },
1807 );
1808 }
1809 }
1810 }
1811 }
1812 });
1813 }
1814
1815 for (_, effect) in focus_effects.drain() {
1816 self.handle_focus_effect(effect);
1817 }
1818
1819 if self.pending_effects.is_empty() {
1820 for callback in after_window_update_callbacks.drain(..) {
1821 callback(self);
1822 }
1823
1824 for window in updated_windows.drain() {
1825 self.update_window(window, |cx| {
1826 if let Some(scene) = cx.paint().log_err() {
1827 cx.window.platform_window.present_scene(scene);
1828 }
1829 });
1830 }
1831
1832 if self.pending_effects.is_empty() {
1833 self.flushing_effects = false;
1834 self.pending_notifications.clear();
1835 self.pending_global_notifications.clear();
1836 break;
1837 }
1838 }
1839
1840 refreshing = false;
1841 }
1842 }
1843 }
1844 }
1845
1846 fn window_was_resized(&mut self, window: AnyWindowHandle) {
1847 self.pending_effects
1848 .push_back(Effect::ResizeWindow { window });
1849 }
1850
1851 fn window_was_moved(&mut self, window: AnyWindowHandle) {
1852 self.pending_effects
1853 .push_back(Effect::MoveWindow { window });
1854 }
1855
1856 fn window_was_fullscreen_changed(&mut self, window: AnyWindowHandle, is_fullscreen: bool) {
1857 self.pending_effects.push_back(Effect::FullscreenWindow {
1858 window,
1859 is_fullscreen,
1860 });
1861 }
1862
1863 fn window_changed_active_status(&mut self, window: AnyWindowHandle, is_active: bool) {
1864 self.pending_effects
1865 .push_back(Effect::ActivateWindow { window, is_active });
1866 }
1867
1868 fn keystroke(
1869 &mut self,
1870 window: AnyWindowHandle,
1871 keystroke: Keystroke,
1872 handled_by: Option<Box<dyn Action>>,
1873 result: MatchResult,
1874 ) {
1875 self.pending_effects.push_back(Effect::Keystroke {
1876 window,
1877 keystroke,
1878 handled_by,
1879 result,
1880 });
1881 }
1882
1883 pub fn refresh_windows(&mut self) {
1884 self.pending_effects.push_back(Effect::RefreshWindows);
1885 }
1886
1887 fn emit_global_event(&mut self, payload: Box<dyn Any>) {
1888 let type_id = (&*payload).type_id();
1889
1890 let mut subscriptions = self.global_subscriptions.clone();
1891 subscriptions.emit(type_id, |callback| {
1892 callback(payload.as_ref(), self);
1893 true //Always alive
1894 });
1895 }
1896
1897 fn handle_view_notification_effect(
1898 &mut self,
1899 observed_window: AnyWindowHandle,
1900 observed_view_id: usize,
1901 ) {
1902 let view_key = (observed_window.id(), observed_view_id);
1903 if let Some((view, mut view_metadata)) = self
1904 .views
1905 .remove(&view_key)
1906 .zip(self.views_metadata.remove(&view_key))
1907 {
1908 if let Some(window) = self.windows.get_mut(&observed_window.id()) {
1909 window
1910 .invalidation
1911 .get_or_insert_with(Default::default)
1912 .updated
1913 .insert(observed_view_id);
1914 }
1915
1916 view.update_keymap_context(&mut view_metadata.keymap_context, self);
1917 self.views.insert(view_key, view);
1918 self.views_metadata.insert(view_key, view_metadata);
1919
1920 let mut observations = self.observations.clone();
1921 observations.emit(observed_view_id, |callback| callback(self));
1922 }
1923 }
1924
1925 fn handle_entity_release_effect(&mut self, entity_id: usize, entity: &dyn Any) {
1926 self.release_observations
1927 .clone()
1928 .emit(entity_id, |callback| {
1929 callback(entity, self);
1930 // Release observations happen one time. So clear the callback by returning false
1931 false
1932 })
1933 }
1934
1935 fn handle_fullscreen_effect(&mut self, window: AnyWindowHandle, is_fullscreen: bool) {
1936 self.update_window(window, |cx| {
1937 cx.window.is_fullscreen = is_fullscreen;
1938
1939 let mut fullscreen_observations = cx.window_fullscreen_observations.clone();
1940 fullscreen_observations.emit(window.id(), |callback| callback(is_fullscreen, cx));
1941
1942 if let Some(uuid) = cx.window_display_uuid() {
1943 let bounds = cx.window_bounds();
1944 let mut bounds_observations = cx.window_bounds_observations.clone();
1945 bounds_observations.emit(window.id(), |callback| callback(bounds, uuid, cx));
1946 }
1947
1948 Some(())
1949 });
1950 }
1951
1952 fn handle_keystroke_effect(
1953 &mut self,
1954 window: AnyWindowHandle,
1955 keystroke: Keystroke,
1956 handled_by: Option<Box<dyn Action>>,
1957 result: MatchResult,
1958 ) {
1959 self.update_window(window, |cx| {
1960 let mut observations = cx.keystroke_observations.clone();
1961 observations.emit(window.id(), move |callback| {
1962 callback(&keystroke, &result, handled_by.as_ref(), cx)
1963 });
1964 });
1965 }
1966
1967 fn handle_window_activation_effect(&mut self, window: AnyWindowHandle, active: bool) -> bool {
1968 self.update_window(window, |cx| {
1969 if cx.window.is_active == active {
1970 return false;
1971 }
1972 cx.window.is_active = active;
1973
1974 let mut observations = cx.window_activation_observations.clone();
1975 observations.emit(window.id(), |callback| callback(active, cx));
1976 true
1977 })
1978 .unwrap_or(false)
1979 }
1980
1981 fn handle_focus_effect(&mut self, effect: FocusEffect) {
1982 let window = effect.window();
1983 self.update_window(window, |cx| {
1984 // Ensure the newly-focused view still exists, otherwise focus
1985 // the root view instead.
1986 let focused_id = match effect {
1987 FocusEffect::View { view_id, .. } => {
1988 if let Some(view_id) = view_id {
1989 if cx.views.contains_key(&(window.id(), view_id)) {
1990 Some(view_id)
1991 } else {
1992 Some(cx.root_view().id())
1993 }
1994 } else {
1995 None
1996 }
1997 }
1998 FocusEffect::ViewParent { view_id, .. } => Some(
1999 cx.window
2000 .parents
2001 .get(&view_id)
2002 .copied()
2003 .unwrap_or(cx.root_view().id()),
2004 ),
2005 };
2006
2007 let focus_changed = cx.window.focused_view_id != focused_id;
2008 let blurred_id = cx.window.focused_view_id;
2009 cx.window.focused_view_id = focused_id;
2010
2011 if focus_changed {
2012 if let Some(blurred_id) = blurred_id {
2013 for view_id in cx.ancestors(blurred_id).collect::<Vec<_>>() {
2014 if let Some(mut view) = cx.views.remove(&(window.id(), view_id)) {
2015 view.focus_out(blurred_id, cx, view_id);
2016 cx.views.insert((window.id(), view_id), view);
2017 }
2018 }
2019
2020 let mut subscriptions = cx.focus_observations.clone();
2021 subscriptions.emit(blurred_id, |callback| callback(false, cx));
2022 }
2023 }
2024
2025 if focus_changed || effect.is_forced() {
2026 if let Some(focused_id) = focused_id {
2027 for view_id in cx.ancestors(focused_id).collect::<Vec<_>>() {
2028 if let Some(mut view) = cx.views.remove(&(window.id(), view_id)) {
2029 view.focus_in(focused_id, cx, view_id);
2030 cx.views.insert((window.id(), view_id), view);
2031 }
2032 }
2033
2034 let mut subscriptions = cx.focus_observations.clone();
2035 subscriptions.emit(focused_id, |callback| callback(true, cx));
2036 }
2037 }
2038 });
2039 }
2040
2041 fn handle_action_dispatch_notification_effect(&mut self, action_id: TypeId) {
2042 self.action_dispatch_observations
2043 .clone()
2044 .emit((), |callback| {
2045 callback(action_id, self);
2046 true
2047 });
2048 }
2049
2050 fn handle_window_should_close_subscription_effect(
2051 &mut self,
2052 window: AnyWindowHandle,
2053 mut callback: WindowShouldCloseSubscriptionCallback,
2054 ) {
2055 let mut app = self.upgrade();
2056 if let Some(window) = self.windows.get_mut(&window.id()) {
2057 window
2058 .platform_window
2059 .on_should_close(Box::new(move || app.update(|cx| callback(cx))))
2060 }
2061 }
2062
2063 fn handle_window_moved(&mut self, window: AnyWindowHandle) {
2064 self.update_window(window, |cx| {
2065 if let Some(display) = cx.window_display_uuid() {
2066 let bounds = cx.window_bounds();
2067 cx.window_bounds_observations
2068 .clone()
2069 .emit(window.id(), move |callback| {
2070 callback(bounds, display, cx);
2071 true
2072 });
2073 }
2074 });
2075 }
2076
2077 fn handle_active_labeled_tasks_changed_effect(&mut self) {
2078 self.active_labeled_task_observations
2079 .clone()
2080 .emit((), move |callback| {
2081 callback(self);
2082 true
2083 });
2084 }
2085
2086 pub fn focus(&mut self, window: AnyWindowHandle, view_id: Option<usize>) {
2087 self.pending_effects
2088 .push_back(Effect::Focus(FocusEffect::View {
2089 window,
2090 view_id,
2091 is_forced: false,
2092 }));
2093 }
2094
2095 fn spawn_internal<F, Fut, T>(&mut self, task_name: Option<&'static str>, f: F) -> Task<T>
2096 where
2097 F: FnOnce(AsyncAppContext) -> Fut,
2098 Fut: 'static + Future<Output = T>,
2099 T: 'static,
2100 {
2101 let label_id = task_name.map(|task_name| {
2102 let id = post_inc(&mut self.next_labeled_task_id);
2103 self.active_labeled_tasks.insert(id, task_name);
2104 self.pending_effects
2105 .push_back(Effect::ActiveLabeledTasksChanged);
2106 id
2107 });
2108
2109 let future = f(self.to_async());
2110 let cx = self.to_async();
2111 self.foreground.spawn(async move {
2112 let result = future.await;
2113 let mut cx = cx.0.borrow_mut();
2114
2115 if let Some(completed_label_id) = label_id {
2116 cx.active_labeled_tasks.remove(&completed_label_id);
2117 cx.pending_effects
2118 .push_back(Effect::ActiveLabeledTasksChanged);
2119 }
2120 cx.flush_effects();
2121 result
2122 })
2123 }
2124
2125 pub fn spawn_labeled<F, Fut, T>(&mut self, task_name: &'static str, f: F) -> Task<T>
2126 where
2127 F: FnOnce(AsyncAppContext) -> Fut,
2128 Fut: 'static + Future<Output = T>,
2129 T: 'static,
2130 {
2131 self.spawn_internal(Some(task_name), f)
2132 }
2133
2134 pub fn spawn<F, Fut, T>(&mut self, f: F) -> Task<T>
2135 where
2136 F: FnOnce(AsyncAppContext) -> Fut,
2137 Fut: 'static + Future<Output = T>,
2138 T: 'static,
2139 {
2140 self.spawn_internal(None, f)
2141 }
2142
2143 pub fn to_async(&self) -> AsyncAppContext {
2144 AsyncAppContext(self.weak_self.as_ref().unwrap().upgrade().unwrap())
2145 }
2146
2147 pub fn write_to_clipboard(&self, item: ClipboardItem) {
2148 self.platform.write_to_clipboard(item);
2149 }
2150
2151 pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
2152 self.platform.read_from_clipboard()
2153 }
2154
2155 #[cfg(any(test, feature = "test-support"))]
2156 pub fn leak_detector(&self) -> Arc<Mutex<LeakDetector>> {
2157 self.ref_counts.lock().leak_detector.clone()
2158 }
2159}
2160
2161impl BorrowAppContext for AppContext {
2162 fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
2163 f(self)
2164 }
2165
2166 fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T {
2167 f(self)
2168 }
2169}
2170
2171impl BorrowWindowContext for AppContext {
2172 type Result<T> = Option<T>;
2173
2174 fn read_window<T, F>(&self, window: AnyWindowHandle, f: F) -> Self::Result<T>
2175 where
2176 F: FnOnce(&WindowContext) -> T,
2177 {
2178 AppContext::read_window(self, window, f)
2179 }
2180
2181 fn read_window_optional<T, F>(&self, window: AnyWindowHandle, f: F) -> Option<T>
2182 where
2183 F: FnOnce(&WindowContext) -> Option<T>,
2184 {
2185 AppContext::read_window(self, window, f).flatten()
2186 }
2187
2188 fn update_window<T, F>(&mut self, handle: AnyWindowHandle, f: F) -> Self::Result<T>
2189 where
2190 F: FnOnce(&mut WindowContext) -> T,
2191 {
2192 self.update(|app_context| {
2193 let mut window = app_context.windows.remove(&handle.id())?;
2194 let mut window_context = WindowContext::mutable(app_context, &mut window, handle);
2195 let result = f(&mut window_context);
2196 if !window_context.removed {
2197 app_context.windows.insert(handle.id(), window);
2198 }
2199 Some(result)
2200 })
2201 }
2202
2203 fn update_window_optional<T, F>(&mut self, handle: AnyWindowHandle, f: F) -> Option<T>
2204 where
2205 F: FnOnce(&mut WindowContext) -> Option<T>,
2206 {
2207 AppContext::update_window(self, handle, f).flatten()
2208 }
2209}
2210
2211#[derive(Debug)]
2212pub enum ParentId {
2213 View(usize),
2214 Root,
2215}
2216
2217struct ViewMetadata {
2218 type_id: TypeId,
2219 keymap_context: KeymapContext,
2220}
2221
2222#[derive(Default, Clone)]
2223pub struct WindowInvalidation {
2224 pub updated: HashSet<usize>,
2225 pub removed: Vec<usize>,
2226}
2227
2228#[derive(Debug)]
2229pub enum FocusEffect {
2230 View {
2231 window: AnyWindowHandle,
2232 view_id: Option<usize>,
2233 is_forced: bool,
2234 },
2235 ViewParent {
2236 window: AnyWindowHandle,
2237 view_id: usize,
2238 is_forced: bool,
2239 },
2240}
2241
2242impl FocusEffect {
2243 fn window(&self) -> AnyWindowHandle {
2244 match self {
2245 FocusEffect::View { window, .. } => *window,
2246 FocusEffect::ViewParent { window, .. } => *window,
2247 }
2248 }
2249
2250 fn is_forced(&self) -> bool {
2251 match self {
2252 FocusEffect::View { is_forced, .. } => *is_forced,
2253 FocusEffect::ViewParent { is_forced, .. } => *is_forced,
2254 }
2255 }
2256
2257 fn force(&mut self) {
2258 match self {
2259 FocusEffect::View { is_forced, .. } => *is_forced = true,
2260 FocusEffect::ViewParent { is_forced, .. } => *is_forced = true,
2261 }
2262 }
2263}
2264
2265pub enum Effect {
2266 Subscription {
2267 entity_id: usize,
2268 subscription_id: usize,
2269 callback: SubscriptionCallback,
2270 },
2271 Event {
2272 entity_id: usize,
2273 payload: Box<dyn Any>,
2274 },
2275 GlobalSubscription {
2276 type_id: TypeId,
2277 subscription_id: usize,
2278 callback: GlobalSubscriptionCallback,
2279 },
2280 GlobalEvent {
2281 payload: Box<dyn Any>,
2282 },
2283 Observation {
2284 entity_id: usize,
2285 subscription_id: usize,
2286 callback: ObservationCallback,
2287 },
2288 ModelNotification {
2289 model_id: usize,
2290 },
2291 ViewNotification {
2292 window: AnyWindowHandle,
2293 view_id: usize,
2294 },
2295 Deferred {
2296 callback: Box<dyn FnOnce(&mut AppContext)>,
2297 after_window_update: bool,
2298 },
2299 GlobalNotification {
2300 type_id: TypeId,
2301 },
2302 ModelRelease {
2303 model_id: usize,
2304 model: Box<dyn AnyModel>,
2305 },
2306 ViewRelease {
2307 view_id: usize,
2308 view: Box<dyn AnyView>,
2309 },
2310 Focus(FocusEffect),
2311 FocusObservation {
2312 view_id: usize,
2313 subscription_id: usize,
2314 callback: FocusObservationCallback,
2315 },
2316 ResizeWindow {
2317 window: AnyWindowHandle,
2318 },
2319 MoveWindow {
2320 window: AnyWindowHandle,
2321 },
2322 ActivateWindow {
2323 window: AnyWindowHandle,
2324 is_active: bool,
2325 },
2326 WindowActivationObservation {
2327 window: AnyWindowHandle,
2328 subscription_id: usize,
2329 callback: WindowActivationCallback,
2330 },
2331 FullscreenWindow {
2332 window: AnyWindowHandle,
2333 is_fullscreen: bool,
2334 },
2335 WindowFullscreenObservation {
2336 window: AnyWindowHandle,
2337 subscription_id: usize,
2338 callback: WindowFullscreenCallback,
2339 },
2340 WindowBoundsObservation {
2341 window: AnyWindowHandle,
2342 subscription_id: usize,
2343 callback: WindowBoundsCallback,
2344 },
2345 Keystroke {
2346 window: AnyWindowHandle,
2347 keystroke: Keystroke,
2348 handled_by: Option<Box<dyn Action>>,
2349 result: MatchResult,
2350 },
2351 RefreshWindows,
2352 ActionDispatchNotification {
2353 action_id: TypeId,
2354 },
2355 WindowShouldCloseSubscription {
2356 window: AnyWindowHandle,
2357 callback: WindowShouldCloseSubscriptionCallback,
2358 },
2359 ActiveLabeledTasksChanged,
2360 ActiveLabeledTasksObservation {
2361 subscription_id: usize,
2362 callback: ActiveLabeledTasksCallback,
2363 },
2364}
2365
2366impl Debug for Effect {
2367 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2368 match self {
2369 Effect::Subscription {
2370 entity_id,
2371 subscription_id,
2372 ..
2373 } => f
2374 .debug_struct("Effect::Subscribe")
2375 .field("entity_id", entity_id)
2376 .field("subscription_id", subscription_id)
2377 .finish(),
2378 Effect::Event { entity_id, .. } => f
2379 .debug_struct("Effect::Event")
2380 .field("entity_id", entity_id)
2381 .finish(),
2382 Effect::GlobalSubscription {
2383 type_id,
2384 subscription_id,
2385 ..
2386 } => f
2387 .debug_struct("Effect::Subscribe")
2388 .field("type_id", type_id)
2389 .field("subscription_id", subscription_id)
2390 .finish(),
2391 Effect::GlobalEvent { payload, .. } => f
2392 .debug_struct("Effect::GlobalEvent")
2393 .field("type_id", &(&*payload).type_id())
2394 .finish(),
2395 Effect::Observation {
2396 entity_id,
2397 subscription_id,
2398 ..
2399 } => f
2400 .debug_struct("Effect::Observation")
2401 .field("entity_id", entity_id)
2402 .field("subscription_id", subscription_id)
2403 .finish(),
2404 Effect::ModelNotification { model_id } => f
2405 .debug_struct("Effect::ModelNotification")
2406 .field("model_id", model_id)
2407 .finish(),
2408 Effect::ViewNotification { window, view_id } => f
2409 .debug_struct("Effect::ViewNotification")
2410 .field("window_id", &window.id())
2411 .field("view_id", view_id)
2412 .finish(),
2413 Effect::GlobalNotification { type_id } => f
2414 .debug_struct("Effect::GlobalNotification")
2415 .field("type_id", type_id)
2416 .finish(),
2417 Effect::Deferred { .. } => f.debug_struct("Effect::Deferred").finish(),
2418 Effect::ModelRelease { model_id, .. } => f
2419 .debug_struct("Effect::ModelRelease")
2420 .field("model_id", model_id)
2421 .finish(),
2422 Effect::ViewRelease { view_id, .. } => f
2423 .debug_struct("Effect::ViewRelease")
2424 .field("view_id", view_id)
2425 .finish(),
2426 Effect::Focus(focus) => f.debug_tuple("Effect::Focus").field(focus).finish(),
2427 Effect::FocusObservation {
2428 view_id,
2429 subscription_id,
2430 ..
2431 } => f
2432 .debug_struct("Effect::FocusObservation")
2433 .field("view_id", view_id)
2434 .field("subscription_id", subscription_id)
2435 .finish(),
2436 Effect::ActionDispatchNotification { action_id, .. } => f
2437 .debug_struct("Effect::ActionDispatchNotification")
2438 .field("action_id", action_id)
2439 .finish(),
2440 Effect::ResizeWindow { window } => f
2441 .debug_struct("Effect::RefreshWindow")
2442 .field("window_id", &window.id())
2443 .finish(),
2444 Effect::MoveWindow { window } => f
2445 .debug_struct("Effect::MoveWindow")
2446 .field("window_id", &window.id())
2447 .finish(),
2448 Effect::WindowActivationObservation {
2449 window,
2450 subscription_id,
2451 ..
2452 } => f
2453 .debug_struct("Effect::WindowActivationObservation")
2454 .field("window_id", &window.id())
2455 .field("subscription_id", subscription_id)
2456 .finish(),
2457 Effect::ActivateWindow { window, is_active } => f
2458 .debug_struct("Effect::ActivateWindow")
2459 .field("window_id", &window.id())
2460 .field("is_active", is_active)
2461 .finish(),
2462 Effect::FullscreenWindow {
2463 window,
2464 is_fullscreen,
2465 } => f
2466 .debug_struct("Effect::FullscreenWindow")
2467 .field("window_id", &window.id())
2468 .field("is_fullscreen", is_fullscreen)
2469 .finish(),
2470 Effect::WindowFullscreenObservation {
2471 window,
2472 subscription_id,
2473 callback: _,
2474 } => f
2475 .debug_struct("Effect::WindowFullscreenObservation")
2476 .field("window_id", &window.id())
2477 .field("subscription_id", subscription_id)
2478 .finish(),
2479
2480 Effect::WindowBoundsObservation {
2481 window,
2482 subscription_id,
2483 callback: _,
2484 } => f
2485 .debug_struct("Effect::WindowBoundsObservation")
2486 .field("window_id", &window.id())
2487 .field("subscription_id", subscription_id)
2488 .finish(),
2489 Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(),
2490 Effect::WindowShouldCloseSubscription { window, .. } => f
2491 .debug_struct("Effect::WindowShouldCloseSubscription")
2492 .field("window_id", &window.id())
2493 .finish(),
2494 Effect::Keystroke {
2495 window,
2496 keystroke,
2497 handled_by,
2498 result,
2499 } => f
2500 .debug_struct("Effect::Keystroke")
2501 .field("window_id", &window.id())
2502 .field("keystroke", keystroke)
2503 .field(
2504 "keystroke",
2505 &handled_by.as_ref().map(|handled_by| handled_by.name()),
2506 )
2507 .field("result", result)
2508 .finish(),
2509 Effect::ActiveLabeledTasksChanged => {
2510 f.debug_struct("Effect::ActiveLabeledTasksChanged").finish()
2511 }
2512 Effect::ActiveLabeledTasksObservation {
2513 subscription_id,
2514 callback: _,
2515 } => f
2516 .debug_struct("Effect::ActiveLabeledTasksObservation")
2517 .field("subscription_id", subscription_id)
2518 .finish(),
2519 }
2520 }
2521}
2522
2523pub trait AnyModel {
2524 fn as_any(&self) -> &dyn Any;
2525 fn as_any_mut(&mut self) -> &mut dyn Any;
2526 fn release(&mut self, cx: &mut AppContext);
2527 fn app_will_quit(
2528 &mut self,
2529 cx: &mut AppContext,
2530 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2531}
2532
2533impl<T> AnyModel for T
2534where
2535 T: Entity,
2536{
2537 fn as_any(&self) -> &dyn Any {
2538 self
2539 }
2540
2541 fn as_any_mut(&mut self) -> &mut dyn Any {
2542 self
2543 }
2544
2545 fn release(&mut self, cx: &mut AppContext) {
2546 self.release(cx);
2547 }
2548
2549 fn app_will_quit(
2550 &mut self,
2551 cx: &mut AppContext,
2552 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2553 self.app_will_quit(cx)
2554 }
2555}
2556
2557pub trait AnyView {
2558 fn as_any(&self) -> &dyn Any;
2559 fn as_any_mut(&mut self) -> &mut dyn Any;
2560 fn release(&mut self, cx: &mut AppContext);
2561 fn app_will_quit(
2562 &mut self,
2563 cx: &mut AppContext,
2564 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>>;
2565 fn ui_name(&self) -> &'static str;
2566 fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box<dyn AnyRootElement>;
2567 fn focus_in<'a, 'b>(&mut self, focused_id: usize, cx: &mut WindowContext<'a>, view_id: usize);
2568 fn focus_out(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize);
2569 fn key_down(&mut self, event: &KeyDownEvent, cx: &mut WindowContext, view_id: usize) -> bool;
2570 fn key_up(&mut self, event: &KeyUpEvent, cx: &mut WindowContext, view_id: usize) -> bool;
2571 fn modifiers_changed(
2572 &mut self,
2573 event: &ModifiersChangedEvent,
2574 cx: &mut WindowContext,
2575 view_id: usize,
2576 ) -> bool;
2577 fn update_keymap_context(&self, keymap: &mut KeymapContext, cx: &AppContext);
2578 fn debug_json(&self, cx: &WindowContext) -> serde_json::Value;
2579
2580 fn text_for_range(&self, range: Range<usize>, cx: &WindowContext) -> Option<String>;
2581 fn selected_text_range(&self, cx: &WindowContext) -> Option<Range<usize>>;
2582 fn marked_text_range(&self, cx: &WindowContext) -> Option<Range<usize>>;
2583 fn unmark_text(&mut self, cx: &mut WindowContext, view_id: usize);
2584 fn replace_text_in_range(
2585 &mut self,
2586 range: Option<Range<usize>>,
2587 text: &str,
2588 cx: &mut WindowContext,
2589 view_id: usize,
2590 );
2591 fn replace_and_mark_text_in_range(
2592 &mut self,
2593 range: Option<Range<usize>>,
2594 new_text: &str,
2595 new_selected_range: Option<Range<usize>>,
2596 cx: &mut WindowContext,
2597 view_id: usize,
2598 );
2599 fn any_handle(
2600 &self,
2601 window: AnyWindowHandle,
2602 view_id: usize,
2603 cx: &AppContext,
2604 ) -> AnyViewHandle {
2605 AnyViewHandle::new(
2606 window,
2607 view_id,
2608 self.as_any().type_id(),
2609 cx.ref_counts.clone(),
2610 )
2611 }
2612}
2613
2614impl<V> AnyView for V
2615where
2616 V: View,
2617{
2618 fn as_any(&self) -> &dyn Any {
2619 self
2620 }
2621
2622 fn as_any_mut(&mut self) -> &mut dyn Any {
2623 self
2624 }
2625
2626 fn release(&mut self, cx: &mut AppContext) {
2627 self.release(cx);
2628 }
2629
2630 fn app_will_quit(
2631 &mut self,
2632 cx: &mut AppContext,
2633 ) -> Option<Pin<Box<dyn 'static + Future<Output = ()>>>> {
2634 self.app_will_quit(cx)
2635 }
2636
2637 fn ui_name(&self) -> &'static str {
2638 V::ui_name()
2639 }
2640
2641 fn render(&mut self, cx: &mut WindowContext, view_id: usize) -> Box<dyn AnyRootElement> {
2642 let mut view_context = ViewContext::mutable(cx, view_id);
2643 let element = V::render(self, &mut view_context);
2644 let view = WeakViewHandle::new(cx.window_handle, view_id);
2645 Box::new(RootElement::new(element, view))
2646 }
2647
2648 fn focus_in(&mut self, focused_id: usize, cx: &mut WindowContext, view_id: usize) {
2649 let mut cx = ViewContext::mutable(cx, view_id);
2650 let focused_view_handle: AnyViewHandle = if view_id == focused_id {
2651 cx.handle().into_any()
2652 } else {
2653 let focused_type = cx
2654 .views_metadata
2655 .get(&(cx.window_handle.id(), focused_id))
2656 .unwrap()
2657 .type_id;
2658 AnyViewHandle::new(
2659 cx.window_handle,
2660 focused_id,
2661 focused_type,
2662 cx.ref_counts.clone(),
2663 )
2664 };
2665 View::focus_in(self, focused_view_handle, &mut cx);
2666 }
2667
2668 fn focus_out(&mut self, blurred_id: usize, cx: &mut WindowContext, view_id: usize) {
2669 let mut cx = ViewContext::mutable(cx, view_id);
2670 let blurred_view_handle: AnyViewHandle = if view_id == blurred_id {
2671 cx.handle().into_any()
2672 } else {
2673 let blurred_type = cx
2674 .views_metadata
2675 .get(&(cx.window_handle.id(), blurred_id))
2676 .unwrap()
2677 .type_id;
2678 AnyViewHandle::new(
2679 cx.window_handle,
2680 blurred_id,
2681 blurred_type,
2682 cx.ref_counts.clone(),
2683 )
2684 };
2685 View::focus_out(self, blurred_view_handle, &mut cx);
2686 }
2687
2688 fn key_down(&mut self, event: &KeyDownEvent, cx: &mut WindowContext, view_id: usize) -> bool {
2689 let mut cx = ViewContext::mutable(cx, view_id);
2690 View::key_down(self, event, &mut cx)
2691 }
2692
2693 fn key_up(&mut self, event: &KeyUpEvent, cx: &mut WindowContext, view_id: usize) -> bool {
2694 let mut cx = ViewContext::mutable(cx, view_id);
2695 View::key_up(self, event, &mut cx)
2696 }
2697
2698 fn modifiers_changed(
2699 &mut self,
2700 event: &ModifiersChangedEvent,
2701 cx: &mut WindowContext,
2702 view_id: usize,
2703 ) -> bool {
2704 let mut cx = ViewContext::mutable(cx, view_id);
2705 View::modifiers_changed(self, event, &mut cx)
2706 }
2707
2708 fn update_keymap_context(&self, keymap: &mut KeymapContext, cx: &AppContext) {
2709 View::update_keymap_context(self, keymap, cx)
2710 }
2711
2712 fn debug_json(&self, cx: &WindowContext) -> serde_json::Value {
2713 View::debug_json(self, cx)
2714 }
2715
2716 fn text_for_range(&self, range: Range<usize>, cx: &WindowContext) -> Option<String> {
2717 View::text_for_range(self, range, cx)
2718 }
2719
2720 fn selected_text_range(&self, cx: &WindowContext) -> Option<Range<usize>> {
2721 View::selected_text_range(self, cx)
2722 }
2723
2724 fn marked_text_range(&self, cx: &WindowContext) -> Option<Range<usize>> {
2725 View::marked_text_range(self, cx)
2726 }
2727
2728 fn unmark_text(&mut self, cx: &mut WindowContext, view_id: usize) {
2729 let mut cx = ViewContext::mutable(cx, view_id);
2730 View::unmark_text(self, &mut cx)
2731 }
2732
2733 fn replace_text_in_range(
2734 &mut self,
2735 range: Option<Range<usize>>,
2736 text: &str,
2737 cx: &mut WindowContext,
2738 view_id: usize,
2739 ) {
2740 let mut cx = ViewContext::mutable(cx, view_id);
2741 View::replace_text_in_range(self, range, text, &mut cx)
2742 }
2743
2744 fn replace_and_mark_text_in_range(
2745 &mut self,
2746 range: Option<Range<usize>>,
2747 new_text: &str,
2748 new_selected_range: Option<Range<usize>>,
2749 cx: &mut WindowContext,
2750 view_id: usize,
2751 ) {
2752 let mut cx = ViewContext::mutable(cx, view_id);
2753 View::replace_and_mark_text_in_range(self, range, new_text, new_selected_range, &mut cx)
2754 }
2755}
2756
2757pub struct ModelContext<'a, T: ?Sized> {
2758 app: &'a mut AppContext,
2759 model_id: usize,
2760 model_type: PhantomData<T>,
2761 halt_stream: bool,
2762}
2763
2764impl<'a, T: Entity> ModelContext<'a, T> {
2765 fn new(app: &'a mut AppContext, model_id: usize) -> Self {
2766 Self {
2767 app,
2768 model_id,
2769 model_type: PhantomData,
2770 halt_stream: false,
2771 }
2772 }
2773
2774 pub fn background(&self) -> &Arc<executor::Background> {
2775 &self.app.background
2776 }
2777
2778 pub fn halt_stream(&mut self) {
2779 self.halt_stream = true;
2780 }
2781
2782 pub fn model_id(&self) -> usize {
2783 self.model_id
2784 }
2785
2786 pub fn add_model<S, F>(&mut self, build_model: F) -> ModelHandle<S>
2787 where
2788 S: Entity,
2789 F: FnOnce(&mut ModelContext<S>) -> S,
2790 {
2791 self.app.add_model(build_model)
2792 }
2793
2794 pub fn emit(&mut self, payload: T::Event) {
2795 self.app.pending_effects.push_back(Effect::Event {
2796 entity_id: self.model_id,
2797 payload: Box::new(payload),
2798 });
2799 }
2800
2801 pub fn notify(&mut self) {
2802 self.app.notify_model(self.model_id);
2803 }
2804
2805 pub fn subscribe<S: Entity, F>(
2806 &mut self,
2807 handle: &ModelHandle<S>,
2808 mut callback: F,
2809 ) -> Subscription
2810 where
2811 S::Event: 'static,
2812 F: 'static + FnMut(&mut T, ModelHandle<S>, &S::Event, &mut ModelContext<T>),
2813 {
2814 let subscriber = self.weak_handle();
2815 self.app
2816 .subscribe_internal(handle, move |emitter, event, cx| {
2817 if let Some(subscriber) = subscriber.upgrade(cx) {
2818 subscriber.update(cx, |subscriber, cx| {
2819 callback(subscriber, emitter, event, cx);
2820 });
2821 true
2822 } else {
2823 false
2824 }
2825 })
2826 }
2827
2828 pub fn observe<S, F>(&mut self, handle: &ModelHandle<S>, mut callback: F) -> Subscription
2829 where
2830 S: Entity,
2831 F: 'static + FnMut(&mut T, ModelHandle<S>, &mut ModelContext<T>),
2832 {
2833 let observer = self.weak_handle();
2834 self.app.observe_internal(handle, move |observed, cx| {
2835 if let Some(observer) = observer.upgrade(cx) {
2836 observer.update(cx, |observer, cx| {
2837 callback(observer, observed, cx);
2838 });
2839 true
2840 } else {
2841 false
2842 }
2843 })
2844 }
2845
2846 pub fn observe_global<G, F>(&mut self, mut callback: F) -> Subscription
2847 where
2848 G: Any,
2849 F: 'static + FnMut(&mut T, &mut ModelContext<T>),
2850 {
2851 let observer = self.weak_handle();
2852 self.app.observe_global::<G, _>(move |cx| {
2853 if let Some(observer) = observer.upgrade(cx) {
2854 observer.update(cx, |observer, cx| callback(observer, cx));
2855 }
2856 })
2857 }
2858
2859 pub fn observe_release<S, F>(
2860 &mut self,
2861 handle: &ModelHandle<S>,
2862 mut callback: F,
2863 ) -> Subscription
2864 where
2865 S: Entity,
2866 F: 'static + FnMut(&mut T, &S, &mut ModelContext<T>),
2867 {
2868 let observer = self.weak_handle();
2869 self.app.observe_release(handle, move |released, cx| {
2870 if let Some(observer) = observer.upgrade(cx) {
2871 observer.update(cx, |observer, cx| {
2872 callback(observer, released, cx);
2873 });
2874 }
2875 })
2876 }
2877
2878 pub fn handle(&self) -> ModelHandle<T> {
2879 ModelHandle::new(self.model_id, &self.app.ref_counts)
2880 }
2881
2882 pub fn weak_handle(&self) -> WeakModelHandle<T> {
2883 WeakModelHandle::new(self.model_id)
2884 }
2885
2886 pub fn spawn<F, Fut, S>(&mut self, f: F) -> Task<S>
2887 where
2888 F: FnOnce(ModelHandle<T>, AsyncAppContext) -> Fut,
2889 Fut: 'static + Future<Output = S>,
2890 S: 'static,
2891 {
2892 let handle = self.handle();
2893 self.app.spawn(|cx| f(handle, cx))
2894 }
2895
2896 pub fn spawn_weak<F, Fut, S>(&mut self, f: F) -> Task<S>
2897 where
2898 F: FnOnce(WeakModelHandle<T>, AsyncAppContext) -> Fut,
2899 Fut: 'static + Future<Output = S>,
2900 S: 'static,
2901 {
2902 let handle = self.weak_handle();
2903 self.app.spawn(|cx| f(handle, cx))
2904 }
2905}
2906
2907impl<M> AsRef<AppContext> for ModelContext<'_, M> {
2908 fn as_ref(&self) -> &AppContext {
2909 &self.app
2910 }
2911}
2912
2913impl<M> AsMut<AppContext> for ModelContext<'_, M> {
2914 fn as_mut(&mut self) -> &mut AppContext {
2915 self.app
2916 }
2917}
2918
2919impl<M> BorrowAppContext for ModelContext<'_, M> {
2920 fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
2921 self.app.read_with(f)
2922 }
2923
2924 fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T {
2925 self.app.update(f)
2926 }
2927}
2928
2929impl<M> Deref for ModelContext<'_, M> {
2930 type Target = AppContext;
2931
2932 fn deref(&self) -> &Self::Target {
2933 self.app
2934 }
2935}
2936
2937impl<M> DerefMut for ModelContext<'_, M> {
2938 fn deref_mut(&mut self) -> &mut Self::Target {
2939 &mut self.app
2940 }
2941}
2942
2943pub struct ViewContext<'a, 'b, T: ?Sized> {
2944 window_context: Reference<'b, WindowContext<'a>>,
2945 view_id: usize,
2946 view_type: PhantomData<T>,
2947}
2948
2949impl<'a, 'b, T: View> Deref for ViewContext<'a, 'b, T> {
2950 type Target = WindowContext<'a>;
2951
2952 fn deref(&self) -> &Self::Target {
2953 &self.window_context
2954 }
2955}
2956
2957impl<T: View> DerefMut for ViewContext<'_, '_, T> {
2958 fn deref_mut(&mut self) -> &mut Self::Target {
2959 &mut self.window_context
2960 }
2961}
2962
2963impl<'a, 'b, V: View> ViewContext<'a, 'b, V> {
2964 pub(crate) fn mutable(window_context: &'b mut WindowContext<'a>, view_id: usize) -> Self {
2965 Self {
2966 window_context: Reference::Mutable(window_context),
2967 view_id,
2968 view_type: PhantomData,
2969 }
2970 }
2971
2972 pub(crate) fn immutable(window_context: &'b WindowContext<'a>, view_id: usize) -> Self {
2973 Self {
2974 window_context: Reference::Immutable(window_context),
2975 view_id,
2976 view_type: PhantomData,
2977 }
2978 }
2979
2980 pub fn window_context(&mut self) -> &mut WindowContext<'a> {
2981 &mut self.window_context
2982 }
2983
2984 pub fn handle(&self) -> ViewHandle<V> {
2985 ViewHandle::new(
2986 self.window_handle,
2987 self.view_id,
2988 &self.window_context.ref_counts,
2989 )
2990 }
2991
2992 pub fn weak_handle(&self) -> WeakViewHandle<V> {
2993 WeakViewHandle::new(self.window_handle, self.view_id)
2994 }
2995
2996 pub fn window(&self) -> AnyWindowHandle {
2997 self.window_handle
2998 }
2999
3000 pub fn view_id(&self) -> usize {
3001 self.view_id
3002 }
3003
3004 pub fn foreground(&self) -> &Rc<executor::Foreground> {
3005 self.window_context.foreground()
3006 }
3007
3008 pub fn background_executor(&self) -> &Arc<executor::Background> {
3009 &self.window_context.background
3010 }
3011
3012 pub fn platform(&self) -> &Arc<dyn Platform> {
3013 self.window_context.platform()
3014 }
3015
3016 pub fn prompt_for_paths(
3017 &self,
3018 options: PathPromptOptions,
3019 ) -> oneshot::Receiver<Option<Vec<PathBuf>>> {
3020 self.window_context.prompt_for_paths(options)
3021 }
3022
3023 pub fn prompt_for_new_path(&self, directory: &Path) -> oneshot::Receiver<Option<PathBuf>> {
3024 self.window_context.prompt_for_new_path(directory)
3025 }
3026
3027 pub fn reveal_path(&self, path: &Path) {
3028 self.window_context.reveal_path(path)
3029 }
3030
3031 pub fn focus(&mut self, handle: &AnyViewHandle) {
3032 self.window_context.focus(Some(handle.view_id));
3033 }
3034
3035 pub fn focus_self(&mut self) {
3036 let view_id = self.view_id;
3037 self.window_context.focus(Some(view_id));
3038 }
3039
3040 pub fn is_self_focused(&self) -> bool {
3041 self.window.focused_view_id == Some(self.view_id)
3042 }
3043
3044 pub fn focus_parent(&mut self) {
3045 let window = self.window_handle;
3046 let view_id = self.view_id;
3047 self.pending_effects
3048 .push_back(Effect::Focus(FocusEffect::ViewParent {
3049 window,
3050 view_id,
3051 is_forced: false,
3052 }));
3053 }
3054
3055 pub fn blur(&mut self) {
3056 self.window_context.focus(None);
3057 }
3058
3059 pub fn on_window_should_close<F>(&mut self, mut callback: F)
3060 where
3061 F: 'static + FnMut(&mut V, &mut ViewContext<V>) -> bool,
3062 {
3063 let window = self.window_handle;
3064 let view = self.weak_handle();
3065 self.pending_effects
3066 .push_back(Effect::WindowShouldCloseSubscription {
3067 window,
3068 callback: Box::new(move |cx| {
3069 cx.update_window(window, |cx| {
3070 if let Some(view) = view.upgrade(cx) {
3071 view.update(cx, |view, cx| callback(view, cx))
3072 } else {
3073 true
3074 }
3075 })
3076 .unwrap_or(true)
3077 }),
3078 });
3079 }
3080
3081 pub fn subscribe<E, H, F>(&mut self, handle: &H, mut callback: F) -> Subscription
3082 where
3083 E: Entity,
3084 E::Event: 'static,
3085 H: Handle<E>,
3086 F: 'static + FnMut(&mut V, H, &E::Event, &mut ViewContext<V>),
3087 {
3088 let subscriber = self.weak_handle();
3089 self.window_context
3090 .subscribe_internal(handle, move |emitter, event, cx| {
3091 if let Some(subscriber) = subscriber.upgrade(cx) {
3092 subscriber.update(cx, |subscriber, cx| {
3093 callback(subscriber, emitter, event, cx);
3094 });
3095 true
3096 } else {
3097 false
3098 }
3099 })
3100 }
3101
3102 pub fn observe<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3103 where
3104 E: Entity,
3105 H: Handle<E>,
3106 F: 'static + FnMut(&mut V, H, &mut ViewContext<V>),
3107 {
3108 let window = self.window_handle;
3109 let observer = self.weak_handle();
3110 self.window_context
3111 .observe_internal(handle, move |observed, cx| {
3112 cx.update_window(window, |cx| {
3113 if let Some(observer) = observer.upgrade(cx) {
3114 observer.update(cx, |observer, cx| {
3115 callback(observer, observed, cx);
3116 });
3117 true
3118 } else {
3119 false
3120 }
3121 })
3122 .unwrap_or(false)
3123 })
3124 }
3125
3126 pub fn observe_global<G, F>(&mut self, mut callback: F) -> Subscription
3127 where
3128 G: Any,
3129 F: 'static + FnMut(&mut V, &mut ViewContext<V>),
3130 {
3131 let window = self.window_handle;
3132 let observer = self.weak_handle();
3133 self.window_context.observe_global::<G, _>(move |cx| {
3134 cx.update_window(window, |cx| {
3135 if let Some(observer) = observer.upgrade(cx) {
3136 observer.update(cx, |observer, cx| callback(observer, cx));
3137 }
3138 });
3139 })
3140 }
3141
3142 pub fn observe_focus<F, W>(&mut self, handle: &ViewHandle<W>, mut callback: F) -> Subscription
3143 where
3144 F: 'static + FnMut(&mut V, ViewHandle<W>, bool, &mut ViewContext<V>),
3145 W: View,
3146 {
3147 let observer = self.weak_handle();
3148 self.window_context
3149 .observe_focus(handle, move |observed, focused, cx| {
3150 if let Some(observer) = observer.upgrade(cx) {
3151 observer.update(cx, |observer, cx| {
3152 callback(observer, observed, focused, cx);
3153 });
3154 true
3155 } else {
3156 false
3157 }
3158 })
3159 }
3160
3161 pub fn observe_release<E, F, H>(&mut self, handle: &H, mut callback: F) -> Subscription
3162 where
3163 E: Entity,
3164 H: Handle<E>,
3165 F: 'static + FnMut(&mut V, &E, &mut ViewContext<V>),
3166 {
3167 let window = self.window_handle;
3168 let observer = self.weak_handle();
3169 self.window_context
3170 .observe_release(handle, move |released, cx| {
3171 cx.update_window(window, |cx| {
3172 if let Some(observer) = observer.upgrade(cx) {
3173 observer.update(cx, |observer, cx| {
3174 callback(observer, released, cx);
3175 });
3176 }
3177 });
3178 })
3179 }
3180
3181 pub fn observe_actions<F>(&mut self, mut callback: F) -> Subscription
3182 where
3183 F: 'static + FnMut(&mut V, TypeId, &mut ViewContext<V>),
3184 {
3185 let window = self.window_handle;
3186 let observer = self.weak_handle();
3187 self.window_context.observe_actions(move |action_id, cx| {
3188 cx.update_window(window, |cx| {
3189 if let Some(observer) = observer.upgrade(cx) {
3190 observer.update(cx, |observer, cx| {
3191 callback(observer, action_id, cx);
3192 });
3193 }
3194 });
3195 })
3196 }
3197
3198 pub fn observe_window_activation<F>(&mut self, mut callback: F) -> Subscription
3199 where
3200 F: 'static + FnMut(&mut V, bool, &mut ViewContext<V>),
3201 {
3202 let observer = self.weak_handle();
3203 self.window_context
3204 .observe_window_activation(move |active, cx| {
3205 if let Some(observer) = observer.upgrade(cx) {
3206 observer.update(cx, |observer, cx| {
3207 callback(observer, active, cx);
3208 });
3209 true
3210 } else {
3211 false
3212 }
3213 })
3214 }
3215
3216 pub fn observe_fullscreen<F>(&mut self, mut callback: F) -> Subscription
3217 where
3218 F: 'static + FnMut(&mut V, bool, &mut ViewContext<V>),
3219 {
3220 let observer = self.weak_handle();
3221 self.window_context.observe_fullscreen(move |active, cx| {
3222 if let Some(observer) = observer.upgrade(cx) {
3223 observer.update(cx, |observer, cx| {
3224 callback(observer, active, cx);
3225 });
3226 true
3227 } else {
3228 false
3229 }
3230 })
3231 }
3232
3233 pub fn observe_keystrokes<F>(&mut self, mut callback: F) -> Subscription
3234 where
3235 F: 'static
3236 + FnMut(
3237 &mut V,
3238 &Keystroke,
3239 Option<&Box<dyn Action>>,
3240 &MatchResult,
3241 &mut ViewContext<V>,
3242 ) -> bool,
3243 {
3244 let observer = self.weak_handle();
3245 self.window_context
3246 .observe_keystrokes(move |keystroke, result, handled_by, cx| {
3247 if let Some(observer) = observer.upgrade(cx) {
3248 observer.update(cx, |observer, cx| {
3249 callback(observer, keystroke, handled_by, result, cx);
3250 });
3251 true
3252 } else {
3253 false
3254 }
3255 })
3256 }
3257
3258 pub fn observe_window_bounds<F>(&mut self, mut callback: F) -> Subscription
3259 where
3260 F: 'static + FnMut(&mut V, WindowBounds, Uuid, &mut ViewContext<V>),
3261 {
3262 let observer = self.weak_handle();
3263 self.window_context
3264 .observe_window_bounds(move |bounds, display, cx| {
3265 if let Some(observer) = observer.upgrade(cx) {
3266 observer.update(cx, |observer, cx| {
3267 callback(observer, bounds, display, cx);
3268 });
3269 true
3270 } else {
3271 false
3272 }
3273 })
3274 }
3275
3276 pub fn observe_active_labeled_tasks<F>(&mut self, mut callback: F) -> Subscription
3277 where
3278 F: 'static + FnMut(&mut V, &mut ViewContext<V>),
3279 {
3280 let window = self.window_handle;
3281 let observer = self.weak_handle();
3282 self.window_context.observe_active_labeled_tasks(move |cx| {
3283 cx.update_window(window, |cx| {
3284 if let Some(observer) = observer.upgrade(cx) {
3285 observer.update(cx, |observer, cx| {
3286 callback(observer, cx);
3287 });
3288 true
3289 } else {
3290 false
3291 }
3292 })
3293 .unwrap_or(false)
3294 })
3295 }
3296
3297 pub fn emit(&mut self, payload: V::Event) {
3298 self.window_context
3299 .pending_effects
3300 .push_back(Effect::Event {
3301 entity_id: self.view_id,
3302 payload: Box::new(payload),
3303 });
3304 }
3305
3306 pub fn notify(&mut self) {
3307 let window = self.window_handle;
3308 let view_id = self.view_id;
3309 self.window_context.notify_view(window, view_id);
3310 }
3311
3312 pub fn defer(&mut self, callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>)) {
3313 let handle = self.handle();
3314 self.window_context
3315 .defer(move |cx| handle.update(cx, |view, cx| callback(view, cx)))
3316 }
3317
3318 pub fn after_window_update(
3319 &mut self,
3320 callback: impl 'static + FnOnce(&mut V, &mut ViewContext<V>),
3321 ) {
3322 let window = self.window_handle;
3323 let handle = self.handle();
3324 self.window_context.after_window_update(move |cx| {
3325 cx.update_window(window, |cx| {
3326 handle.update(cx, |view, cx| {
3327 callback(view, cx);
3328 })
3329 });
3330 })
3331 }
3332
3333 pub fn propagate_action(&mut self) {
3334 self.window_context.halt_action_dispatch = false;
3335 }
3336
3337 pub fn spawn_labeled<F, Fut, S>(&mut self, task_label: &'static str, f: F) -> Task<S>
3338 where
3339 F: FnOnce(WeakViewHandle<V>, AsyncAppContext) -> Fut,
3340 Fut: 'static + Future<Output = S>,
3341 S: 'static,
3342 {
3343 let handle = self.weak_handle();
3344 self.window_context
3345 .spawn_labeled(task_label, |cx| f(handle, cx))
3346 }
3347
3348 pub fn spawn<F, Fut, S>(&mut self, f: F) -> Task<S>
3349 where
3350 F: FnOnce(WeakViewHandle<V>, AsyncAppContext) -> Fut,
3351 Fut: 'static + Future<Output = S>,
3352 S: 'static,
3353 {
3354 let handle = self.weak_handle();
3355 self.window_context.spawn(|cx| f(handle, cx))
3356 }
3357
3358 pub fn mouse_state<Tag: 'static>(&self, region_id: usize) -> MouseState {
3359 let region_id = MouseRegionId::new::<Tag>(self.view_id, region_id);
3360 MouseState {
3361 hovered: self.window.hovered_region_ids.contains(®ion_id),
3362 clicked: if let Some((clicked_region_id, button)) = self.window.clicked_region {
3363 if region_id == clicked_region_id {
3364 Some(button)
3365 } else {
3366 None
3367 }
3368 } else {
3369 None
3370 },
3371 accessed_hovered: false,
3372 accessed_clicked: false,
3373 }
3374 }
3375
3376 pub fn element_state<Tag: 'static, T: 'static>(
3377 &mut self,
3378 element_id: usize,
3379 initial: T,
3380 ) -> ElementStateHandle<T> {
3381 let id = ElementStateId {
3382 view_id: self.view_id(),
3383 element_id,
3384 tag: TypeId::of::<Tag>(),
3385 };
3386 self.element_states
3387 .entry(id)
3388 .or_insert_with(|| Box::new(initial));
3389 ElementStateHandle::new(id, self.frame_count, &self.ref_counts)
3390 }
3391
3392 pub fn default_element_state<Tag: 'static, T: 'static + Default>(
3393 &mut self,
3394 element_id: usize,
3395 ) -> ElementStateHandle<T> {
3396 self.element_state::<Tag, T>(element_id, T::default())
3397 }
3398}
3399
3400impl<V> BorrowAppContext for ViewContext<'_, '_, V> {
3401 fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
3402 BorrowAppContext::read_with(&*self.window_context, f)
3403 }
3404
3405 fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T {
3406 BorrowAppContext::update(&mut *self.window_context, f)
3407 }
3408}
3409
3410impl<V> BorrowWindowContext for ViewContext<'_, '_, V> {
3411 type Result<T> = T;
3412
3413 fn read_window<T, F: FnOnce(&WindowContext) -> T>(&self, window: AnyWindowHandle, f: F) -> T {
3414 BorrowWindowContext::read_window(&*self.window_context, window, f)
3415 }
3416
3417 fn read_window_optional<T, F>(&self, window: AnyWindowHandle, f: F) -> Option<T>
3418 where
3419 F: FnOnce(&WindowContext) -> Option<T>,
3420 {
3421 BorrowWindowContext::read_window_optional(&*self.window_context, window, f)
3422 }
3423
3424 fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
3425 &mut self,
3426 window: AnyWindowHandle,
3427 f: F,
3428 ) -> T {
3429 BorrowWindowContext::update_window(&mut *self.window_context, window, f)
3430 }
3431
3432 fn update_window_optional<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Option<T>
3433 where
3434 F: FnOnce(&mut WindowContext) -> Option<T>,
3435 {
3436 BorrowWindowContext::update_window_optional(&mut *self.window_context, window, f)
3437 }
3438}
3439
3440pub struct LayoutContext<'a, 'b, 'c, V: View> {
3441 view_context: &'c mut ViewContext<'a, 'b, V>,
3442 new_parents: &'c mut HashMap<usize, usize>,
3443 views_to_notify_if_ancestors_change: &'c mut HashMap<usize, SmallVec<[usize; 2]>>,
3444 pub refreshing: bool,
3445}
3446
3447impl<'a, 'b, 'c, V: View> LayoutContext<'a, 'b, 'c, V> {
3448 pub fn new(
3449 view_context: &'c mut ViewContext<'a, 'b, V>,
3450 new_parents: &'c mut HashMap<usize, usize>,
3451 views_to_notify_if_ancestors_change: &'c mut HashMap<usize, SmallVec<[usize; 2]>>,
3452 refreshing: bool,
3453 ) -> Self {
3454 Self {
3455 view_context,
3456 new_parents,
3457 views_to_notify_if_ancestors_change,
3458 refreshing,
3459 }
3460 }
3461
3462 pub fn view_context(&mut self) -> &mut ViewContext<'a, 'b, V> {
3463 self.view_context
3464 }
3465
3466 /// Return keystrokes that would dispatch the given action on the given view.
3467 pub(crate) fn keystrokes_for_action(
3468 &mut self,
3469 view_id: usize,
3470 action: &dyn Action,
3471 ) -> Option<SmallVec<[Keystroke; 2]>> {
3472 self.notify_if_view_ancestors_change(view_id);
3473
3474 let window = self.window_handle;
3475 let mut contexts = Vec::new();
3476 let mut handler_depth = None;
3477 for (i, view_id) in self.ancestors(view_id).enumerate() {
3478 if let Some(view_metadata) = self.views_metadata.get(&(window.id(), view_id)) {
3479 if let Some(actions) = self.actions.get(&view_metadata.type_id) {
3480 if actions.contains_key(&action.id()) {
3481 handler_depth = Some(i);
3482 }
3483 }
3484 contexts.push(view_metadata.keymap_context.clone());
3485 }
3486 }
3487
3488 if self.global_actions.contains_key(&action.id()) {
3489 handler_depth = Some(contexts.len())
3490 }
3491
3492 let action_contexts = if let Some(depth) = handler_depth {
3493 &contexts[depth..]
3494 } else {
3495 &contexts
3496 };
3497
3498 self.keystroke_matcher
3499 .keystrokes_for_action(action, action_contexts)
3500 }
3501
3502 fn notify_if_view_ancestors_change(&mut self, view_id: usize) {
3503 let self_view_id = self.view_id;
3504 self.views_to_notify_if_ancestors_change
3505 .entry(view_id)
3506 .or_default()
3507 .push(self_view_id);
3508 }
3509}
3510
3511impl<'a, 'b, 'c, V: View> Deref for LayoutContext<'a, 'b, 'c, V> {
3512 type Target = ViewContext<'a, 'b, V>;
3513
3514 fn deref(&self) -> &Self::Target {
3515 &self.view_context
3516 }
3517}
3518
3519impl<V: View> DerefMut for LayoutContext<'_, '_, '_, V> {
3520 fn deref_mut(&mut self) -> &mut Self::Target {
3521 &mut self.view_context
3522 }
3523}
3524
3525impl<V: View> BorrowAppContext for LayoutContext<'_, '_, '_, V> {
3526 fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
3527 BorrowAppContext::read_with(&*self.view_context, f)
3528 }
3529
3530 fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T {
3531 BorrowAppContext::update(&mut *self.view_context, f)
3532 }
3533}
3534
3535impl<V: View> BorrowWindowContext for LayoutContext<'_, '_, '_, V> {
3536 type Result<T> = T;
3537
3538 fn read_window<T, F: FnOnce(&WindowContext) -> T>(&self, window: AnyWindowHandle, f: F) -> T {
3539 BorrowWindowContext::read_window(&*self.view_context, window, f)
3540 }
3541
3542 fn read_window_optional<T, F>(&self, window: AnyWindowHandle, f: F) -> Option<T>
3543 where
3544 F: FnOnce(&WindowContext) -> Option<T>,
3545 {
3546 BorrowWindowContext::read_window_optional(&*self.view_context, window, f)
3547 }
3548
3549 fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
3550 &mut self,
3551 window: AnyWindowHandle,
3552 f: F,
3553 ) -> T {
3554 BorrowWindowContext::update_window(&mut *self.view_context, window, f)
3555 }
3556
3557 fn update_window_optional<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Option<T>
3558 where
3559 F: FnOnce(&mut WindowContext) -> Option<T>,
3560 {
3561 BorrowWindowContext::update_window_optional(&mut *self.view_context, window, f)
3562 }
3563}
3564
3565pub struct EventContext<'a, 'b, 'c, V: View> {
3566 view_context: &'c mut ViewContext<'a, 'b, V>,
3567 pub(crate) handled: bool,
3568}
3569
3570impl<'a, 'b, 'c, V: View> EventContext<'a, 'b, 'c, V> {
3571 pub(crate) fn new(view_context: &'c mut ViewContext<'a, 'b, V>) -> Self {
3572 EventContext {
3573 view_context,
3574 handled: true,
3575 }
3576 }
3577
3578 pub fn propagate_event(&mut self) {
3579 self.handled = false;
3580 }
3581}
3582
3583impl<'a, 'b, 'c, V: View> Deref for EventContext<'a, 'b, 'c, V> {
3584 type Target = ViewContext<'a, 'b, V>;
3585
3586 fn deref(&self) -> &Self::Target {
3587 &self.view_context
3588 }
3589}
3590
3591impl<V: View> DerefMut for EventContext<'_, '_, '_, V> {
3592 fn deref_mut(&mut self) -> &mut Self::Target {
3593 &mut self.view_context
3594 }
3595}
3596
3597impl<V: View> BorrowAppContext for EventContext<'_, '_, '_, V> {
3598 fn read_with<T, F: FnOnce(&AppContext) -> T>(&self, f: F) -> T {
3599 BorrowAppContext::read_with(&*self.view_context, f)
3600 }
3601
3602 fn update<T, F: FnOnce(&mut AppContext) -> T>(&mut self, f: F) -> T {
3603 BorrowAppContext::update(&mut *self.view_context, f)
3604 }
3605}
3606
3607impl<V: View> BorrowWindowContext for EventContext<'_, '_, '_, V> {
3608 type Result<T> = T;
3609
3610 fn read_window<T, F: FnOnce(&WindowContext) -> T>(&self, window: AnyWindowHandle, f: F) -> T {
3611 BorrowWindowContext::read_window(&*self.view_context, window, f)
3612 }
3613
3614 fn read_window_optional<T, F>(&self, window: AnyWindowHandle, f: F) -> Option<T>
3615 where
3616 F: FnOnce(&WindowContext) -> Option<T>,
3617 {
3618 BorrowWindowContext::read_window_optional(&*self.view_context, window, f)
3619 }
3620
3621 fn update_window<T, F: FnOnce(&mut WindowContext) -> T>(
3622 &mut self,
3623 window: AnyWindowHandle,
3624 f: F,
3625 ) -> T {
3626 BorrowWindowContext::update_window(&mut *self.view_context, window, f)
3627 }
3628
3629 fn update_window_optional<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Option<T>
3630 where
3631 F: FnOnce(&mut WindowContext) -> Option<T>,
3632 {
3633 BorrowWindowContext::update_window_optional(&mut *self.view_context, window, f)
3634 }
3635}
3636
3637pub(crate) enum Reference<'a, T> {
3638 Immutable(&'a T),
3639 Mutable(&'a mut T),
3640}
3641
3642impl<'a, T> Deref for Reference<'a, T> {
3643 type Target = T;
3644
3645 fn deref(&self) -> &Self::Target {
3646 match self {
3647 Reference::Immutable(target) => target,
3648 Reference::Mutable(target) => target,
3649 }
3650 }
3651}
3652
3653impl<'a, T> DerefMut for Reference<'a, T> {
3654 fn deref_mut(&mut self) -> &mut Self::Target {
3655 match self {
3656 Reference::Immutable(_) => {
3657 panic!("cannot mutably deref an immutable reference. this is a bug in GPUI.");
3658 }
3659 Reference::Mutable(target) => target,
3660 }
3661 }
3662}
3663
3664#[derive(Debug, Clone, Default)]
3665pub struct MouseState {
3666 pub(crate) hovered: bool,
3667 pub(crate) clicked: Option<MouseButton>,
3668 pub(crate) accessed_hovered: bool,
3669 pub(crate) accessed_clicked: bool,
3670}
3671
3672impl MouseState {
3673 pub fn hovered(&mut self) -> bool {
3674 self.accessed_hovered = true;
3675 self.hovered
3676 }
3677
3678 pub fn clicked(&mut self) -> Option<MouseButton> {
3679 self.accessed_clicked = true;
3680 self.clicked
3681 }
3682
3683 pub fn accessed_hovered(&self) -> bool {
3684 self.accessed_hovered
3685 }
3686
3687 pub fn accessed_clicked(&self) -> bool {
3688 self.accessed_clicked
3689 }
3690}
3691
3692pub trait Handle<T> {
3693 type Weak: 'static;
3694 fn id(&self) -> usize;
3695 fn location(&self) -> EntityLocation;
3696 fn downgrade(&self) -> Self::Weak;
3697 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3698 where
3699 Self: Sized;
3700}
3701
3702pub trait WeakHandle {
3703 fn id(&self) -> usize;
3704}
3705
3706#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
3707pub enum EntityLocation {
3708 Model(usize),
3709 View(usize, usize),
3710}
3711
3712pub struct ModelHandle<T: Entity> {
3713 any_handle: AnyModelHandle,
3714 model_type: PhantomData<T>,
3715}
3716
3717impl<T: Entity> Deref for ModelHandle<T> {
3718 type Target = AnyModelHandle;
3719
3720 fn deref(&self) -> &Self::Target {
3721 &self.any_handle
3722 }
3723}
3724
3725impl<T: Entity> ModelHandle<T> {
3726 fn new(model_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
3727 Self {
3728 any_handle: AnyModelHandle::new(model_id, TypeId::of::<T>(), ref_counts.clone()),
3729 model_type: PhantomData,
3730 }
3731 }
3732
3733 pub fn downgrade(&self) -> WeakModelHandle<T> {
3734 WeakModelHandle::new(self.model_id)
3735 }
3736
3737 pub fn id(&self) -> usize {
3738 self.model_id
3739 }
3740
3741 pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
3742 cx.read_model(self)
3743 }
3744
3745 pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> S
3746 where
3747 C: BorrowAppContext,
3748 F: FnOnce(&T, &AppContext) -> S,
3749 {
3750 cx.read_with(|cx| read(self.read(cx), cx))
3751 }
3752
3753 pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> S
3754 where
3755 C: BorrowAppContext,
3756 F: FnOnce(&mut T, &mut ModelContext<T>) -> S,
3757 {
3758 let mut update = Some(update);
3759 cx.update(|cx| {
3760 cx.update_model(self, &mut |model, cx| {
3761 let update = update.take().unwrap();
3762 update(model, cx)
3763 })
3764 })
3765 }
3766}
3767
3768impl<T: Entity> Clone for ModelHandle<T> {
3769 fn clone(&self) -> Self {
3770 Self::new(self.model_id, &self.ref_counts)
3771 }
3772}
3773
3774impl<T: Entity> PartialEq for ModelHandle<T> {
3775 fn eq(&self, other: &Self) -> bool {
3776 self.model_id == other.model_id
3777 }
3778}
3779
3780impl<T: Entity> Eq for ModelHandle<T> {}
3781
3782impl<T: Entity> PartialEq<WeakModelHandle<T>> for ModelHandle<T> {
3783 fn eq(&self, other: &WeakModelHandle<T>) -> bool {
3784 self.model_id == other.model_id
3785 }
3786}
3787
3788impl<T: Entity> Hash for ModelHandle<T> {
3789 fn hash<H: Hasher>(&self, state: &mut H) {
3790 self.model_id.hash(state);
3791 }
3792}
3793
3794impl<T: Entity> std::borrow::Borrow<usize> for ModelHandle<T> {
3795 fn borrow(&self) -> &usize {
3796 &self.model_id
3797 }
3798}
3799
3800impl<T: Entity> Debug for ModelHandle<T> {
3801 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3802 f.debug_tuple(&format!("ModelHandle<{}>", type_name::<T>()))
3803 .field(&self.model_id)
3804 .finish()
3805 }
3806}
3807
3808unsafe impl<T: Entity> Send for ModelHandle<T> {}
3809unsafe impl<T: Entity> Sync for ModelHandle<T> {}
3810
3811impl<T: Entity> Handle<T> for ModelHandle<T> {
3812 type Weak = WeakModelHandle<T>;
3813
3814 fn id(&self) -> usize {
3815 self.model_id
3816 }
3817
3818 fn location(&self) -> EntityLocation {
3819 EntityLocation::Model(self.model_id)
3820 }
3821
3822 fn downgrade(&self) -> Self::Weak {
3823 self.downgrade()
3824 }
3825
3826 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3827 where
3828 Self: Sized,
3829 {
3830 weak.upgrade(cx)
3831 }
3832}
3833
3834pub struct WeakModelHandle<T> {
3835 any_handle: AnyWeakModelHandle,
3836 model_type: PhantomData<T>,
3837}
3838
3839impl<T> WeakModelHandle<T> {
3840 pub fn into_any(self) -> AnyWeakModelHandle {
3841 self.any_handle
3842 }
3843}
3844
3845impl<T> Deref for WeakModelHandle<T> {
3846 type Target = AnyWeakModelHandle;
3847
3848 fn deref(&self) -> &Self::Target {
3849 &self.any_handle
3850 }
3851}
3852
3853impl<T> WeakHandle for WeakModelHandle<T> {
3854 fn id(&self) -> usize {
3855 self.model_id
3856 }
3857}
3858
3859unsafe impl<T> Send for WeakModelHandle<T> {}
3860unsafe impl<T> Sync for WeakModelHandle<T> {}
3861
3862impl<T: Entity> WeakModelHandle<T> {
3863 fn new(model_id: usize) -> Self {
3864 Self {
3865 any_handle: AnyWeakModelHandle {
3866 model_id,
3867 model_type: TypeId::of::<T>(),
3868 },
3869 model_type: PhantomData,
3870 }
3871 }
3872
3873 pub fn id(&self) -> usize {
3874 self.model_id
3875 }
3876
3877 pub fn is_upgradable(&self, cx: &impl BorrowAppContext) -> bool {
3878 cx.read_with(|cx| cx.model_handle_is_upgradable(self))
3879 }
3880
3881 pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option<ModelHandle<T>> {
3882 cx.read_with(|cx| cx.upgrade_model_handle(self))
3883 }
3884}
3885
3886impl<T> Hash for WeakModelHandle<T> {
3887 fn hash<H: Hasher>(&self, state: &mut H) {
3888 self.model_id.hash(state)
3889 }
3890}
3891
3892impl<T> PartialEq for WeakModelHandle<T> {
3893 fn eq(&self, other: &Self) -> bool {
3894 self.model_id == other.model_id
3895 }
3896}
3897
3898impl<T> Eq for WeakModelHandle<T> {}
3899
3900impl<T: Entity> PartialEq<ModelHandle<T>> for WeakModelHandle<T> {
3901 fn eq(&self, other: &ModelHandle<T>) -> bool {
3902 self.model_id == other.model_id
3903 }
3904}
3905
3906impl<T> Clone for WeakModelHandle<T> {
3907 fn clone(&self) -> Self {
3908 Self {
3909 any_handle: self.any_handle.clone(),
3910 model_type: PhantomData,
3911 }
3912 }
3913}
3914
3915impl<T> Copy for WeakModelHandle<T> {}
3916
3917#[derive(Deref)]
3918pub struct WindowHandle<V> {
3919 #[deref]
3920 any_handle: AnyWindowHandle,
3921 root_view_type: PhantomData<V>,
3922}
3923
3924impl<V> Clone for WindowHandle<V> {
3925 fn clone(&self) -> Self {
3926 Self {
3927 any_handle: self.any_handle.clone(),
3928 root_view_type: PhantomData,
3929 }
3930 }
3931}
3932
3933impl<V> Copy for WindowHandle<V> {}
3934
3935impl<V: View> WindowHandle<V> {
3936 fn new(window_id: usize) -> Self {
3937 WindowHandle {
3938 any_handle: AnyWindowHandle {
3939 window_id,
3940 root_view_type: TypeId::of::<V>(),
3941 },
3942 root_view_type: PhantomData,
3943 }
3944 }
3945
3946 pub fn root<C: BorrowWindowContext>(&self, cx: &C) -> C::Result<ViewHandle<V>> {
3947 self.read_with(cx, |cx| cx.root_view().clone().downcast().unwrap())
3948 }
3949
3950 pub fn read_root_with<C, F, R>(&self, cx: &C, read: F) -> C::Result<R>
3951 where
3952 C: BorrowWindowContext,
3953 F: FnOnce(&V, &ViewContext<V>) -> R,
3954 {
3955 self.read_with(cx, |cx| {
3956 cx.root_view()
3957 .downcast_ref::<V>()
3958 .unwrap()
3959 .read_with(cx, read)
3960 })
3961 }
3962
3963 pub fn update_root<C, F, R>(&self, cx: &mut C, update: F) -> C::Result<R>
3964 where
3965 C: BorrowWindowContext,
3966 F: FnOnce(&mut V, &mut ViewContext<V>) -> R,
3967 {
3968 cx.update_window(self.any_handle, |cx| {
3969 cx.root_view()
3970 .clone()
3971 .downcast::<V>()
3972 .unwrap()
3973 .update(cx, update)
3974 })
3975 }
3976
3977 pub fn replace_root<C, F>(&self, cx: &mut C, build_root: F) -> C::Result<ViewHandle<V>>
3978 where
3979 C: BorrowWindowContext,
3980 F: FnOnce(&mut ViewContext<V>) -> V,
3981 {
3982 cx.update_window(self.any_handle, |cx| {
3983 let root_view = self.add_view(cx, |cx| build_root(cx));
3984 cx.window.root_view = Some(root_view.clone().into_any());
3985 cx.window.focused_view_id = Some(root_view.id());
3986 root_view
3987 })
3988 }
3989}
3990
3991impl<V> Into<AnyWindowHandle> for WindowHandle<V> {
3992 fn into(self) -> AnyWindowHandle {
3993 self.any_handle
3994 }
3995}
3996
3997#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
3998pub struct AnyWindowHandle {
3999 window_id: usize,
4000 root_view_type: TypeId,
4001}
4002
4003impl AnyWindowHandle {
4004 fn new(window_id: usize, root_view_type: TypeId) -> Self {
4005 Self {
4006 window_id,
4007 root_view_type,
4008 }
4009 }
4010
4011 pub fn id(&self) -> usize {
4012 self.window_id
4013 }
4014
4015 pub fn read_with<C, F, R>(&self, cx: &C, read: F) -> C::Result<R>
4016 where
4017 C: BorrowWindowContext,
4018 F: FnOnce(&WindowContext) -> R,
4019 {
4020 cx.read_window(*self, |cx| read(cx))
4021 }
4022
4023 pub fn read_optional_with<C, F, R>(&self, cx: &C, read: F) -> Option<R>
4024 where
4025 C: BorrowWindowContext,
4026 F: FnOnce(&WindowContext) -> Option<R>,
4027 {
4028 cx.read_window_optional(*self, |cx| read(cx))
4029 }
4030
4031 pub fn update<C, F, R>(&self, cx: &mut C, update: F) -> C::Result<R>
4032 where
4033 C: BorrowWindowContext,
4034 F: FnOnce(&mut WindowContext) -> R,
4035 {
4036 cx.update_window(*self, update)
4037 }
4038
4039 pub fn update_optional<C, F, R>(&self, cx: &mut C, update: F) -> Option<R>
4040 where
4041 C: BorrowWindowContext,
4042 F: FnOnce(&mut WindowContext) -> Option<R>,
4043 {
4044 cx.update_window_optional(*self, update)
4045 }
4046
4047 pub fn add_view<C, U, F>(&self, cx: &mut C, build_view: F) -> C::Result<ViewHandle<U>>
4048 where
4049 C: BorrowWindowContext,
4050 U: View,
4051 F: FnOnce(&mut ViewContext<U>) -> U,
4052 {
4053 self.update(cx, |cx| cx.add_view(build_view))
4054 }
4055
4056 pub fn downcast<V: View>(self) -> Option<WindowHandle<V>> {
4057 if self.root_view_type == TypeId::of::<V>() {
4058 Some(WindowHandle {
4059 any_handle: self,
4060 root_view_type: PhantomData,
4061 })
4062 } else {
4063 None
4064 }
4065 }
4066
4067 pub fn root_is<V: View>(&self) -> bool {
4068 self.root_view_type == TypeId::of::<V>()
4069 }
4070
4071 pub fn is_active<C: BorrowWindowContext>(&self, cx: &C) -> C::Result<bool> {
4072 self.read_with(cx, |cx| cx.window.is_active)
4073 }
4074
4075 pub fn remove<C: BorrowWindowContext>(&self, cx: &mut C) -> C::Result<()> {
4076 self.update(cx, |cx| cx.remove_window())
4077 }
4078
4079 #[cfg(any(test, feature = "test-support"))]
4080 pub fn simulate_activation(&self, cx: &mut TestAppContext) {
4081 self.update(cx, |cx| {
4082 let other_window_ids = cx
4083 .windows()
4084 .filter(|window| *window != *self)
4085 .collect::<Vec<_>>();
4086
4087 for window in other_window_ids {
4088 cx.window_changed_active_status(window, false)
4089 }
4090
4091 cx.window_changed_active_status(*self, true)
4092 });
4093 }
4094
4095 #[cfg(any(test, feature = "test-support"))]
4096 pub fn simulate_deactivation(&self, cx: &mut TestAppContext) {
4097 self.update(cx, |cx| {
4098 cx.window_changed_active_status(*self, false);
4099 })
4100 }
4101}
4102
4103#[repr(transparent)]
4104pub struct ViewHandle<T> {
4105 any_handle: AnyViewHandle,
4106 view_type: PhantomData<T>,
4107}
4108
4109impl<T> Deref for ViewHandle<T> {
4110 type Target = AnyViewHandle;
4111
4112 fn deref(&self) -> &Self::Target {
4113 &self.any_handle
4114 }
4115}
4116
4117impl<T: View> ViewHandle<T> {
4118 fn new(window: AnyWindowHandle, view_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4119 Self {
4120 any_handle: AnyViewHandle::new(window, view_id, TypeId::of::<T>(), ref_counts.clone()),
4121 view_type: PhantomData,
4122 }
4123 }
4124
4125 pub fn downgrade(&self) -> WeakViewHandle<T> {
4126 WeakViewHandle::new(self.window, self.view_id)
4127 }
4128
4129 pub fn into_any(self) -> AnyViewHandle {
4130 self.any_handle
4131 }
4132
4133 pub fn window(&self) -> AnyWindowHandle {
4134 self.window
4135 }
4136
4137 pub fn id(&self) -> usize {
4138 self.view_id
4139 }
4140
4141 pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
4142 cx.read_view(self)
4143 }
4144
4145 pub fn read_with<C, F, S>(&self, cx: &C, read: F) -> C::Result<S>
4146 where
4147 C: BorrowWindowContext,
4148 F: FnOnce(&T, &ViewContext<T>) -> S,
4149 {
4150 cx.read_window(self.window, |cx| {
4151 let cx = ViewContext::immutable(cx, self.view_id);
4152 read(cx.read_view(self), &cx)
4153 })
4154 }
4155
4156 pub fn update<C, F, S>(&self, cx: &mut C, update: F) -> C::Result<S>
4157 where
4158 C: BorrowWindowContext,
4159 F: FnOnce(&mut T, &mut ViewContext<T>) -> S,
4160 {
4161 let mut update = Some(update);
4162
4163 cx.update_window(self.window, |cx| {
4164 cx.update_view(self, &mut |view, cx| {
4165 let update = update.take().unwrap();
4166 update(view, cx)
4167 })
4168 })
4169 }
4170
4171 pub fn is_focused(&self, cx: &WindowContext) -> bool {
4172 cx.focused_view_id() == Some(self.view_id)
4173 }
4174}
4175
4176impl<T: View> Clone for ViewHandle<T> {
4177 fn clone(&self) -> Self {
4178 ViewHandle::new(self.window, self.view_id, &self.ref_counts)
4179 }
4180}
4181
4182impl<T> PartialEq for ViewHandle<T> {
4183 fn eq(&self, other: &Self) -> bool {
4184 self.window == other.window && self.view_id == other.view_id
4185 }
4186}
4187
4188impl<T> PartialEq<AnyViewHandle> for ViewHandle<T> {
4189 fn eq(&self, other: &AnyViewHandle) -> bool {
4190 self.window == other.window && self.view_id == other.view_id
4191 }
4192}
4193
4194impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
4195 fn eq(&self, other: &WeakViewHandle<T>) -> bool {
4196 self.window == other.window && self.view_id == other.view_id
4197 }
4198}
4199
4200impl<T> PartialEq<ViewHandle<T>> for WeakViewHandle<T> {
4201 fn eq(&self, other: &ViewHandle<T>) -> bool {
4202 self.window == other.window && self.view_id == other.view_id
4203 }
4204}
4205
4206impl<T> Eq for ViewHandle<T> {}
4207
4208impl<T> Hash for ViewHandle<T> {
4209 fn hash<H: Hasher>(&self, state: &mut H) {
4210 self.window.hash(state);
4211 self.view_id.hash(state);
4212 }
4213}
4214
4215impl<T> Debug for ViewHandle<T> {
4216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4217 f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
4218 .field("window_id", &self.window)
4219 .field("view_id", &self.view_id)
4220 .finish()
4221 }
4222}
4223
4224impl<T: View> Handle<T> for ViewHandle<T> {
4225 type Weak = WeakViewHandle<T>;
4226
4227 fn id(&self) -> usize {
4228 self.view_id
4229 }
4230
4231 fn location(&self) -> EntityLocation {
4232 EntityLocation::View(self.window.id(), self.view_id)
4233 }
4234
4235 fn downgrade(&self) -> Self::Weak {
4236 self.downgrade()
4237 }
4238
4239 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
4240 where
4241 Self: Sized,
4242 {
4243 weak.upgrade(cx)
4244 }
4245}
4246
4247pub struct AnyViewHandle {
4248 window: AnyWindowHandle,
4249 view_id: usize,
4250 view_type: TypeId,
4251 ref_counts: Arc<Mutex<RefCounts>>,
4252
4253 #[cfg(any(test, feature = "test-support"))]
4254 handle_id: usize,
4255}
4256
4257impl AnyViewHandle {
4258 fn new(
4259 window: AnyWindowHandle,
4260 view_id: usize,
4261 view_type: TypeId,
4262 ref_counts: Arc<Mutex<RefCounts>>,
4263 ) -> Self {
4264 ref_counts.lock().inc_view(window.id(), view_id);
4265
4266 #[cfg(any(test, feature = "test-support"))]
4267 let handle_id = ref_counts
4268 .lock()
4269 .leak_detector
4270 .lock()
4271 .handle_created(None, view_id);
4272
4273 Self {
4274 window,
4275 view_id,
4276 view_type,
4277 ref_counts,
4278 #[cfg(any(test, feature = "test-support"))]
4279 handle_id,
4280 }
4281 }
4282
4283 pub fn window(&self) -> AnyWindowHandle {
4284 self.window
4285 }
4286
4287 pub fn window_id(&self) -> usize {
4288 self.window.id()
4289 }
4290
4291 pub fn id(&self) -> usize {
4292 self.view_id
4293 }
4294
4295 pub fn is<T: 'static>(&self) -> bool {
4296 TypeId::of::<T>() == self.view_type
4297 }
4298
4299 pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
4300 if self.is::<T>() {
4301 Some(ViewHandle {
4302 any_handle: self,
4303 view_type: PhantomData,
4304 })
4305 } else {
4306 None
4307 }
4308 }
4309
4310 pub fn downcast_ref<T: View>(&self) -> Option<&ViewHandle<T>> {
4311 if self.is::<T>() {
4312 Some(unsafe { mem::transmute(self) })
4313 } else {
4314 None
4315 }
4316 }
4317
4318 pub fn downgrade(&self) -> AnyWeakViewHandle {
4319 AnyWeakViewHandle {
4320 window: self.window,
4321 view_id: self.view_id,
4322 view_type: self.view_type,
4323 }
4324 }
4325
4326 pub fn view_type(&self) -> TypeId {
4327 self.view_type
4328 }
4329
4330 pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a>) -> serde_json::Value {
4331 cx.views
4332 .get(&(self.window.id(), self.view_id))
4333 .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
4334 }
4335}
4336
4337impl Clone for AnyViewHandle {
4338 fn clone(&self) -> Self {
4339 Self::new(
4340 self.window,
4341 self.view_id,
4342 self.view_type,
4343 self.ref_counts.clone(),
4344 )
4345 }
4346}
4347
4348impl PartialEq for AnyViewHandle {
4349 fn eq(&self, other: &Self) -> bool {
4350 self.window == other.window && self.view_id == other.view_id
4351 }
4352}
4353
4354impl<T> PartialEq<ViewHandle<T>> for AnyViewHandle {
4355 fn eq(&self, other: &ViewHandle<T>) -> bool {
4356 self.window == other.window && self.view_id == other.view_id
4357 }
4358}
4359
4360impl Drop for AnyViewHandle {
4361 fn drop(&mut self) {
4362 self.ref_counts
4363 .lock()
4364 .dec_view(self.window.id(), self.view_id);
4365 #[cfg(any(test, feature = "test-support"))]
4366 self.ref_counts
4367 .lock()
4368 .leak_detector
4369 .lock()
4370 .handle_dropped(self.view_id, self.handle_id);
4371 }
4372}
4373
4374impl Debug for AnyViewHandle {
4375 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4376 f.debug_struct("AnyViewHandle")
4377 .field("window_id", &self.window.id())
4378 .field("view_id", &self.view_id)
4379 .finish()
4380 }
4381}
4382
4383pub struct AnyModelHandle {
4384 model_id: usize,
4385 model_type: TypeId,
4386 ref_counts: Arc<Mutex<RefCounts>>,
4387
4388 #[cfg(any(test, feature = "test-support"))]
4389 handle_id: usize,
4390}
4391
4392impl AnyModelHandle {
4393 fn new(model_id: usize, model_type: TypeId, ref_counts: Arc<Mutex<RefCounts>>) -> Self {
4394 ref_counts.lock().inc_model(model_id);
4395
4396 #[cfg(any(test, feature = "test-support"))]
4397 let handle_id = ref_counts
4398 .lock()
4399 .leak_detector
4400 .lock()
4401 .handle_created(None, model_id);
4402
4403 Self {
4404 model_id,
4405 model_type,
4406 ref_counts,
4407
4408 #[cfg(any(test, feature = "test-support"))]
4409 handle_id,
4410 }
4411 }
4412
4413 pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
4414 if self.is::<T>() {
4415 Some(ModelHandle {
4416 any_handle: self,
4417 model_type: PhantomData,
4418 })
4419 } else {
4420 None
4421 }
4422 }
4423
4424 pub fn downgrade(&self) -> AnyWeakModelHandle {
4425 AnyWeakModelHandle {
4426 model_id: self.model_id,
4427 model_type: self.model_type,
4428 }
4429 }
4430
4431 pub fn is<T: Entity>(&self) -> bool {
4432 self.model_type == TypeId::of::<T>()
4433 }
4434
4435 pub fn model_type(&self) -> TypeId {
4436 self.model_type
4437 }
4438}
4439
4440impl Clone for AnyModelHandle {
4441 fn clone(&self) -> Self {
4442 Self::new(self.model_id, self.model_type, self.ref_counts.clone())
4443 }
4444}
4445
4446impl Drop for AnyModelHandle {
4447 fn drop(&mut self) {
4448 let mut ref_counts = self.ref_counts.lock();
4449 ref_counts.dec_model(self.model_id);
4450
4451 #[cfg(any(test, feature = "test-support"))]
4452 ref_counts
4453 .leak_detector
4454 .lock()
4455 .handle_dropped(self.model_id, self.handle_id);
4456 }
4457}
4458
4459#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)]
4460pub struct AnyWeakModelHandle {
4461 model_id: usize,
4462 model_type: TypeId,
4463}
4464
4465impl AnyWeakModelHandle {
4466 pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option<AnyModelHandle> {
4467 cx.read_with(|cx| cx.upgrade_any_model_handle(self))
4468 }
4469
4470 pub fn model_type(&self) -> TypeId {
4471 self.model_type
4472 }
4473
4474 fn is<T: 'static>(&self) -> bool {
4475 TypeId::of::<T>() == self.model_type
4476 }
4477
4478 pub fn downcast<T: Entity>(self) -> Option<WeakModelHandle<T>> {
4479 if self.is::<T>() {
4480 let result = Some(WeakModelHandle {
4481 any_handle: self,
4482 model_type: PhantomData,
4483 });
4484
4485 result
4486 } else {
4487 None
4488 }
4489 }
4490}
4491
4492#[derive(Copy)]
4493pub struct WeakViewHandle<T> {
4494 any_handle: AnyWeakViewHandle,
4495 view_type: PhantomData<T>,
4496}
4497
4498impl<T> Debug for WeakViewHandle<T> {
4499 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4500 f.debug_struct(&format!("WeakViewHandle<{}>", type_name::<T>()))
4501 .field("any_handle", &self.any_handle)
4502 .finish()
4503 }
4504}
4505
4506impl<T> WeakHandle for WeakViewHandle<T> {
4507 fn id(&self) -> usize {
4508 self.view_id
4509 }
4510}
4511
4512impl<V: View> WeakViewHandle<V> {
4513 fn new(window: AnyWindowHandle, view_id: usize) -> Self {
4514 Self {
4515 any_handle: AnyWeakViewHandle {
4516 window,
4517 view_id,
4518 view_type: TypeId::of::<V>(),
4519 },
4520 view_type: PhantomData,
4521 }
4522 }
4523
4524 pub fn id(&self) -> usize {
4525 self.view_id
4526 }
4527
4528 pub fn window(&self) -> AnyWindowHandle {
4529 self.window
4530 }
4531
4532 pub fn window_id(&self) -> usize {
4533 self.window.id()
4534 }
4535
4536 pub fn into_any(self) -> AnyWeakViewHandle {
4537 self.any_handle
4538 }
4539
4540 pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option<ViewHandle<V>> {
4541 cx.read_with(|cx| cx.upgrade_view_handle(self))
4542 }
4543
4544 pub fn read_with<T>(
4545 &self,
4546 cx: &AsyncAppContext,
4547 read: impl FnOnce(&V, &ViewContext<V>) -> T,
4548 ) -> Result<T> {
4549 cx.read(|cx| {
4550 let handle = cx
4551 .upgrade_view_handle(self)
4552 .ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?;
4553 cx.read_window(self.window, |cx| handle.read_with(cx, read))
4554 .ok_or_else(|| anyhow!("window was removed"))
4555 })
4556 }
4557
4558 pub fn update<T>(
4559 &self,
4560 cx: &mut AsyncAppContext,
4561 update: impl FnOnce(&mut V, &mut ViewContext<V>) -> T,
4562 ) -> Result<T> {
4563 cx.update(|cx| {
4564 let handle = cx
4565 .upgrade_view_handle(self)
4566 .ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?;
4567 cx.update_window(self.window, |cx| handle.update(cx, update))
4568 .ok_or_else(|| anyhow!("window was removed"))
4569 })
4570 }
4571}
4572
4573impl<T> Deref for WeakViewHandle<T> {
4574 type Target = AnyWeakViewHandle;
4575
4576 fn deref(&self) -> &Self::Target {
4577 &self.any_handle
4578 }
4579}
4580
4581impl<T> Clone for WeakViewHandle<T> {
4582 fn clone(&self) -> Self {
4583 Self {
4584 any_handle: self.any_handle.clone(),
4585 view_type: PhantomData,
4586 }
4587 }
4588}
4589
4590impl<T> PartialEq for WeakViewHandle<T> {
4591 fn eq(&self, other: &Self) -> bool {
4592 self.window == other.window && self.view_id == other.view_id
4593 }
4594}
4595
4596impl<T> Eq for WeakViewHandle<T> {}
4597
4598impl<T> Hash for WeakViewHandle<T> {
4599 fn hash<H: Hasher>(&self, state: &mut H) {
4600 self.any_handle.hash(state);
4601 }
4602}
4603
4604#[derive(Debug, Clone, Copy, Eq, PartialEq)]
4605pub struct AnyWeakViewHandle {
4606 window: AnyWindowHandle,
4607 view_id: usize,
4608 view_type: TypeId,
4609}
4610
4611impl AnyWeakViewHandle {
4612 pub fn id(&self) -> usize {
4613 self.view_id
4614 }
4615
4616 fn is<T: 'static>(&self) -> bool {
4617 TypeId::of::<T>() == self.view_type
4618 }
4619
4620 pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option<AnyViewHandle> {
4621 cx.read_with(|cx| cx.upgrade_any_view_handle(self))
4622 }
4623
4624 pub fn downcast<T: View>(self) -> Option<WeakViewHandle<T>> {
4625 if self.is::<T>() {
4626 Some(WeakViewHandle {
4627 any_handle: self,
4628 view_type: PhantomData,
4629 })
4630 } else {
4631 None
4632 }
4633 }
4634}
4635
4636impl Hash for AnyWeakViewHandle {
4637 fn hash<H: Hasher>(&self, state: &mut H) {
4638 self.window.hash(state);
4639 self.view_id.hash(state);
4640 self.view_type.hash(state);
4641 }
4642}
4643
4644#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4645pub struct ElementStateId {
4646 view_id: usize,
4647 element_id: usize,
4648 tag: TypeId,
4649}
4650
4651pub struct ElementStateHandle<T> {
4652 value_type: PhantomData<T>,
4653 id: ElementStateId,
4654 ref_counts: Weak<Mutex<RefCounts>>,
4655}
4656
4657impl<T: 'static> ElementStateHandle<T> {
4658 fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4659 ref_counts.lock().inc_element_state(id, frame_id);
4660 Self {
4661 value_type: PhantomData,
4662 id,
4663 ref_counts: Arc::downgrade(ref_counts),
4664 }
4665 }
4666
4667 pub fn id(&self) -> ElementStateId {
4668 self.id
4669 }
4670
4671 pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
4672 cx.element_states
4673 .get(&self.id)
4674 .unwrap()
4675 .downcast_ref()
4676 .unwrap()
4677 }
4678
4679 pub fn update<C, D, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
4680 where
4681 C: DerefMut<Target = D>,
4682 D: DerefMut<Target = AppContext>,
4683 {
4684 let mut element_state = cx.deref_mut().element_states.remove(&self.id).unwrap();
4685 let result = f(element_state.downcast_mut().unwrap(), cx);
4686 cx.deref_mut().element_states.insert(self.id, element_state);
4687 result
4688 }
4689}
4690
4691impl<T> Drop for ElementStateHandle<T> {
4692 fn drop(&mut self) {
4693 if let Some(ref_counts) = self.ref_counts.upgrade() {
4694 ref_counts.lock().dec_element_state(self.id);
4695 }
4696 }
4697}
4698
4699#[must_use]
4700pub enum Subscription {
4701 Subscription(callback_collection::Subscription<usize, SubscriptionCallback>),
4702 Observation(callback_collection::Subscription<usize, ObservationCallback>),
4703 GlobalSubscription(callback_collection::Subscription<TypeId, GlobalSubscriptionCallback>),
4704 GlobalObservation(callback_collection::Subscription<TypeId, GlobalObservationCallback>),
4705 FocusObservation(callback_collection::Subscription<usize, FocusObservationCallback>),
4706 WindowActivationObservation(callback_collection::Subscription<usize, WindowActivationCallback>),
4707 WindowFullscreenObservation(callback_collection::Subscription<usize, WindowFullscreenCallback>),
4708 WindowBoundsObservation(callback_collection::Subscription<usize, WindowBoundsCallback>),
4709 KeystrokeObservation(callback_collection::Subscription<usize, KeystrokeCallback>),
4710 ReleaseObservation(callback_collection::Subscription<usize, ReleaseObservationCallback>),
4711 ActionObservation(callback_collection::Subscription<(), ActionObservationCallback>),
4712 ActiveLabeledTasksObservation(
4713 callback_collection::Subscription<(), ActiveLabeledTasksCallback>,
4714 ),
4715}
4716
4717impl Subscription {
4718 pub fn id(&self) -> usize {
4719 match self {
4720 Subscription::Subscription(subscription) => subscription.id(),
4721 Subscription::Observation(subscription) => subscription.id(),
4722 Subscription::GlobalSubscription(subscription) => subscription.id(),
4723 Subscription::GlobalObservation(subscription) => subscription.id(),
4724 Subscription::FocusObservation(subscription) => subscription.id(),
4725 Subscription::WindowActivationObservation(subscription) => subscription.id(),
4726 Subscription::WindowFullscreenObservation(subscription) => subscription.id(),
4727 Subscription::WindowBoundsObservation(subscription) => subscription.id(),
4728 Subscription::KeystrokeObservation(subscription) => subscription.id(),
4729 Subscription::ReleaseObservation(subscription) => subscription.id(),
4730 Subscription::ActionObservation(subscription) => subscription.id(),
4731 Subscription::ActiveLabeledTasksObservation(subscription) => subscription.id(),
4732 }
4733 }
4734
4735 pub fn detach(&mut self) {
4736 match self {
4737 Subscription::Subscription(subscription) => subscription.detach(),
4738 Subscription::GlobalSubscription(subscription) => subscription.detach(),
4739 Subscription::Observation(subscription) => subscription.detach(),
4740 Subscription::GlobalObservation(subscription) => subscription.detach(),
4741 Subscription::FocusObservation(subscription) => subscription.detach(),
4742 Subscription::KeystrokeObservation(subscription) => subscription.detach(),
4743 Subscription::WindowActivationObservation(subscription) => subscription.detach(),
4744 Subscription::WindowFullscreenObservation(subscription) => subscription.detach(),
4745 Subscription::WindowBoundsObservation(subscription) => subscription.detach(),
4746 Subscription::ReleaseObservation(subscription) => subscription.detach(),
4747 Subscription::ActionObservation(subscription) => subscription.detach(),
4748 Subscription::ActiveLabeledTasksObservation(subscription) => subscription.detach(),
4749 }
4750 }
4751}
4752
4753#[cfg(test)]
4754mod tests {
4755 use super::*;
4756 use crate::{
4757 actions,
4758 elements::*,
4759 impl_actions,
4760 platform::{MouseButton, MouseButtonEvent},
4761 window::ChildView,
4762 };
4763 use itertools::Itertools;
4764 use postage::{sink::Sink, stream::Stream};
4765 use serde::Deserialize;
4766 use smol::future::poll_once;
4767 use std::{
4768 cell::Cell,
4769 sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
4770 };
4771
4772 #[crate::test(self)]
4773 fn test_model_handles(cx: &mut AppContext) {
4774 struct Model {
4775 other: Option<ModelHandle<Model>>,
4776 events: Vec<String>,
4777 }
4778
4779 impl Entity for Model {
4780 type Event = usize;
4781 }
4782
4783 impl Model {
4784 fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
4785 if let Some(other) = other.as_ref() {
4786 cx.observe(other, |me, _, _| {
4787 me.events.push("notified".into());
4788 })
4789 .detach();
4790 cx.subscribe(other, |me, _, event, _| {
4791 me.events.push(format!("observed event {}", event));
4792 })
4793 .detach();
4794 }
4795
4796 Self {
4797 other,
4798 events: Vec::new(),
4799 }
4800 }
4801 }
4802
4803 let handle_1 = cx.add_model(|cx| Model::new(None, cx));
4804 let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
4805 assert_eq!(cx.models.len(), 2);
4806
4807 handle_1.update(cx, |model, cx| {
4808 model.events.push("updated".into());
4809 cx.emit(1);
4810 cx.notify();
4811 cx.emit(2);
4812 });
4813 assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
4814 assert_eq!(
4815 handle_2.read(cx).events,
4816 vec![
4817 "observed event 1".to_string(),
4818 "notified".to_string(),
4819 "observed event 2".to_string(),
4820 ]
4821 );
4822
4823 handle_2.update(cx, |model, _| {
4824 drop(handle_1);
4825 model.other.take();
4826 });
4827
4828 assert_eq!(cx.models.len(), 1);
4829 assert!(cx.subscriptions.is_empty());
4830 assert!(cx.observations.is_empty());
4831 }
4832
4833 #[crate::test(self)]
4834 fn test_model_events(cx: &mut AppContext) {
4835 #[derive(Default)]
4836 struct Model {
4837 events: Vec<usize>,
4838 }
4839
4840 impl Entity for Model {
4841 type Event = usize;
4842 }
4843
4844 let handle_1 = cx.add_model(|_| Model::default());
4845 let handle_2 = cx.add_model(|_| Model::default());
4846
4847 handle_1.update(cx, |_, cx| {
4848 cx.subscribe(&handle_2, move |model: &mut Model, emitter, event, cx| {
4849 model.events.push(*event);
4850
4851 cx.subscribe(&emitter, |model, _, event, _| {
4852 model.events.push(*event * 2);
4853 })
4854 .detach();
4855 })
4856 .detach();
4857 });
4858
4859 handle_2.update(cx, |_, c| c.emit(7));
4860 assert_eq!(handle_1.read(cx).events, vec![7]);
4861
4862 handle_2.update(cx, |_, c| c.emit(5));
4863 assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
4864 }
4865
4866 #[crate::test(self)]
4867 fn test_model_emit_before_subscribe_in_same_update_cycle(cx: &mut AppContext) {
4868 #[derive(Default)]
4869 struct Model;
4870
4871 impl Entity for Model {
4872 type Event = ();
4873 }
4874
4875 let events = Rc::new(RefCell::new(Vec::new()));
4876 cx.add_model(|cx| {
4877 drop(cx.subscribe(&cx.handle(), {
4878 let events = events.clone();
4879 move |_, _, _, _| events.borrow_mut().push("dropped before flush")
4880 }));
4881 cx.subscribe(&cx.handle(), {
4882 let events = events.clone();
4883 move |_, _, _, _| events.borrow_mut().push("before emit")
4884 })
4885 .detach();
4886 cx.emit(());
4887 cx.subscribe(&cx.handle(), {
4888 let events = events.clone();
4889 move |_, _, _, _| events.borrow_mut().push("after emit")
4890 })
4891 .detach();
4892 Model
4893 });
4894 assert_eq!(*events.borrow(), ["before emit"]);
4895 }
4896
4897 #[crate::test(self)]
4898 fn test_observe_and_notify_from_model(cx: &mut AppContext) {
4899 #[derive(Default)]
4900 struct Model {
4901 count: usize,
4902 events: Vec<usize>,
4903 }
4904
4905 impl Entity for Model {
4906 type Event = ();
4907 }
4908
4909 let handle_1 = cx.add_model(|_| Model::default());
4910 let handle_2 = cx.add_model(|_| Model::default());
4911
4912 handle_1.update(cx, |_, c| {
4913 c.observe(&handle_2, move |model, observed, c| {
4914 model.events.push(observed.read(c).count);
4915 c.observe(&observed, |model, observed, c| {
4916 model.events.push(observed.read(c).count * 2);
4917 })
4918 .detach();
4919 })
4920 .detach();
4921 });
4922
4923 handle_2.update(cx, |model, c| {
4924 model.count = 7;
4925 c.notify()
4926 });
4927 assert_eq!(handle_1.read(cx).events, vec![7]);
4928
4929 handle_2.update(cx, |model, c| {
4930 model.count = 5;
4931 c.notify()
4932 });
4933 assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
4934 }
4935
4936 #[crate::test(self)]
4937 fn test_model_notify_before_observe_in_same_update_cycle(cx: &mut AppContext) {
4938 #[derive(Default)]
4939 struct Model;
4940
4941 impl Entity for Model {
4942 type Event = ();
4943 }
4944
4945 let events = Rc::new(RefCell::new(Vec::new()));
4946 cx.add_model(|cx| {
4947 drop(cx.observe(&cx.handle(), {
4948 let events = events.clone();
4949 move |_, _, _| events.borrow_mut().push("dropped before flush")
4950 }));
4951 cx.observe(&cx.handle(), {
4952 let events = events.clone();
4953 move |_, _, _| events.borrow_mut().push("before notify")
4954 })
4955 .detach();
4956 cx.notify();
4957 cx.observe(&cx.handle(), {
4958 let events = events.clone();
4959 move |_, _, _| events.borrow_mut().push("after notify")
4960 })
4961 .detach();
4962 Model
4963 });
4964 assert_eq!(*events.borrow(), ["before notify"]);
4965 }
4966
4967 #[crate::test(self)]
4968 fn test_defer_and_after_window_update(cx: &mut TestAppContext) {
4969 struct View {
4970 render_count: usize,
4971 }
4972
4973 impl Entity for View {
4974 type Event = usize;
4975 }
4976
4977 impl super::View for View {
4978 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
4979 post_inc(&mut self.render_count);
4980 Empty::new().into_any()
4981 }
4982
4983 fn ui_name() -> &'static str {
4984 "View"
4985 }
4986 }
4987
4988 let window = cx.add_window(|_| View { render_count: 0 });
4989 let called_defer = Rc::new(AtomicBool::new(false));
4990 let called_after_window_update = Rc::new(AtomicBool::new(false));
4991
4992 window.root(cx).update(cx, |this, cx| {
4993 assert_eq!(this.render_count, 1);
4994 cx.defer({
4995 let called_defer = called_defer.clone();
4996 move |this, _| {
4997 assert_eq!(this.render_count, 1);
4998 called_defer.store(true, SeqCst);
4999 }
5000 });
5001 cx.after_window_update({
5002 let called_after_window_update = called_after_window_update.clone();
5003 move |this, cx| {
5004 assert_eq!(this.render_count, 2);
5005 called_after_window_update.store(true, SeqCst);
5006 cx.notify();
5007 }
5008 });
5009 assert!(!called_defer.load(SeqCst));
5010 assert!(!called_after_window_update.load(SeqCst));
5011 cx.notify();
5012 });
5013
5014 assert!(called_defer.load(SeqCst));
5015 assert!(called_after_window_update.load(SeqCst));
5016 assert_eq!(window.read_root_with(cx, |view, _| view.render_count), 3);
5017 }
5018
5019 #[crate::test(self)]
5020 fn test_view_handles(cx: &mut TestAppContext) {
5021 struct View {
5022 other: Option<ViewHandle<View>>,
5023 events: Vec<String>,
5024 }
5025
5026 impl Entity for View {
5027 type Event = usize;
5028 }
5029
5030 impl super::View for View {
5031 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5032 Empty::new().into_any()
5033 }
5034
5035 fn ui_name() -> &'static str {
5036 "View"
5037 }
5038 }
5039
5040 impl View {
5041 fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
5042 if let Some(other) = other.as_ref() {
5043 cx.subscribe(other, |me, _, event, _| {
5044 me.events.push(format!("observed event {}", event));
5045 })
5046 .detach();
5047 }
5048 Self {
5049 other,
5050 events: Vec::new(),
5051 }
5052 }
5053 }
5054
5055 let window = cx.add_window(|cx| View::new(None, cx));
5056 let handle_1 = window.add_view(cx, |cx| View::new(None, cx));
5057 let handle_2 = window.add_view(cx, |cx| View::new(Some(handle_1.clone()), cx));
5058 assert_eq!(cx.read(|cx| cx.views.len()), 3);
5059
5060 handle_1.update(cx, |view, cx| {
5061 view.events.push("updated".into());
5062 cx.emit(1);
5063 cx.emit(2);
5064 });
5065 handle_1.read_with(cx, |view, _| {
5066 assert_eq!(view.events, vec!["updated".to_string()]);
5067 });
5068 handle_2.read_with(cx, |view, _| {
5069 assert_eq!(
5070 view.events,
5071 vec![
5072 "observed event 1".to_string(),
5073 "observed event 2".to_string(),
5074 ]
5075 );
5076 });
5077
5078 handle_2.update(cx, |view, _| {
5079 drop(handle_1);
5080 view.other.take();
5081 });
5082
5083 cx.read(|cx| {
5084 assert_eq!(cx.views.len(), 2);
5085 assert!(cx.subscriptions.is_empty());
5086 assert!(cx.observations.is_empty());
5087 });
5088 }
5089
5090 #[crate::test(self)]
5091 fn test_add_window(cx: &mut AppContext) {
5092 struct View {
5093 mouse_down_count: Arc<AtomicUsize>,
5094 }
5095
5096 impl Entity for View {
5097 type Event = ();
5098 }
5099
5100 impl super::View for View {
5101 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
5102 enum Handler {}
5103 let mouse_down_count = self.mouse_down_count.clone();
5104 MouseEventHandler::<Handler, _>::new(0, cx, |_, _| Empty::new())
5105 .on_down(MouseButton::Left, move |_, _, _| {
5106 mouse_down_count.fetch_add(1, SeqCst);
5107 })
5108 .into_any()
5109 }
5110
5111 fn ui_name() -> &'static str {
5112 "View"
5113 }
5114 }
5115
5116 let mouse_down_count = Arc::new(AtomicUsize::new(0));
5117 let window = cx.add_window(Default::default(), |_| View {
5118 mouse_down_count: mouse_down_count.clone(),
5119 });
5120
5121 window.update(cx, |cx| {
5122 // Ensure window's root element is in a valid lifecycle state.
5123 cx.dispatch_event(
5124 Event::MouseDown(MouseButtonEvent {
5125 position: Default::default(),
5126 button: MouseButton::Left,
5127 modifiers: Default::default(),
5128 click_count: 1,
5129 }),
5130 false,
5131 );
5132 assert_eq!(mouse_down_count.load(SeqCst), 1);
5133 });
5134 }
5135
5136 #[crate::test(self)]
5137 fn test_entity_release_hooks(cx: &mut TestAppContext) {
5138 struct Model {
5139 released: Rc<Cell<bool>>,
5140 }
5141
5142 struct View {
5143 released: Rc<Cell<bool>>,
5144 }
5145
5146 impl Entity for Model {
5147 type Event = ();
5148
5149 fn release(&mut self, _: &mut AppContext) {
5150 self.released.set(true);
5151 }
5152 }
5153
5154 impl Entity for View {
5155 type Event = ();
5156
5157 fn release(&mut self, _: &mut AppContext) {
5158 self.released.set(true);
5159 }
5160 }
5161
5162 impl super::View for View {
5163 fn ui_name() -> &'static str {
5164 "View"
5165 }
5166
5167 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5168 Empty::new().into_any()
5169 }
5170 }
5171
5172 let model_released = Rc::new(Cell::new(false));
5173 let model_release_observed = Rc::new(Cell::new(false));
5174 let view_released = Rc::new(Cell::new(false));
5175 let view_release_observed = Rc::new(Cell::new(false));
5176
5177 let model = cx.add_model(|_| Model {
5178 released: model_released.clone(),
5179 });
5180 let window = cx.add_window(|_| View {
5181 released: view_released.clone(),
5182 });
5183 let view = window.root(cx);
5184
5185 assert!(!model_released.get());
5186 assert!(!view_released.get());
5187
5188 cx.update(|cx| {
5189 cx.observe_release(&model, {
5190 let model_release_observed = model_release_observed.clone();
5191 move |_, _| model_release_observed.set(true)
5192 })
5193 .detach();
5194 cx.observe_release(&view, {
5195 let view_release_observed = view_release_observed.clone();
5196 move |_, _| view_release_observed.set(true)
5197 })
5198 .detach();
5199 });
5200
5201 cx.update(move |_| {
5202 drop(model);
5203 });
5204 assert!(model_released.get());
5205 assert!(model_release_observed.get());
5206
5207 drop(view);
5208 window.update(cx, |cx| cx.remove_window());
5209 assert!(view_released.get());
5210 assert!(view_release_observed.get());
5211 }
5212
5213 #[crate::test(self)]
5214 fn test_view_events(cx: &mut TestAppContext) {
5215 struct Model;
5216
5217 impl Entity for Model {
5218 type Event = String;
5219 }
5220
5221 let window = cx.add_window(|_| TestView::default());
5222 let handle_1 = window.root(cx);
5223 let handle_2 = window.add_view(cx, |_| TestView::default());
5224 let handle_3 = cx.add_model(|_| Model);
5225
5226 handle_1.update(cx, |_, cx| {
5227 cx.subscribe(&handle_2, move |me, emitter, event, cx| {
5228 me.events.push(event.clone());
5229
5230 cx.subscribe(&emitter, |me, _, event, _| {
5231 me.events.push(format!("{event} from inner"));
5232 })
5233 .detach();
5234 })
5235 .detach();
5236
5237 cx.subscribe(&handle_3, |me, _, event, _| {
5238 me.events.push(event.clone());
5239 })
5240 .detach();
5241 });
5242
5243 handle_2.update(cx, |_, c| c.emit("7".into()));
5244 handle_1.read_with(cx, |view, _| assert_eq!(view.events, ["7"]));
5245
5246 handle_2.update(cx, |_, c| c.emit("5".into()));
5247 handle_1.read_with(cx, |view, _| {
5248 assert_eq!(view.events, ["7", "5", "5 from inner"])
5249 });
5250
5251 handle_3.update(cx, |_, c| c.emit("9".into()));
5252 handle_1.read_with(cx, |view, _| {
5253 assert_eq!(view.events, ["7", "5", "5 from inner", "9"])
5254 });
5255 }
5256
5257 #[crate::test(self)]
5258 fn test_global_events(cx: &mut AppContext) {
5259 #[derive(Clone, Debug, Eq, PartialEq)]
5260 struct GlobalEvent(u64);
5261
5262 let events = Rc::new(RefCell::new(Vec::new()));
5263 let first_subscription;
5264 let second_subscription;
5265
5266 {
5267 let events = events.clone();
5268 first_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
5269 events.borrow_mut().push(("First", e.clone()));
5270 });
5271 }
5272
5273 {
5274 let events = events.clone();
5275 second_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
5276 events.borrow_mut().push(("Second", e.clone()));
5277 });
5278 }
5279
5280 cx.update(|cx| {
5281 cx.emit_global(GlobalEvent(1));
5282 cx.emit_global(GlobalEvent(2));
5283 });
5284
5285 drop(first_subscription);
5286
5287 cx.update(|cx| {
5288 cx.emit_global(GlobalEvent(3));
5289 });
5290
5291 drop(second_subscription);
5292
5293 cx.update(|cx| {
5294 cx.emit_global(GlobalEvent(4));
5295 });
5296
5297 assert_eq!(
5298 &*events.borrow(),
5299 &[
5300 ("First", GlobalEvent(1)),
5301 ("Second", GlobalEvent(1)),
5302 ("First", GlobalEvent(2)),
5303 ("Second", GlobalEvent(2)),
5304 ("Second", GlobalEvent(3)),
5305 ]
5306 );
5307 }
5308
5309 #[crate::test(self)]
5310 fn test_global_events_emitted_before_subscription_in_same_update_cycle(cx: &mut AppContext) {
5311 let events = Rc::new(RefCell::new(Vec::new()));
5312 cx.update(|cx| {
5313 {
5314 let events = events.clone();
5315 drop(cx.subscribe_global(move |_: &(), _| {
5316 events.borrow_mut().push("dropped before emit");
5317 }));
5318 }
5319
5320 {
5321 let events = events.clone();
5322 cx.subscribe_global(move |_: &(), _| {
5323 events.borrow_mut().push("before emit");
5324 })
5325 .detach();
5326 }
5327
5328 cx.emit_global(());
5329
5330 {
5331 let events = events.clone();
5332 cx.subscribe_global(move |_: &(), _| {
5333 events.borrow_mut().push("after emit");
5334 })
5335 .detach();
5336 }
5337 });
5338
5339 assert_eq!(*events.borrow(), ["before emit"]);
5340 }
5341
5342 #[crate::test(self)]
5343 fn test_global_nested_events(cx: &mut AppContext) {
5344 #[derive(Clone, Debug, Eq, PartialEq)]
5345 struct GlobalEvent(u64);
5346
5347 let events = Rc::new(RefCell::new(Vec::new()));
5348
5349 {
5350 let events = events.clone();
5351 cx.subscribe_global(move |e: &GlobalEvent, cx| {
5352 events.borrow_mut().push(("Outer", e.clone()));
5353
5354 if e.0 == 1 {
5355 let events = events.clone();
5356 cx.subscribe_global(move |e: &GlobalEvent, _| {
5357 events.borrow_mut().push(("Inner", e.clone()));
5358 })
5359 .detach();
5360 }
5361 })
5362 .detach();
5363 }
5364
5365 cx.update(|cx| {
5366 cx.emit_global(GlobalEvent(1));
5367 cx.emit_global(GlobalEvent(2));
5368 cx.emit_global(GlobalEvent(3));
5369 });
5370 cx.update(|cx| {
5371 cx.emit_global(GlobalEvent(4));
5372 });
5373
5374 assert_eq!(
5375 &*events.borrow(),
5376 &[
5377 ("Outer", GlobalEvent(1)),
5378 ("Outer", GlobalEvent(2)),
5379 ("Outer", GlobalEvent(3)),
5380 ("Outer", GlobalEvent(4)),
5381 ("Inner", GlobalEvent(4)),
5382 ]
5383 );
5384 }
5385
5386 #[crate::test(self)]
5387 fn test_global(cx: &mut AppContext) {
5388 type Global = usize;
5389
5390 let observation_count = Rc::new(RefCell::new(0));
5391 let subscription = cx.observe_global::<Global, _>({
5392 let observation_count = observation_count.clone();
5393 move |_| {
5394 *observation_count.borrow_mut() += 1;
5395 }
5396 });
5397
5398 assert!(!cx.has_global::<Global>());
5399 assert_eq!(cx.default_global::<Global>(), &0);
5400 assert_eq!(*observation_count.borrow(), 1);
5401 assert!(cx.has_global::<Global>());
5402 assert_eq!(
5403 cx.update_global::<Global, _, _>(|global, _| {
5404 *global = 1;
5405 "Update Result"
5406 }),
5407 "Update Result"
5408 );
5409 assert_eq!(*observation_count.borrow(), 2);
5410 assert_eq!(cx.global::<Global>(), &1);
5411
5412 drop(subscription);
5413 cx.update_global::<Global, _, _>(|global, _| {
5414 *global = 2;
5415 });
5416 assert_eq!(*observation_count.borrow(), 2);
5417
5418 type OtherGlobal = f32;
5419
5420 let observation_count = Rc::new(RefCell::new(0));
5421 cx.observe_global::<OtherGlobal, _>({
5422 let observation_count = observation_count.clone();
5423 move |_| {
5424 *observation_count.borrow_mut() += 1;
5425 }
5426 })
5427 .detach();
5428
5429 assert_eq!(
5430 cx.update_default_global::<OtherGlobal, _, _>(|global, _| {
5431 assert_eq!(global, &0.0);
5432 *global = 2.0;
5433 "Default update result"
5434 }),
5435 "Default update result"
5436 );
5437 assert_eq!(cx.global::<OtherGlobal>(), &2.0);
5438 assert_eq!(*observation_count.borrow(), 1);
5439 }
5440
5441 #[crate::test(self)]
5442 fn test_dropping_subscribers(cx: &mut TestAppContext) {
5443 struct Model;
5444
5445 impl Entity for Model {
5446 type Event = ();
5447 }
5448
5449 let window = cx.add_window(|_| TestView::default());
5450 let observing_view = window.add_view(cx, |_| TestView::default());
5451 let emitting_view = window.add_view(cx, |_| TestView::default());
5452 let observing_model = cx.add_model(|_| Model);
5453 let observed_model = cx.add_model(|_| Model);
5454
5455 observing_view.update(cx, |_, cx| {
5456 cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
5457 cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5458 });
5459 observing_model.update(cx, |_, cx| {
5460 cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5461 });
5462
5463 cx.update(|_| {
5464 drop(observing_view);
5465 drop(observing_model);
5466 });
5467
5468 emitting_view.update(cx, |_, cx| cx.emit(Default::default()));
5469 observed_model.update(cx, |_, cx| cx.emit(()));
5470 }
5471
5472 #[crate::test(self)]
5473 fn test_view_emit_before_subscribe_in_same_update_cycle(cx: &mut AppContext) {
5474 let window = cx.add_window::<TestView, _>(Default::default(), |cx| {
5475 drop(cx.subscribe(&cx.handle(), {
5476 move |this, _, _, _| this.events.push("dropped before flush".into())
5477 }));
5478 cx.subscribe(&cx.handle(), {
5479 move |this, _, _, _| this.events.push("before emit".into())
5480 })
5481 .detach();
5482 cx.emit("the event".into());
5483 cx.subscribe(&cx.handle(), {
5484 move |this, _, _, _| this.events.push("after emit".into())
5485 })
5486 .detach();
5487 TestView { events: Vec::new() }
5488 });
5489
5490 window.read_root_with(cx, |view, _| assert_eq!(view.events, ["before emit"]));
5491 }
5492
5493 #[crate::test(self)]
5494 fn test_observe_and_notify_from_view(cx: &mut TestAppContext) {
5495 #[derive(Default)]
5496 struct Model {
5497 state: String,
5498 }
5499
5500 impl Entity for Model {
5501 type Event = ();
5502 }
5503
5504 let window = cx.add_window(|_| TestView::default());
5505 let view = window.root(cx);
5506 let model = cx.add_model(|_| Model {
5507 state: "old-state".into(),
5508 });
5509
5510 view.update(cx, |_, c| {
5511 c.observe(&model, |me, observed, cx| {
5512 me.events.push(observed.read(cx).state.clone())
5513 })
5514 .detach();
5515 });
5516
5517 model.update(cx, |model, cx| {
5518 model.state = "new-state".into();
5519 cx.notify();
5520 });
5521 view.read_with(cx, |view, _| assert_eq!(view.events, ["new-state"]));
5522 }
5523
5524 #[crate::test(self)]
5525 fn test_view_notify_before_observe_in_same_update_cycle(cx: &mut AppContext) {
5526 let window = cx.add_window::<TestView, _>(Default::default(), |cx| {
5527 drop(cx.observe(&cx.handle(), {
5528 move |this, _, _| this.events.push("dropped before flush".into())
5529 }));
5530 cx.observe(&cx.handle(), {
5531 move |this, _, _| this.events.push("before notify".into())
5532 })
5533 .detach();
5534 cx.notify();
5535 cx.observe(&cx.handle(), {
5536 move |this, _, _| this.events.push("after notify".into())
5537 })
5538 .detach();
5539 TestView { events: Vec::new() }
5540 });
5541
5542 window.read_root_with(cx, |view, _| assert_eq!(view.events, ["before notify"]));
5543 }
5544
5545 #[crate::test(self)]
5546 fn test_notify_and_drop_observe_subscription_in_same_update_cycle(cx: &mut TestAppContext) {
5547 struct Model;
5548 impl Entity for Model {
5549 type Event = ();
5550 }
5551
5552 let model = cx.add_model(|_| Model);
5553 let window = cx.add_window(|_| TestView::default());
5554 let view = window.root(cx);
5555
5556 view.update(cx, |_, cx| {
5557 model.update(cx, |_, cx| cx.notify());
5558 drop(cx.observe(&model, move |this, _, _| {
5559 this.events.push("model notified".into());
5560 }));
5561 model.update(cx, |_, cx| cx.notify());
5562 });
5563
5564 for _ in 0..3 {
5565 model.update(cx, |_, cx| cx.notify());
5566 }
5567 view.read_with(cx, |view, _| assert_eq!(view.events, Vec::<&str>::new()));
5568 }
5569
5570 #[crate::test(self)]
5571 fn test_dropping_observers(cx: &mut TestAppContext) {
5572 struct Model;
5573
5574 impl Entity for Model {
5575 type Event = ();
5576 }
5577
5578 let window = cx.add_window(|_| TestView::default());
5579 let observing_view = window.add_view(cx, |_| TestView::default());
5580 let observing_model = cx.add_model(|_| Model);
5581 let observed_model = cx.add_model(|_| Model);
5582
5583 observing_view.update(cx, |_, cx| {
5584 cx.observe(&observed_model, |_, _, _| {}).detach();
5585 });
5586 observing_model.update(cx, |_, cx| {
5587 cx.observe(&observed_model, |_, _, _| {}).detach();
5588 });
5589
5590 cx.update(|_| {
5591 drop(observing_view);
5592 drop(observing_model);
5593 });
5594
5595 observed_model.update(cx, |_, cx| cx.notify());
5596 }
5597
5598 #[crate::test(self)]
5599 fn test_dropping_subscriptions_during_callback(cx: &mut TestAppContext) {
5600 struct Model;
5601
5602 impl Entity for Model {
5603 type Event = u64;
5604 }
5605
5606 // Events
5607 let observing_model = cx.add_model(|_| Model);
5608 let observed_model = cx.add_model(|_| Model);
5609
5610 let events = Rc::new(RefCell::new(Vec::new()));
5611
5612 observing_model.update(cx, |_, cx| {
5613 let events = events.clone();
5614 let subscription = Rc::new(RefCell::new(None));
5615 *subscription.borrow_mut() = Some(cx.subscribe(&observed_model, {
5616 let subscription = subscription.clone();
5617 move |_, _, e, _| {
5618 subscription.borrow_mut().take();
5619 events.borrow_mut().push(*e);
5620 }
5621 }));
5622 });
5623
5624 observed_model.update(cx, |_, cx| {
5625 cx.emit(1);
5626 cx.emit(2);
5627 });
5628
5629 assert_eq!(*events.borrow(), [1]);
5630
5631 // Global Events
5632 #[derive(Clone, Debug, Eq, PartialEq)]
5633 struct GlobalEvent(u64);
5634
5635 let events = Rc::new(RefCell::new(Vec::new()));
5636
5637 {
5638 let events = events.clone();
5639 let subscription = Rc::new(RefCell::new(None));
5640 *subscription.borrow_mut() = Some(cx.subscribe_global({
5641 let subscription = subscription.clone();
5642 move |e: &GlobalEvent, _| {
5643 subscription.borrow_mut().take();
5644 events.borrow_mut().push(e.clone());
5645 }
5646 }));
5647 }
5648
5649 cx.update(|cx| {
5650 cx.emit_global(GlobalEvent(1));
5651 cx.emit_global(GlobalEvent(2));
5652 });
5653
5654 assert_eq!(*events.borrow(), [GlobalEvent(1)]);
5655
5656 // Model Observation
5657 let observing_model = cx.add_model(|_| Model);
5658 let observed_model = cx.add_model(|_| Model);
5659
5660 let observation_count = Rc::new(RefCell::new(0));
5661
5662 observing_model.update(cx, |_, cx| {
5663 let observation_count = observation_count.clone();
5664 let subscription = Rc::new(RefCell::new(None));
5665 *subscription.borrow_mut() = Some(cx.observe(&observed_model, {
5666 let subscription = subscription.clone();
5667 move |_, _, _| {
5668 subscription.borrow_mut().take();
5669 *observation_count.borrow_mut() += 1;
5670 }
5671 }));
5672 });
5673
5674 observed_model.update(cx, |_, cx| {
5675 cx.notify();
5676 });
5677
5678 observed_model.update(cx, |_, cx| {
5679 cx.notify();
5680 });
5681
5682 assert_eq!(*observation_count.borrow(), 1);
5683
5684 // View Observation
5685 struct View;
5686
5687 impl Entity for View {
5688 type Event = ();
5689 }
5690
5691 impl super::View for View {
5692 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5693 Empty::new().into_any()
5694 }
5695
5696 fn ui_name() -> &'static str {
5697 "View"
5698 }
5699 }
5700
5701 let window = cx.add_window(|_| View);
5702 let observing_view = window.add_view(cx, |_| View);
5703 let observed_view = window.add_view(cx, |_| View);
5704
5705 let observation_count = Rc::new(RefCell::new(0));
5706 observing_view.update(cx, |_, cx| {
5707 let observation_count = observation_count.clone();
5708 let subscription = Rc::new(RefCell::new(None));
5709 *subscription.borrow_mut() = Some(cx.observe(&observed_view, {
5710 let subscription = subscription.clone();
5711 move |_, _, _| {
5712 subscription.borrow_mut().take();
5713 *observation_count.borrow_mut() += 1;
5714 }
5715 }));
5716 });
5717
5718 observed_view.update(cx, |_, cx| {
5719 cx.notify();
5720 });
5721
5722 observed_view.update(cx, |_, cx| {
5723 cx.notify();
5724 });
5725
5726 assert_eq!(*observation_count.borrow(), 1);
5727
5728 // Global Observation
5729 let observation_count = Rc::new(RefCell::new(0));
5730 let subscription = Rc::new(RefCell::new(None));
5731 *subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
5732 let observation_count = observation_count.clone();
5733 let subscription = subscription.clone();
5734 move |_| {
5735 subscription.borrow_mut().take();
5736 *observation_count.borrow_mut() += 1;
5737 }
5738 }));
5739
5740 cx.update(|cx| {
5741 cx.default_global::<()>();
5742 cx.set_global(());
5743 });
5744 assert_eq!(*observation_count.borrow(), 1);
5745 }
5746
5747 #[crate::test(self)]
5748 fn test_focus(cx: &mut TestAppContext) {
5749 struct View {
5750 name: String,
5751 events: Arc<Mutex<Vec<String>>>,
5752 child: Option<AnyViewHandle>,
5753 }
5754
5755 impl Entity for View {
5756 type Event = ();
5757 }
5758
5759 impl super::View for View {
5760 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
5761 self.child
5762 .as_ref()
5763 .map(|child| ChildView::new(child, cx).into_any())
5764 .unwrap_or(Empty::new().into_any())
5765 }
5766
5767 fn ui_name() -> &'static str {
5768 "View"
5769 }
5770
5771 fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
5772 if cx.handle().id() == focused.id() {
5773 self.events.lock().push(format!("{} focused", &self.name));
5774 }
5775 }
5776
5777 fn focus_out(&mut self, blurred: AnyViewHandle, cx: &mut ViewContext<Self>) {
5778 if cx.handle().id() == blurred.id() {
5779 self.events.lock().push(format!("{} blurred", &self.name));
5780 }
5781 }
5782 }
5783
5784 let view_events: Arc<Mutex<Vec<String>>> = Default::default();
5785 let window = cx.add_window(|_| View {
5786 events: view_events.clone(),
5787 name: "view 1".to_string(),
5788 child: None,
5789 });
5790 let view_1 = window.root(cx);
5791 let view_2 = window.update(cx, |cx| {
5792 let view_2 = cx.add_view(|_| View {
5793 events: view_events.clone(),
5794 name: "view 2".to_string(),
5795 child: None,
5796 });
5797 view_1.update(cx, |view_1, cx| {
5798 view_1.child = Some(view_2.clone().into_any());
5799 cx.notify();
5800 });
5801 view_2
5802 });
5803
5804 let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
5805 view_1.update(cx, |_, cx| {
5806 cx.observe_focus(&view_2, {
5807 let observed_events = observed_events.clone();
5808 move |this, view, focused, cx| {
5809 let label = if focused { "focus" } else { "blur" };
5810 observed_events.lock().push(format!(
5811 "{} observed {}'s {}",
5812 this.name,
5813 view.read(cx).name,
5814 label
5815 ))
5816 }
5817 })
5818 .detach();
5819 });
5820 view_2.update(cx, |_, cx| {
5821 cx.observe_focus(&view_1, {
5822 let observed_events = observed_events.clone();
5823 move |this, view, focused, cx| {
5824 let label = if focused { "focus" } else { "blur" };
5825 observed_events.lock().push(format!(
5826 "{} observed {}'s {}",
5827 this.name,
5828 view.read(cx).name,
5829 label
5830 ))
5831 }
5832 })
5833 .detach();
5834 });
5835 assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
5836 assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
5837
5838 view_1.update(cx, |_, cx| {
5839 // Ensure only the last focus event is honored.
5840 cx.focus(&view_2);
5841 cx.focus(&view_1);
5842 cx.focus(&view_2);
5843 });
5844
5845 assert_eq!(
5846 mem::take(&mut *view_events.lock()),
5847 ["view 1 blurred", "view 2 focused"],
5848 );
5849 assert_eq!(
5850 mem::take(&mut *observed_events.lock()),
5851 [
5852 "view 2 observed view 1's blur",
5853 "view 1 observed view 2's focus"
5854 ]
5855 );
5856
5857 view_1.update(cx, |_, cx| cx.focus(&view_1));
5858 assert_eq!(
5859 mem::take(&mut *view_events.lock()),
5860 ["view 2 blurred", "view 1 focused"],
5861 );
5862 assert_eq!(
5863 mem::take(&mut *observed_events.lock()),
5864 [
5865 "view 1 observed view 2's blur",
5866 "view 2 observed view 1's focus"
5867 ]
5868 );
5869
5870 view_1.update(cx, |_, cx| cx.focus(&view_2));
5871 assert_eq!(
5872 mem::take(&mut *view_events.lock()),
5873 ["view 1 blurred", "view 2 focused"],
5874 );
5875 assert_eq!(
5876 mem::take(&mut *observed_events.lock()),
5877 [
5878 "view 2 observed view 1's blur",
5879 "view 1 observed view 2's focus"
5880 ]
5881 );
5882
5883 println!("=====================");
5884 view_1.update(cx, |view, _| {
5885 drop(view_2);
5886 view.child = None;
5887 });
5888 assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
5889 assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
5890 }
5891
5892 #[crate::test(self)]
5893 fn test_deserialize_actions(cx: &mut AppContext) {
5894 #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
5895 pub struct ComplexAction {
5896 arg: String,
5897 count: usize,
5898 }
5899
5900 actions!(test::something, [SimpleAction]);
5901 impl_actions!(test::something, [ComplexAction]);
5902
5903 cx.add_global_action(move |_: &SimpleAction, _: &mut AppContext| {});
5904 cx.add_global_action(move |_: &ComplexAction, _: &mut AppContext| {});
5905
5906 let action1 = cx
5907 .deserialize_action(
5908 "test::something::ComplexAction",
5909 Some(serde_json::from_str(r#"{"arg": "a", "count": 5}"#).unwrap()),
5910 )
5911 .unwrap();
5912 let action2 = cx
5913 .deserialize_action("test::something::SimpleAction", None)
5914 .unwrap();
5915 assert_eq!(
5916 action1.as_any().downcast_ref::<ComplexAction>().unwrap(),
5917 &ComplexAction {
5918 arg: "a".to_string(),
5919 count: 5,
5920 }
5921 );
5922 assert_eq!(
5923 action2.as_any().downcast_ref::<SimpleAction>().unwrap(),
5924 &SimpleAction
5925 );
5926 }
5927
5928 #[crate::test(self)]
5929 fn test_dispatch_action(cx: &mut TestAppContext) {
5930 struct ViewA {
5931 id: usize,
5932 child: Option<AnyViewHandle>,
5933 }
5934
5935 impl Entity for ViewA {
5936 type Event = ();
5937 }
5938
5939 impl View for ViewA {
5940 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
5941 self.child
5942 .as_ref()
5943 .map(|child| ChildView::new(child, cx).into_any())
5944 .unwrap_or(Empty::new().into_any())
5945 }
5946
5947 fn ui_name() -> &'static str {
5948 "View"
5949 }
5950 }
5951
5952 struct ViewB {
5953 id: usize,
5954 child: Option<AnyViewHandle>,
5955 }
5956
5957 impl Entity for ViewB {
5958 type Event = ();
5959 }
5960
5961 impl View for ViewB {
5962 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
5963 self.child
5964 .as_ref()
5965 .map(|child| ChildView::new(child, cx).into_any())
5966 .unwrap_or(Empty::new().into_any())
5967 }
5968
5969 fn ui_name() -> &'static str {
5970 "View"
5971 }
5972 }
5973
5974 #[derive(Clone, Default, Deserialize, PartialEq)]
5975 pub struct Action(pub String);
5976
5977 impl_actions!(test, [Action]);
5978
5979 let actions = Rc::new(RefCell::new(Vec::new()));
5980 let observed_actions = Rc::new(RefCell::new(Vec::new()));
5981
5982 cx.update(|cx| {
5983 cx.add_global_action({
5984 let actions = actions.clone();
5985 move |_: &Action, _: &mut AppContext| {
5986 actions.borrow_mut().push("global".to_string());
5987 }
5988 });
5989
5990 cx.add_action({
5991 let actions = actions.clone();
5992 move |view: &mut ViewA, action: &Action, cx| {
5993 assert_eq!(action.0, "bar");
5994 cx.propagate_action();
5995 actions.borrow_mut().push(format!("{} a", view.id));
5996 }
5997 });
5998
5999 cx.add_action({
6000 let actions = actions.clone();
6001 move |view: &mut ViewA, _: &Action, cx| {
6002 if view.id != 1 {
6003 cx.add_view(|cx| {
6004 cx.propagate_action(); // Still works on a nested ViewContext
6005 ViewB { id: 5, child: None }
6006 });
6007 }
6008 actions.borrow_mut().push(format!("{} b", view.id));
6009 }
6010 });
6011
6012 cx.add_action({
6013 let actions = actions.clone();
6014 move |view: &mut ViewB, _: &Action, cx| {
6015 cx.propagate_action();
6016 actions.borrow_mut().push(format!("{} c", view.id));
6017 }
6018 });
6019
6020 cx.add_action({
6021 let actions = actions.clone();
6022 move |view: &mut ViewB, _: &Action, cx| {
6023 cx.propagate_action();
6024 actions.borrow_mut().push(format!("{} d", view.id));
6025 }
6026 });
6027
6028 cx.capture_action({
6029 let actions = actions.clone();
6030 move |view: &mut ViewA, _: &Action, cx| {
6031 cx.propagate_action();
6032 actions.borrow_mut().push(format!("{} capture", view.id));
6033 }
6034 });
6035
6036 cx.observe_actions({
6037 let observed_actions = observed_actions.clone();
6038 move |action_id, _| observed_actions.borrow_mut().push(action_id)
6039 })
6040 .detach();
6041 });
6042
6043 let window = cx.add_window(|_| ViewA { id: 1, child: None });
6044 let view_1 = window.root(cx);
6045 let view_2 = window.update(cx, |cx| {
6046 let child = cx.add_view(|_| ViewB { id: 2, child: None });
6047 view_1.update(cx, |view, cx| {
6048 view.child = Some(child.clone().into_any());
6049 cx.notify();
6050 });
6051 child
6052 });
6053 let view_3 = window.update(cx, |cx| {
6054 let child = cx.add_view(|_| ViewA { id: 3, child: None });
6055 view_2.update(cx, |view, cx| {
6056 view.child = Some(child.clone().into_any());
6057 cx.notify();
6058 });
6059 child
6060 });
6061 let view_4 = window.update(cx, |cx| {
6062 let child = cx.add_view(|_| ViewB { id: 4, child: None });
6063 view_3.update(cx, |view, cx| {
6064 view.child = Some(child.clone().into_any());
6065 cx.notify();
6066 });
6067 child
6068 });
6069
6070 window.update(cx, |cx| {
6071 cx.dispatch_action(Some(view_4.id()), &Action("bar".to_string()))
6072 });
6073
6074 assert_eq!(
6075 *actions.borrow(),
6076 vec![
6077 "1 capture",
6078 "3 capture",
6079 "4 d",
6080 "4 c",
6081 "3 b",
6082 "3 a",
6083 "2 d",
6084 "2 c",
6085 "1 b"
6086 ]
6087 );
6088 assert_eq!(*observed_actions.borrow(), [Action::default().id()]);
6089
6090 // Remove view_1, which doesn't propagate the action
6091
6092 let window = cx.add_window(|_| ViewB { id: 2, child: None });
6093 let view_2 = window.root(cx);
6094 let view_3 = window.update(cx, |cx| {
6095 let child = cx.add_view(|_| ViewA { id: 3, child: None });
6096 view_2.update(cx, |view, cx| {
6097 view.child = Some(child.clone().into_any());
6098 cx.notify();
6099 });
6100 child
6101 });
6102 let view_4 = window.update(cx, |cx| {
6103 let child = cx.add_view(|_| ViewB { id: 4, child: None });
6104 view_3.update(cx, |view, cx| {
6105 view.child = Some(child.clone().into_any());
6106 cx.notify();
6107 });
6108 child
6109 });
6110
6111 actions.borrow_mut().clear();
6112 window.update(cx, |cx| {
6113 cx.dispatch_action(Some(view_4.id()), &Action("bar".to_string()))
6114 });
6115
6116 assert_eq!(
6117 *actions.borrow(),
6118 vec![
6119 "3 capture",
6120 "4 d",
6121 "4 c",
6122 "3 b",
6123 "3 a",
6124 "2 d",
6125 "2 c",
6126 "global"
6127 ]
6128 );
6129 assert_eq!(
6130 *observed_actions.borrow(),
6131 [Action::default().id(), Action::default().id()]
6132 );
6133 }
6134
6135 #[crate::test(self)]
6136 fn test_dispatch_keystroke(cx: &mut AppContext) {
6137 #[derive(Clone, Deserialize, PartialEq)]
6138 pub struct Action(String);
6139
6140 impl_actions!(test, [Action]);
6141
6142 struct View {
6143 id: usize,
6144 keymap_context: KeymapContext,
6145 child: Option<AnyViewHandle>,
6146 }
6147
6148 impl Entity for View {
6149 type Event = ();
6150 }
6151
6152 impl super::View for View {
6153 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
6154 self.child
6155 .as_ref()
6156 .map(|child| ChildView::new(child, cx).into_any())
6157 .unwrap_or(Empty::new().into_any())
6158 }
6159
6160 fn ui_name() -> &'static str {
6161 "View"
6162 }
6163
6164 fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
6165 *keymap = self.keymap_context.clone();
6166 }
6167 }
6168
6169 impl View {
6170 fn new(id: usize) -> Self {
6171 View {
6172 id,
6173 keymap_context: KeymapContext::default(),
6174 child: None,
6175 }
6176 }
6177 }
6178
6179 let mut view_1 = View::new(1);
6180 let mut view_2 = View::new(2);
6181 let mut view_3 = View::new(3);
6182 view_1.keymap_context.add_identifier("a");
6183 view_2.keymap_context.add_identifier("a");
6184 view_2.keymap_context.add_identifier("b");
6185 view_3.keymap_context.add_identifier("a");
6186 view_3.keymap_context.add_identifier("b");
6187 view_3.keymap_context.add_identifier("c");
6188
6189 let window = cx.add_window(Default::default(), |cx| {
6190 let view_2 = cx.add_view(|cx| {
6191 let view_3 = cx.add_view(|cx| {
6192 cx.focus_self();
6193 view_3
6194 });
6195 view_2.child = Some(view_3.into_any());
6196 view_2
6197 });
6198 view_1.child = Some(view_2.into_any());
6199 view_1
6200 });
6201
6202 // This binding only dispatches an action on view 2 because that view will have
6203 // "a" and "b" in its context, but not "c".
6204 cx.add_bindings(vec![Binding::new(
6205 "a",
6206 Action("a".to_string()),
6207 Some("a && b && !c"),
6208 )]);
6209
6210 cx.add_bindings(vec![Binding::new("b", Action("b".to_string()), None)]);
6211
6212 // This binding only dispatches an action on views 2 and 3, because they have
6213 // a parent view with a in its context
6214 cx.add_bindings(vec![Binding::new(
6215 "c",
6216 Action("c".to_string()),
6217 Some("b > c"),
6218 )]);
6219
6220 // This binding only dispatches an action on view 2, because they have
6221 // a parent view with a in its context
6222 cx.add_bindings(vec![Binding::new(
6223 "d",
6224 Action("d".to_string()),
6225 Some("a && !b > b"),
6226 )]);
6227
6228 let actions = Rc::new(RefCell::new(Vec::new()));
6229 cx.add_action({
6230 let actions = actions.clone();
6231 move |view: &mut View, action: &Action, cx| {
6232 actions
6233 .borrow_mut()
6234 .push(format!("{} {}", view.id, action.0));
6235
6236 if action.0 == "b" {
6237 cx.propagate_action();
6238 }
6239 }
6240 });
6241
6242 cx.add_global_action({
6243 let actions = actions.clone();
6244 move |action: &Action, _| {
6245 actions.borrow_mut().push(format!("global {}", action.0));
6246 }
6247 });
6248
6249 window.update(cx, |cx| {
6250 cx.dispatch_keystroke(&Keystroke::parse("a").unwrap())
6251 });
6252 assert_eq!(&*actions.borrow(), &["2 a"]);
6253 actions.borrow_mut().clear();
6254
6255 window.update(cx, |cx| {
6256 cx.dispatch_keystroke(&Keystroke::parse("b").unwrap());
6257 });
6258
6259 assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
6260 actions.borrow_mut().clear();
6261
6262 window.update(cx, |cx| {
6263 cx.dispatch_keystroke(&Keystroke::parse("c").unwrap());
6264 });
6265 assert_eq!(&*actions.borrow(), &["3 c"]);
6266 actions.borrow_mut().clear();
6267
6268 window.update(cx, |cx| {
6269 cx.dispatch_keystroke(&Keystroke::parse("d").unwrap());
6270 });
6271 assert_eq!(&*actions.borrow(), &["2 d"]);
6272 actions.borrow_mut().clear();
6273 }
6274
6275 #[crate::test(self)]
6276 fn test_keystrokes_for_action(cx: &mut TestAppContext) {
6277 actions!(test, [Action1, Action2, GlobalAction]);
6278
6279 struct View1 {
6280 child: ViewHandle<View2>,
6281 }
6282 struct View2 {}
6283
6284 impl Entity for View1 {
6285 type Event = ();
6286 }
6287 impl Entity for View2 {
6288 type Event = ();
6289 }
6290
6291 impl super::View for View1 {
6292 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
6293 ChildView::new(&self.child, cx).into_any()
6294 }
6295 fn ui_name() -> &'static str {
6296 "View1"
6297 }
6298 }
6299 impl super::View for View2 {
6300 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6301 Empty::new().into_any()
6302 }
6303 fn ui_name() -> &'static str {
6304 "View2"
6305 }
6306 }
6307
6308 let window = cx.add_window(|cx| {
6309 let view_2 = cx.add_view(|cx| {
6310 cx.focus_self();
6311 View2 {}
6312 });
6313 View1 { child: view_2 }
6314 });
6315 let view_1 = window.root(cx);
6316 let view_2 = view_1.read_with(cx, |view, _| view.child.clone());
6317
6318 cx.update(|cx| {
6319 cx.add_action(|_: &mut View1, _: &Action1, _cx| {});
6320 cx.add_action(|_: &mut View2, _: &Action2, _cx| {});
6321 cx.add_global_action(|_: &GlobalAction, _| {});
6322 cx.add_bindings(vec![
6323 Binding::new("a", Action1, Some("View1")),
6324 Binding::new("b", Action2, Some("View1 > View2")),
6325 Binding::new("c", GlobalAction, Some("View3")), // View 3 does not exist
6326 ]);
6327 });
6328
6329 let view_1_id = view_1.id();
6330 view_1.update(cx, |_, cx| {
6331 view_2.update(cx, |_, cx| {
6332 // Sanity check
6333 let mut new_parents = Default::default();
6334 let mut notify_views_if_parents_change = Default::default();
6335 let mut layout_cx = LayoutContext::new(
6336 cx,
6337 &mut new_parents,
6338 &mut notify_views_if_parents_change,
6339 false,
6340 );
6341 assert_eq!(
6342 layout_cx
6343 .keystrokes_for_action(view_1_id, &Action1)
6344 .unwrap()
6345 .as_slice(),
6346 &[Keystroke::parse("a").unwrap()]
6347 );
6348 assert_eq!(
6349 layout_cx
6350 .keystrokes_for_action(view_2.id(), &Action2)
6351 .unwrap()
6352 .as_slice(),
6353 &[Keystroke::parse("b").unwrap()]
6354 );
6355
6356 // The 'a' keystroke propagates up the view tree from view_2
6357 // to view_1. The action, Action1, is handled by view_1.
6358 assert_eq!(
6359 layout_cx
6360 .keystrokes_for_action(view_2.id(), &Action1)
6361 .unwrap()
6362 .as_slice(),
6363 &[Keystroke::parse("a").unwrap()]
6364 );
6365
6366 // Actions that are handled below the current view don't have bindings
6367 assert_eq!(layout_cx.keystrokes_for_action(view_1_id, &Action2), None);
6368
6369 // Actions that are handled in other branches of the tree should not have a binding
6370 assert_eq!(
6371 layout_cx.keystrokes_for_action(view_2.id(), &GlobalAction),
6372 None
6373 );
6374 });
6375 });
6376
6377 // Check that global actions do not have a binding, even if a binding does exist in another view
6378 assert_eq!(
6379 &available_actions(window.into(), view_1.id(), cx),
6380 &[
6381 ("test::Action1", vec![Keystroke::parse("a").unwrap()]),
6382 ("test::GlobalAction", vec![])
6383 ],
6384 );
6385
6386 // Check that view 1 actions and bindings are available even when called from view 2
6387 assert_eq!(
6388 &available_actions(window.into(), view_2.id(), cx),
6389 &[
6390 ("test::Action1", vec![Keystroke::parse("a").unwrap()]),
6391 ("test::Action2", vec![Keystroke::parse("b").unwrap()]),
6392 ("test::GlobalAction", vec![]),
6393 ],
6394 );
6395
6396 // Produces a list of actions and key bindings
6397 fn available_actions(
6398 window: AnyWindowHandle,
6399 view_id: usize,
6400 cx: &TestAppContext,
6401 ) -> Vec<(&'static str, Vec<Keystroke>)> {
6402 cx.available_actions(window.into(), view_id)
6403 .into_iter()
6404 .map(|(action_name, _, bindings)| {
6405 (
6406 action_name,
6407 bindings
6408 .iter()
6409 .map(|binding| binding.keystrokes()[0].clone())
6410 .collect::<Vec<_>>(),
6411 )
6412 })
6413 .sorted_by(|(name1, _), (name2, _)| name1.cmp(name2))
6414 .collect()
6415 }
6416 }
6417
6418 #[crate::test(self)]
6419 fn test_keystrokes_for_action_with_data(cx: &mut TestAppContext) {
6420 #[derive(Clone, Debug, Deserialize, PartialEq)]
6421 struct ActionWithArg {
6422 #[serde(default)]
6423 arg: bool,
6424 }
6425
6426 struct View;
6427 impl super::Entity for View {
6428 type Event = ();
6429 }
6430 impl super::View for View {
6431 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6432 Empty::new().into_any()
6433 }
6434 fn ui_name() -> &'static str {
6435 "View"
6436 }
6437 }
6438
6439 impl_actions!(test, [ActionWithArg]);
6440
6441 let window = cx.add_window(|_| View);
6442 let view = window.root(cx);
6443 cx.update(|cx| {
6444 cx.add_global_action(|_: &ActionWithArg, _| {});
6445 cx.add_bindings(vec![
6446 Binding::new("a", ActionWithArg { arg: false }, None),
6447 Binding::new("shift-a", ActionWithArg { arg: true }, None),
6448 ]);
6449 });
6450
6451 let actions = cx.available_actions(window.into(), view.id());
6452 assert_eq!(
6453 actions[0].1.as_any().downcast_ref::<ActionWithArg>(),
6454 Some(&ActionWithArg { arg: false })
6455 );
6456 assert_eq!(
6457 actions[0]
6458 .2
6459 .iter()
6460 .map(|b| b.keystrokes()[0].clone())
6461 .collect::<Vec<_>>(),
6462 vec![Keystroke::parse("a").unwrap()],
6463 );
6464 }
6465
6466 #[crate::test(self)]
6467 async fn test_model_condition(cx: &mut TestAppContext) {
6468 struct Counter(usize);
6469
6470 impl super::Entity for Counter {
6471 type Event = ();
6472 }
6473
6474 impl Counter {
6475 fn inc(&mut self, cx: &mut ModelContext<Self>) {
6476 self.0 += 1;
6477 cx.notify();
6478 }
6479 }
6480
6481 let model = cx.add_model(|_| Counter(0));
6482
6483 let condition1 = model.condition(cx, |model, _| model.0 == 2);
6484 let condition2 = model.condition(cx, |model, _| model.0 == 3);
6485 smol::pin!(condition1, condition2);
6486
6487 model.update(cx, |model, cx| model.inc(cx));
6488 assert_eq!(poll_once(&mut condition1).await, None);
6489 assert_eq!(poll_once(&mut condition2).await, None);
6490
6491 model.update(cx, |model, cx| model.inc(cx));
6492 assert_eq!(poll_once(&mut condition1).await, Some(()));
6493 assert_eq!(poll_once(&mut condition2).await, None);
6494
6495 model.update(cx, |model, cx| model.inc(cx));
6496 assert_eq!(poll_once(&mut condition2).await, Some(()));
6497
6498 model.update(cx, |_, cx| cx.notify());
6499 }
6500
6501 #[crate::test(self)]
6502 #[should_panic]
6503 async fn test_model_condition_timeout(cx: &mut TestAppContext) {
6504 struct Model;
6505
6506 impl super::Entity for Model {
6507 type Event = ();
6508 }
6509
6510 let model = cx.add_model(|_| Model);
6511 model.condition(cx, |_, _| false).await;
6512 }
6513
6514 #[crate::test(self)]
6515 #[should_panic(expected = "model dropped with pending condition")]
6516 async fn test_model_condition_panic_on_drop(cx: &mut TestAppContext) {
6517 struct Model;
6518
6519 impl super::Entity for Model {
6520 type Event = ();
6521 }
6522
6523 let model = cx.add_model(|_| Model);
6524 let condition = model.condition(cx, |_, _| false);
6525 cx.update(|_| drop(model));
6526 condition.await;
6527 }
6528
6529 #[crate::test(self)]
6530 async fn test_view_condition(cx: &mut TestAppContext) {
6531 struct Counter(usize);
6532
6533 impl super::Entity for Counter {
6534 type Event = ();
6535 }
6536
6537 impl super::View for Counter {
6538 fn ui_name() -> &'static str {
6539 "test view"
6540 }
6541
6542 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6543 Empty::new().into_any()
6544 }
6545 }
6546
6547 impl Counter {
6548 fn inc(&mut self, cx: &mut ViewContext<Self>) {
6549 self.0 += 1;
6550 cx.notify();
6551 }
6552 }
6553
6554 let window = cx.add_window(|_| Counter(0));
6555 let view = window.root(cx);
6556
6557 let condition1 = view.condition(cx, |view, _| view.0 == 2);
6558 let condition2 = view.condition(cx, |view, _| view.0 == 3);
6559 smol::pin!(condition1, condition2);
6560
6561 view.update(cx, |view, cx| view.inc(cx));
6562 assert_eq!(poll_once(&mut condition1).await, None);
6563 assert_eq!(poll_once(&mut condition2).await, None);
6564
6565 view.update(cx, |view, cx| view.inc(cx));
6566 assert_eq!(poll_once(&mut condition1).await, Some(()));
6567 assert_eq!(poll_once(&mut condition2).await, None);
6568
6569 view.update(cx, |view, cx| view.inc(cx));
6570 assert_eq!(poll_once(&mut condition2).await, Some(()));
6571 view.update(cx, |_, cx| cx.notify());
6572 }
6573
6574 #[crate::test(self)]
6575 #[should_panic]
6576 async fn test_view_condition_timeout(cx: &mut TestAppContext) {
6577 let window = cx.add_window(|_| TestView::default());
6578 window.root(cx).condition(cx, |_, _| false).await;
6579 }
6580
6581 #[crate::test(self)]
6582 #[should_panic(expected = "view dropped with pending condition")]
6583 async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) {
6584 let window = cx.add_window(|_| TestView::default());
6585 let view = window.add_view(cx, |_| TestView::default());
6586
6587 let condition = view.condition(cx, |_, _| false);
6588 cx.update(|_| drop(view));
6589 condition.await;
6590 }
6591
6592 #[crate::test(self)]
6593 fn test_refresh_windows(cx: &mut TestAppContext) {
6594 struct View(usize);
6595
6596 impl super::Entity for View {
6597 type Event = ();
6598 }
6599
6600 impl super::View for View {
6601 fn ui_name() -> &'static str {
6602 "test view"
6603 }
6604
6605 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6606 Empty::new().into_any_named(format!("render count: {}", post_inc(&mut self.0)))
6607 }
6608 }
6609
6610 let window = cx.add_window(|_| View(0));
6611 let root_view = window.root(cx);
6612 window.update(cx, |cx| {
6613 assert_eq!(
6614 cx.window.rendered_views[&root_view.id()].name(),
6615 Some("render count: 0")
6616 );
6617 });
6618
6619 let view = window.update(cx, |cx| {
6620 cx.refresh_windows();
6621 cx.add_view(|_| View(0))
6622 });
6623
6624 window.update(cx, |cx| {
6625 assert_eq!(
6626 cx.window.rendered_views[&root_view.id()].name(),
6627 Some("render count: 1")
6628 );
6629 assert_eq!(
6630 cx.window.rendered_views[&view.id()].name(),
6631 Some("render count: 0")
6632 );
6633 });
6634
6635 cx.update(|cx| cx.refresh_windows());
6636
6637 window.update(cx, |cx| {
6638 assert_eq!(
6639 cx.window.rendered_views[&root_view.id()].name(),
6640 Some("render count: 2")
6641 );
6642 assert_eq!(
6643 cx.window.rendered_views[&view.id()].name(),
6644 Some("render count: 1")
6645 );
6646 });
6647
6648 cx.update(|cx| {
6649 cx.refresh_windows();
6650 drop(view);
6651 });
6652
6653 window.update(cx, |cx| {
6654 assert_eq!(
6655 cx.window.rendered_views[&root_view.id()].name(),
6656 Some("render count: 3")
6657 );
6658 assert_eq!(cx.window.rendered_views.len(), 1);
6659 });
6660 }
6661
6662 #[crate::test(self)]
6663 async fn test_labeled_tasks(cx: &mut TestAppContext) {
6664 assert_eq!(None, cx.update(|cx| cx.active_labeled_tasks().next()));
6665 let (mut sender, mut receiver) = postage::oneshot::channel::<()>();
6666 let task = cx
6667 .update(|cx| cx.spawn_labeled("Test Label", |_| async move { receiver.recv().await }));
6668
6669 assert_eq!(
6670 Some("Test Label"),
6671 cx.update(|cx| cx.active_labeled_tasks().next())
6672 );
6673 sender
6674 .send(())
6675 .await
6676 .expect("Could not send message to complete task");
6677 task.await;
6678
6679 assert_eq!(None, cx.update(|cx| cx.active_labeled_tasks().next()));
6680 }
6681
6682 #[crate::test(self)]
6683 async fn test_window_activation(cx: &mut TestAppContext) {
6684 struct View(&'static str);
6685
6686 impl super::Entity for View {
6687 type Event = ();
6688 }
6689
6690 impl super::View for View {
6691 fn ui_name() -> &'static str {
6692 "test view"
6693 }
6694
6695 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6696 Empty::new().into_any()
6697 }
6698 }
6699
6700 let events = Rc::new(RefCell::new(Vec::new()));
6701 let window_1 = cx.add_window(|cx: &mut ViewContext<View>| {
6702 cx.observe_window_activation({
6703 let events = events.clone();
6704 move |this, active, _| events.borrow_mut().push((this.0, active))
6705 })
6706 .detach();
6707 View("window 1")
6708 });
6709 assert_eq!(mem::take(&mut *events.borrow_mut()), [("window 1", true)]);
6710
6711 let window_2 = cx.add_window(|cx: &mut ViewContext<View>| {
6712 cx.observe_window_activation({
6713 let events = events.clone();
6714 move |this, active, _| events.borrow_mut().push((this.0, active))
6715 })
6716 .detach();
6717 View("window 2")
6718 });
6719 assert_eq!(
6720 mem::take(&mut *events.borrow_mut()),
6721 [("window 1", false), ("window 2", true)]
6722 );
6723
6724 let window_3 = cx.add_window(|cx: &mut ViewContext<View>| {
6725 cx.observe_window_activation({
6726 let events = events.clone();
6727 move |this, active, _| events.borrow_mut().push((this.0, active))
6728 })
6729 .detach();
6730 View("window 3")
6731 });
6732 assert_eq!(
6733 mem::take(&mut *events.borrow_mut()),
6734 [("window 2", false), ("window 3", true)]
6735 );
6736
6737 window_2.simulate_activation(cx);
6738 assert_eq!(
6739 mem::take(&mut *events.borrow_mut()),
6740 [("window 3", false), ("window 2", true)]
6741 );
6742
6743 window_1.simulate_activation(cx);
6744 assert_eq!(
6745 mem::take(&mut *events.borrow_mut()),
6746 [("window 2", false), ("window 1", true)]
6747 );
6748
6749 window_3.simulate_activation(cx);
6750 assert_eq!(
6751 mem::take(&mut *events.borrow_mut()),
6752 [("window 1", false), ("window 3", true)]
6753 );
6754
6755 window_3.simulate_activation(cx);
6756 assert_eq!(mem::take(&mut *events.borrow_mut()), []);
6757 }
6758
6759 #[crate::test(self)]
6760 fn test_child_view(cx: &mut TestAppContext) {
6761 struct Child {
6762 rendered: Rc<Cell<bool>>,
6763 dropped: Rc<Cell<bool>>,
6764 }
6765
6766 impl super::Entity for Child {
6767 type Event = ();
6768 }
6769
6770 impl super::View for Child {
6771 fn ui_name() -> &'static str {
6772 "child view"
6773 }
6774
6775 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6776 self.rendered.set(true);
6777 Empty::new().into_any()
6778 }
6779 }
6780
6781 impl Drop for Child {
6782 fn drop(&mut self) {
6783 self.dropped.set(true);
6784 }
6785 }
6786
6787 struct Parent {
6788 child: Option<ViewHandle<Child>>,
6789 }
6790
6791 impl super::Entity for Parent {
6792 type Event = ();
6793 }
6794
6795 impl super::View for Parent {
6796 fn ui_name() -> &'static str {
6797 "parent view"
6798 }
6799
6800 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
6801 if let Some(child) = self.child.as_ref() {
6802 ChildView::new(child, cx).into_any()
6803 } else {
6804 Empty::new().into_any()
6805 }
6806 }
6807 }
6808
6809 let child_rendered = Rc::new(Cell::new(false));
6810 let child_dropped = Rc::new(Cell::new(false));
6811 let window = cx.add_window(|cx| Parent {
6812 child: Some(cx.add_view(|_| Child {
6813 rendered: child_rendered.clone(),
6814 dropped: child_dropped.clone(),
6815 })),
6816 });
6817 let root_view = window.root(cx);
6818 assert!(child_rendered.take());
6819 assert!(!child_dropped.take());
6820
6821 root_view.update(cx, |view, cx| {
6822 view.child.take();
6823 cx.notify();
6824 });
6825 assert!(!child_rendered.take());
6826 assert!(child_dropped.take());
6827 }
6828
6829 #[derive(Default)]
6830 struct TestView {
6831 events: Vec<String>,
6832 }
6833
6834 impl Entity for TestView {
6835 type Event = String;
6836 }
6837
6838 impl View for TestView {
6839 fn ui_name() -> &'static str {
6840 "TestView"
6841 }
6842
6843 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6844 Empty::new().into_any()
6845 }
6846 }
6847}