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