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 isn't rendered 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.window.parents.contains_key(&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 has been rendered, 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.window.parents.contains_key(&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<AnyViewHandle> for ViewHandle<T> {
3862 fn eq(&self, other: &AnyViewHandle) -> bool {
3863 self.window_id == other.window_id && self.view_id == other.view_id
3864 }
3865}
3866
3867impl<T> PartialEq<WeakViewHandle<T>> for ViewHandle<T> {
3868 fn eq(&self, other: &WeakViewHandle<T>) -> bool {
3869 self.window_id == other.window_id && self.view_id == other.view_id
3870 }
3871}
3872
3873impl<T> PartialEq<ViewHandle<T>> for WeakViewHandle<T> {
3874 fn eq(&self, other: &ViewHandle<T>) -> bool {
3875 self.window_id == other.window_id && self.view_id == other.view_id
3876 }
3877}
3878
3879impl<T> Eq for ViewHandle<T> {}
3880
3881impl<T> Hash for ViewHandle<T> {
3882 fn hash<H: Hasher>(&self, state: &mut H) {
3883 self.window_id.hash(state);
3884 self.view_id.hash(state);
3885 }
3886}
3887
3888impl<T> Debug for ViewHandle<T> {
3889 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3890 f.debug_struct(&format!("ViewHandle<{}>", type_name::<T>()))
3891 .field("window_id", &self.window_id)
3892 .field("view_id", &self.view_id)
3893 .finish()
3894 }
3895}
3896
3897impl<T: View> Handle<T> for ViewHandle<T> {
3898 type Weak = WeakViewHandle<T>;
3899
3900 fn id(&self) -> usize {
3901 self.view_id
3902 }
3903
3904 fn location(&self) -> EntityLocation {
3905 EntityLocation::View(self.window_id, self.view_id)
3906 }
3907
3908 fn downgrade(&self) -> Self::Weak {
3909 self.downgrade()
3910 }
3911
3912 fn upgrade_from(weak: &Self::Weak, cx: &AppContext) -> Option<Self>
3913 where
3914 Self: Sized,
3915 {
3916 weak.upgrade(cx)
3917 }
3918}
3919
3920pub struct AnyViewHandle {
3921 window_id: usize,
3922 view_id: usize,
3923 view_type: TypeId,
3924 ref_counts: Arc<Mutex<RefCounts>>,
3925
3926 #[cfg(any(test, feature = "test-support"))]
3927 handle_id: usize,
3928}
3929
3930impl AnyViewHandle {
3931 fn new(
3932 window_id: usize,
3933 view_id: usize,
3934 view_type: TypeId,
3935 ref_counts: Arc<Mutex<RefCounts>>,
3936 ) -> Self {
3937 ref_counts.lock().inc_view(window_id, view_id);
3938
3939 #[cfg(any(test, feature = "test-support"))]
3940 let handle_id = ref_counts
3941 .lock()
3942 .leak_detector
3943 .lock()
3944 .handle_created(None, view_id);
3945
3946 Self {
3947 window_id,
3948 view_id,
3949 view_type,
3950 ref_counts,
3951 #[cfg(any(test, feature = "test-support"))]
3952 handle_id,
3953 }
3954 }
3955
3956 pub fn window_id(&self) -> usize {
3957 self.window_id
3958 }
3959
3960 pub fn id(&self) -> usize {
3961 self.view_id
3962 }
3963
3964 pub fn is<T: 'static>(&self) -> bool {
3965 TypeId::of::<T>() == self.view_type
3966 }
3967
3968 pub fn downcast<T: View>(self) -> Option<ViewHandle<T>> {
3969 if self.is::<T>() {
3970 Some(ViewHandle {
3971 any_handle: self,
3972 view_type: PhantomData,
3973 })
3974 } else {
3975 None
3976 }
3977 }
3978
3979 pub fn downcast_ref<T: View>(&self) -> Option<&ViewHandle<T>> {
3980 if self.is::<T>() {
3981 Some(unsafe { mem::transmute(self) })
3982 } else {
3983 None
3984 }
3985 }
3986
3987 pub fn downgrade(&self) -> AnyWeakViewHandle {
3988 AnyWeakViewHandle {
3989 window_id: self.window_id,
3990 view_id: self.view_id,
3991 view_type: self.view_type,
3992 }
3993 }
3994
3995 pub fn view_type(&self) -> TypeId {
3996 self.view_type
3997 }
3998
3999 pub fn debug_json<'a, 'b>(&self, cx: &'b WindowContext<'a>) -> serde_json::Value {
4000 cx.views
4001 .get(&(self.window_id, self.view_id))
4002 .map_or_else(|| serde_json::Value::Null, |view| view.debug_json(cx))
4003 }
4004}
4005
4006impl Clone for AnyViewHandle {
4007 fn clone(&self) -> Self {
4008 Self::new(
4009 self.window_id,
4010 self.view_id,
4011 self.view_type,
4012 self.ref_counts.clone(),
4013 )
4014 }
4015}
4016
4017impl PartialEq for AnyViewHandle {
4018 fn eq(&self, other: &Self) -> bool {
4019 self.window_id == other.window_id && self.view_id == other.view_id
4020 }
4021}
4022
4023impl<T> PartialEq<ViewHandle<T>> for AnyViewHandle {
4024 fn eq(&self, other: &ViewHandle<T>) -> bool {
4025 self.window_id == other.window_id && self.view_id == other.view_id
4026 }
4027}
4028
4029impl Drop for AnyViewHandle {
4030 fn drop(&mut self) {
4031 self.ref_counts
4032 .lock()
4033 .dec_view(self.window_id, self.view_id);
4034 #[cfg(any(test, feature = "test-support"))]
4035 self.ref_counts
4036 .lock()
4037 .leak_detector
4038 .lock()
4039 .handle_dropped(self.view_id, self.handle_id);
4040 }
4041}
4042
4043impl Debug for AnyViewHandle {
4044 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4045 f.debug_struct("AnyViewHandle")
4046 .field("window_id", &self.window_id)
4047 .field("view_id", &self.view_id)
4048 .finish()
4049 }
4050}
4051
4052pub struct AnyModelHandle {
4053 model_id: usize,
4054 model_type: TypeId,
4055 ref_counts: Arc<Mutex<RefCounts>>,
4056
4057 #[cfg(any(test, feature = "test-support"))]
4058 handle_id: usize,
4059}
4060
4061impl AnyModelHandle {
4062 fn new(model_id: usize, model_type: TypeId, ref_counts: Arc<Mutex<RefCounts>>) -> Self {
4063 ref_counts.lock().inc_model(model_id);
4064
4065 #[cfg(any(test, feature = "test-support"))]
4066 let handle_id = ref_counts
4067 .lock()
4068 .leak_detector
4069 .lock()
4070 .handle_created(None, model_id);
4071
4072 Self {
4073 model_id,
4074 model_type,
4075 ref_counts,
4076
4077 #[cfg(any(test, feature = "test-support"))]
4078 handle_id,
4079 }
4080 }
4081
4082 pub fn downcast<T: Entity>(self) -> Option<ModelHandle<T>> {
4083 if self.is::<T>() {
4084 Some(ModelHandle {
4085 any_handle: self,
4086 model_type: PhantomData,
4087 })
4088 } else {
4089 None
4090 }
4091 }
4092
4093 pub fn downgrade(&self) -> AnyWeakModelHandle {
4094 AnyWeakModelHandle {
4095 model_id: self.model_id,
4096 model_type: self.model_type,
4097 }
4098 }
4099
4100 pub fn is<T: Entity>(&self) -> bool {
4101 self.model_type == TypeId::of::<T>()
4102 }
4103
4104 pub fn model_type(&self) -> TypeId {
4105 self.model_type
4106 }
4107}
4108
4109impl Clone for AnyModelHandle {
4110 fn clone(&self) -> Self {
4111 Self::new(self.model_id, self.model_type, self.ref_counts.clone())
4112 }
4113}
4114
4115impl Drop for AnyModelHandle {
4116 fn drop(&mut self) {
4117 let mut ref_counts = self.ref_counts.lock();
4118 ref_counts.dec_model(self.model_id);
4119
4120 #[cfg(any(test, feature = "test-support"))]
4121 ref_counts
4122 .leak_detector
4123 .lock()
4124 .handle_dropped(self.model_id, self.handle_id);
4125 }
4126}
4127
4128#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)]
4129pub struct AnyWeakModelHandle {
4130 model_id: usize,
4131 model_type: TypeId,
4132}
4133
4134impl AnyWeakModelHandle {
4135 pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option<AnyModelHandle> {
4136 cx.read_with(|cx| cx.upgrade_any_model_handle(self))
4137 }
4138
4139 pub fn model_type(&self) -> TypeId {
4140 self.model_type
4141 }
4142
4143 fn is<T: 'static>(&self) -> bool {
4144 TypeId::of::<T>() == self.model_type
4145 }
4146
4147 pub fn downcast<T: Entity>(self) -> Option<WeakModelHandle<T>> {
4148 if self.is::<T>() {
4149 let result = Some(WeakModelHandle {
4150 any_handle: self,
4151 model_type: PhantomData,
4152 });
4153
4154 result
4155 } else {
4156 None
4157 }
4158 }
4159}
4160
4161#[derive(Copy)]
4162pub struct WeakViewHandle<T> {
4163 any_handle: AnyWeakViewHandle,
4164 view_type: PhantomData<T>,
4165}
4166
4167impl<T> Debug for WeakViewHandle<T> {
4168 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4169 f.debug_struct(&format!("WeakViewHandle<{}>", type_name::<T>()))
4170 .field("any_handle", &self.any_handle)
4171 .finish()
4172 }
4173}
4174
4175impl<T> WeakHandle for WeakViewHandle<T> {
4176 fn id(&self) -> usize {
4177 self.view_id
4178 }
4179}
4180
4181impl<V: View> WeakViewHandle<V> {
4182 fn new(window_id: usize, view_id: usize) -> Self {
4183 Self {
4184 any_handle: AnyWeakViewHandle {
4185 window_id,
4186 view_id,
4187 view_type: TypeId::of::<V>(),
4188 },
4189 view_type: PhantomData,
4190 }
4191 }
4192
4193 pub fn id(&self) -> usize {
4194 self.view_id
4195 }
4196
4197 pub fn window_id(&self) -> usize {
4198 self.window_id
4199 }
4200
4201 pub fn into_any(self) -> AnyWeakViewHandle {
4202 self.any_handle
4203 }
4204
4205 pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option<ViewHandle<V>> {
4206 cx.read_with(|cx| cx.upgrade_view_handle(self))
4207 }
4208
4209 pub fn read_with<T>(
4210 &self,
4211 cx: &AsyncAppContext,
4212 read: impl FnOnce(&V, &ViewContext<V>) -> T,
4213 ) -> Result<T> {
4214 cx.read(|cx| {
4215 let handle = cx
4216 .upgrade_view_handle(self)
4217 .ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?;
4218 cx.read_window(self.window_id, |cx| handle.read_with(cx, read))
4219 .ok_or_else(|| anyhow!("window was removed"))
4220 })
4221 }
4222
4223 pub fn update<T>(
4224 &self,
4225 cx: &mut AsyncAppContext,
4226 update: impl FnOnce(&mut V, &mut ViewContext<V>) -> T,
4227 ) -> Result<T> {
4228 cx.update(|cx| {
4229 let handle = cx
4230 .upgrade_view_handle(self)
4231 .ok_or_else(|| anyhow!("view {} was dropped", V::ui_name()))?;
4232 cx.update_window(self.window_id, |cx| handle.update(cx, update))
4233 .ok_or_else(|| anyhow!("window was removed"))
4234 })
4235 }
4236}
4237
4238impl<T> Deref for WeakViewHandle<T> {
4239 type Target = AnyWeakViewHandle;
4240
4241 fn deref(&self) -> &Self::Target {
4242 &self.any_handle
4243 }
4244}
4245
4246impl<T> Clone for WeakViewHandle<T> {
4247 fn clone(&self) -> Self {
4248 Self {
4249 any_handle: self.any_handle.clone(),
4250 view_type: PhantomData,
4251 }
4252 }
4253}
4254
4255impl<T> PartialEq for WeakViewHandle<T> {
4256 fn eq(&self, other: &Self) -> bool {
4257 self.window_id == other.window_id && self.view_id == other.view_id
4258 }
4259}
4260
4261impl<T> Eq for WeakViewHandle<T> {}
4262
4263impl<T> Hash for WeakViewHandle<T> {
4264 fn hash<H: Hasher>(&self, state: &mut H) {
4265 self.any_handle.hash(state);
4266 }
4267}
4268
4269#[derive(Debug, Clone, Copy, Eq, PartialEq)]
4270pub struct AnyWeakViewHandle {
4271 window_id: usize,
4272 view_id: usize,
4273 view_type: TypeId,
4274}
4275
4276impl AnyWeakViewHandle {
4277 pub fn id(&self) -> usize {
4278 self.view_id
4279 }
4280
4281 fn is<T: 'static>(&self) -> bool {
4282 TypeId::of::<T>() == self.view_type
4283 }
4284
4285 pub fn upgrade(&self, cx: &impl BorrowAppContext) -> Option<AnyViewHandle> {
4286 cx.read_with(|cx| cx.upgrade_any_view_handle(self))
4287 }
4288
4289 pub fn downcast<T: View>(self) -> Option<WeakViewHandle<T>> {
4290 if self.is::<T>() {
4291 Some(WeakViewHandle {
4292 any_handle: self,
4293 view_type: PhantomData,
4294 })
4295 } else {
4296 None
4297 }
4298 }
4299}
4300
4301impl Hash for AnyWeakViewHandle {
4302 fn hash<H: Hasher>(&self, state: &mut H) {
4303 self.window_id.hash(state);
4304 self.view_id.hash(state);
4305 self.view_type.hash(state);
4306 }
4307}
4308
4309#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4310pub struct ElementStateId {
4311 view_id: usize,
4312 element_id: usize,
4313 tag: TypeId,
4314}
4315
4316pub struct ElementStateHandle<T> {
4317 value_type: PhantomData<T>,
4318 id: ElementStateId,
4319 ref_counts: Weak<Mutex<RefCounts>>,
4320}
4321
4322impl<T: 'static> ElementStateHandle<T> {
4323 fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
4324 ref_counts.lock().inc_element_state(id, frame_id);
4325 Self {
4326 value_type: PhantomData,
4327 id,
4328 ref_counts: Arc::downgrade(ref_counts),
4329 }
4330 }
4331
4332 pub fn id(&self) -> ElementStateId {
4333 self.id
4334 }
4335
4336 pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
4337 cx.element_states
4338 .get(&self.id)
4339 .unwrap()
4340 .downcast_ref()
4341 .unwrap()
4342 }
4343
4344 pub fn update<C, D, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
4345 where
4346 C: DerefMut<Target = D>,
4347 D: DerefMut<Target = AppContext>,
4348 {
4349 let mut element_state = cx.deref_mut().element_states.remove(&self.id).unwrap();
4350 let result = f(element_state.downcast_mut().unwrap(), cx);
4351 cx.deref_mut().element_states.insert(self.id, element_state);
4352 result
4353 }
4354}
4355
4356impl<T> Drop for ElementStateHandle<T> {
4357 fn drop(&mut self) {
4358 if let Some(ref_counts) = self.ref_counts.upgrade() {
4359 ref_counts.lock().dec_element_state(self.id);
4360 }
4361 }
4362}
4363
4364#[must_use]
4365pub enum Subscription {
4366 Subscription(callback_collection::Subscription<usize, SubscriptionCallback>),
4367 Observation(callback_collection::Subscription<usize, ObservationCallback>),
4368 GlobalSubscription(callback_collection::Subscription<TypeId, GlobalSubscriptionCallback>),
4369 GlobalObservation(callback_collection::Subscription<TypeId, GlobalObservationCallback>),
4370 FocusObservation(callback_collection::Subscription<usize, FocusObservationCallback>),
4371 WindowActivationObservation(callback_collection::Subscription<usize, WindowActivationCallback>),
4372 WindowFullscreenObservation(callback_collection::Subscription<usize, WindowFullscreenCallback>),
4373 WindowBoundsObservation(callback_collection::Subscription<usize, WindowBoundsCallback>),
4374 KeystrokeObservation(callback_collection::Subscription<usize, KeystrokeCallback>),
4375 ReleaseObservation(callback_collection::Subscription<usize, ReleaseObservationCallback>),
4376 ActionObservation(callback_collection::Subscription<(), ActionObservationCallback>),
4377 ActiveLabeledTasksObservation(
4378 callback_collection::Subscription<(), ActiveLabeledTasksCallback>,
4379 ),
4380}
4381
4382impl Subscription {
4383 pub fn id(&self) -> usize {
4384 match self {
4385 Subscription::Subscription(subscription) => subscription.id(),
4386 Subscription::Observation(subscription) => subscription.id(),
4387 Subscription::GlobalSubscription(subscription) => subscription.id(),
4388 Subscription::GlobalObservation(subscription) => subscription.id(),
4389 Subscription::FocusObservation(subscription) => subscription.id(),
4390 Subscription::WindowActivationObservation(subscription) => subscription.id(),
4391 Subscription::WindowFullscreenObservation(subscription) => subscription.id(),
4392 Subscription::WindowBoundsObservation(subscription) => subscription.id(),
4393 Subscription::KeystrokeObservation(subscription) => subscription.id(),
4394 Subscription::ReleaseObservation(subscription) => subscription.id(),
4395 Subscription::ActionObservation(subscription) => subscription.id(),
4396 Subscription::ActiveLabeledTasksObservation(subscription) => subscription.id(),
4397 }
4398 }
4399
4400 pub fn detach(&mut self) {
4401 match self {
4402 Subscription::Subscription(subscription) => subscription.detach(),
4403 Subscription::GlobalSubscription(subscription) => subscription.detach(),
4404 Subscription::Observation(subscription) => subscription.detach(),
4405 Subscription::GlobalObservation(subscription) => subscription.detach(),
4406 Subscription::FocusObservation(subscription) => subscription.detach(),
4407 Subscription::KeystrokeObservation(subscription) => subscription.detach(),
4408 Subscription::WindowActivationObservation(subscription) => subscription.detach(),
4409 Subscription::WindowFullscreenObservation(subscription) => subscription.detach(),
4410 Subscription::WindowBoundsObservation(subscription) => subscription.detach(),
4411 Subscription::ReleaseObservation(subscription) => subscription.detach(),
4412 Subscription::ActionObservation(subscription) => subscription.detach(),
4413 Subscription::ActiveLabeledTasksObservation(subscription) => subscription.detach(),
4414 }
4415 }
4416}
4417
4418#[cfg(test)]
4419mod tests {
4420 use super::*;
4421 use crate::{
4422 actions,
4423 elements::*,
4424 impl_actions,
4425 platform::{MouseButton, MouseButtonEvent},
4426 window::ChildView,
4427 };
4428 use itertools::Itertools;
4429 use postage::{sink::Sink, stream::Stream};
4430 use serde::Deserialize;
4431 use smol::future::poll_once;
4432 use std::{
4433 cell::Cell,
4434 sync::atomic::{AtomicBool, AtomicUsize, Ordering::SeqCst},
4435 };
4436
4437 #[crate::test(self)]
4438 fn test_model_handles(cx: &mut AppContext) {
4439 struct Model {
4440 other: Option<ModelHandle<Model>>,
4441 events: Vec<String>,
4442 }
4443
4444 impl Entity for Model {
4445 type Event = usize;
4446 }
4447
4448 impl Model {
4449 fn new(other: Option<ModelHandle<Self>>, cx: &mut ModelContext<Self>) -> Self {
4450 if let Some(other) = other.as_ref() {
4451 cx.observe(other, |me, _, _| {
4452 me.events.push("notified".into());
4453 })
4454 .detach();
4455 cx.subscribe(other, |me, _, event, _| {
4456 me.events.push(format!("observed event {}", event));
4457 })
4458 .detach();
4459 }
4460
4461 Self {
4462 other,
4463 events: Vec::new(),
4464 }
4465 }
4466 }
4467
4468 let handle_1 = cx.add_model(|cx| Model::new(None, cx));
4469 let handle_2 = cx.add_model(|cx| Model::new(Some(handle_1.clone()), cx));
4470 assert_eq!(cx.models.len(), 2);
4471
4472 handle_1.update(cx, |model, cx| {
4473 model.events.push("updated".into());
4474 cx.emit(1);
4475 cx.notify();
4476 cx.emit(2);
4477 });
4478 assert_eq!(handle_1.read(cx).events, vec!["updated".to_string()]);
4479 assert_eq!(
4480 handle_2.read(cx).events,
4481 vec![
4482 "observed event 1".to_string(),
4483 "notified".to_string(),
4484 "observed event 2".to_string(),
4485 ]
4486 );
4487
4488 handle_2.update(cx, |model, _| {
4489 drop(handle_1);
4490 model.other.take();
4491 });
4492
4493 assert_eq!(cx.models.len(), 1);
4494 assert!(cx.subscriptions.is_empty());
4495 assert!(cx.observations.is_empty());
4496 }
4497
4498 #[crate::test(self)]
4499 fn test_model_events(cx: &mut AppContext) {
4500 #[derive(Default)]
4501 struct Model {
4502 events: Vec<usize>,
4503 }
4504
4505 impl Entity for Model {
4506 type Event = usize;
4507 }
4508
4509 let handle_1 = cx.add_model(|_| Model::default());
4510 let handle_2 = cx.add_model(|_| Model::default());
4511
4512 handle_1.update(cx, |_, cx| {
4513 cx.subscribe(&handle_2, move |model: &mut Model, emitter, event, cx| {
4514 model.events.push(*event);
4515
4516 cx.subscribe(&emitter, |model, _, event, _| {
4517 model.events.push(*event * 2);
4518 })
4519 .detach();
4520 })
4521 .detach();
4522 });
4523
4524 handle_2.update(cx, |_, c| c.emit(7));
4525 assert_eq!(handle_1.read(cx).events, vec![7]);
4526
4527 handle_2.update(cx, |_, c| c.emit(5));
4528 assert_eq!(handle_1.read(cx).events, vec![7, 5, 10]);
4529 }
4530
4531 #[crate::test(self)]
4532 fn test_model_emit_before_subscribe_in_same_update_cycle(cx: &mut AppContext) {
4533 #[derive(Default)]
4534 struct Model;
4535
4536 impl Entity for Model {
4537 type Event = ();
4538 }
4539
4540 let events = Rc::new(RefCell::new(Vec::new()));
4541 cx.add_model(|cx| {
4542 drop(cx.subscribe(&cx.handle(), {
4543 let events = events.clone();
4544 move |_, _, _, _| events.borrow_mut().push("dropped before flush")
4545 }));
4546 cx.subscribe(&cx.handle(), {
4547 let events = events.clone();
4548 move |_, _, _, _| events.borrow_mut().push("before emit")
4549 })
4550 .detach();
4551 cx.emit(());
4552 cx.subscribe(&cx.handle(), {
4553 let events = events.clone();
4554 move |_, _, _, _| events.borrow_mut().push("after emit")
4555 })
4556 .detach();
4557 Model
4558 });
4559 assert_eq!(*events.borrow(), ["before emit"]);
4560 }
4561
4562 #[crate::test(self)]
4563 fn test_observe_and_notify_from_model(cx: &mut AppContext) {
4564 #[derive(Default)]
4565 struct Model {
4566 count: usize,
4567 events: Vec<usize>,
4568 }
4569
4570 impl Entity for Model {
4571 type Event = ();
4572 }
4573
4574 let handle_1 = cx.add_model(|_| Model::default());
4575 let handle_2 = cx.add_model(|_| Model::default());
4576
4577 handle_1.update(cx, |_, c| {
4578 c.observe(&handle_2, move |model, observed, c| {
4579 model.events.push(observed.read(c).count);
4580 c.observe(&observed, |model, observed, c| {
4581 model.events.push(observed.read(c).count * 2);
4582 })
4583 .detach();
4584 })
4585 .detach();
4586 });
4587
4588 handle_2.update(cx, |model, c| {
4589 model.count = 7;
4590 c.notify()
4591 });
4592 assert_eq!(handle_1.read(cx).events, vec![7]);
4593
4594 handle_2.update(cx, |model, c| {
4595 model.count = 5;
4596 c.notify()
4597 });
4598 assert_eq!(handle_1.read(cx).events, vec![7, 5, 10])
4599 }
4600
4601 #[crate::test(self)]
4602 fn test_model_notify_before_observe_in_same_update_cycle(cx: &mut AppContext) {
4603 #[derive(Default)]
4604 struct Model;
4605
4606 impl Entity for Model {
4607 type Event = ();
4608 }
4609
4610 let events = Rc::new(RefCell::new(Vec::new()));
4611 cx.add_model(|cx| {
4612 drop(cx.observe(&cx.handle(), {
4613 let events = events.clone();
4614 move |_, _, _| events.borrow_mut().push("dropped before flush")
4615 }));
4616 cx.observe(&cx.handle(), {
4617 let events = events.clone();
4618 move |_, _, _| events.borrow_mut().push("before notify")
4619 })
4620 .detach();
4621 cx.notify();
4622 cx.observe(&cx.handle(), {
4623 let events = events.clone();
4624 move |_, _, _| events.borrow_mut().push("after notify")
4625 })
4626 .detach();
4627 Model
4628 });
4629 assert_eq!(*events.borrow(), ["before notify"]);
4630 }
4631
4632 #[crate::test(self)]
4633 fn test_defer_and_after_window_update(cx: &mut TestAppContext) {
4634 struct View {
4635 render_count: usize,
4636 }
4637
4638 impl Entity for View {
4639 type Event = usize;
4640 }
4641
4642 impl super::View for View {
4643 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
4644 post_inc(&mut self.render_count);
4645 Empty::new().into_any()
4646 }
4647
4648 fn ui_name() -> &'static str {
4649 "View"
4650 }
4651 }
4652
4653 let (_, view) = cx.add_window(|_| View { render_count: 0 });
4654 let called_defer = Rc::new(AtomicBool::new(false));
4655 let called_after_window_update = Rc::new(AtomicBool::new(false));
4656
4657 view.update(cx, |this, cx| {
4658 assert_eq!(this.render_count, 1);
4659 cx.defer({
4660 let called_defer = called_defer.clone();
4661 move |this, _| {
4662 assert_eq!(this.render_count, 1);
4663 called_defer.store(true, SeqCst);
4664 }
4665 });
4666 cx.after_window_update({
4667 let called_after_window_update = called_after_window_update.clone();
4668 move |this, cx| {
4669 assert_eq!(this.render_count, 2);
4670 called_after_window_update.store(true, SeqCst);
4671 cx.notify();
4672 }
4673 });
4674 assert!(!called_defer.load(SeqCst));
4675 assert!(!called_after_window_update.load(SeqCst));
4676 cx.notify();
4677 });
4678
4679 assert!(called_defer.load(SeqCst));
4680 assert!(called_after_window_update.load(SeqCst));
4681 assert_eq!(view.read_with(cx, |view, _| view.render_count), 3);
4682 }
4683
4684 #[crate::test(self)]
4685 fn test_view_handles(cx: &mut TestAppContext) {
4686 struct View {
4687 other: Option<ViewHandle<View>>,
4688 events: Vec<String>,
4689 }
4690
4691 impl Entity for View {
4692 type Event = usize;
4693 }
4694
4695 impl super::View for View {
4696 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
4697 Empty::new().into_any()
4698 }
4699
4700 fn ui_name() -> &'static str {
4701 "View"
4702 }
4703 }
4704
4705 impl View {
4706 fn new(other: Option<ViewHandle<View>>, cx: &mut ViewContext<Self>) -> Self {
4707 if let Some(other) = other.as_ref() {
4708 cx.subscribe(other, |me, _, event, _| {
4709 me.events.push(format!("observed event {}", event));
4710 })
4711 .detach();
4712 }
4713 Self {
4714 other,
4715 events: Vec::new(),
4716 }
4717 }
4718 }
4719
4720 let (window_id, _root_view) = cx.add_window(|cx| View::new(None, cx));
4721 let handle_1 = cx.add_view(window_id, |cx| View::new(None, cx));
4722 let handle_2 = cx.add_view(window_id, |cx| View::new(Some(handle_1.clone()), cx));
4723 assert_eq!(cx.read(|cx| cx.views.len()), 3);
4724
4725 handle_1.update(cx, |view, cx| {
4726 view.events.push("updated".into());
4727 cx.emit(1);
4728 cx.emit(2);
4729 });
4730 handle_1.read_with(cx, |view, _| {
4731 assert_eq!(view.events, vec!["updated".to_string()]);
4732 });
4733 handle_2.read_with(cx, |view, _| {
4734 assert_eq!(
4735 view.events,
4736 vec![
4737 "observed event 1".to_string(),
4738 "observed event 2".to_string(),
4739 ]
4740 );
4741 });
4742
4743 handle_2.update(cx, |view, _| {
4744 drop(handle_1);
4745 view.other.take();
4746 });
4747
4748 cx.read(|cx| {
4749 assert_eq!(cx.views.len(), 2);
4750 assert!(cx.subscriptions.is_empty());
4751 assert!(cx.observations.is_empty());
4752 });
4753 }
4754
4755 #[crate::test(self)]
4756 fn test_add_window(cx: &mut AppContext) {
4757 struct View {
4758 mouse_down_count: Arc<AtomicUsize>,
4759 }
4760
4761 impl Entity for View {
4762 type Event = ();
4763 }
4764
4765 impl super::View for View {
4766 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
4767 enum Handler {}
4768 let mouse_down_count = self.mouse_down_count.clone();
4769 MouseEventHandler::<Handler, _>::new(0, cx, |_, _| Empty::new())
4770 .on_down(MouseButton::Left, move |_, _, _| {
4771 mouse_down_count.fetch_add(1, SeqCst);
4772 })
4773 .into_any()
4774 }
4775
4776 fn ui_name() -> &'static str {
4777 "View"
4778 }
4779 }
4780
4781 let mouse_down_count = Arc::new(AtomicUsize::new(0));
4782 let (window_id, _) = cx.add_window(Default::default(), |_| View {
4783 mouse_down_count: mouse_down_count.clone(),
4784 });
4785
4786 cx.update_window(window_id, |cx| {
4787 // Ensure window's root element is in a valid lifecycle state.
4788 cx.dispatch_event(
4789 Event::MouseDown(MouseButtonEvent {
4790 position: Default::default(),
4791 button: MouseButton::Left,
4792 modifiers: Default::default(),
4793 click_count: 1,
4794 }),
4795 false,
4796 );
4797 assert_eq!(mouse_down_count.load(SeqCst), 1);
4798 });
4799 }
4800
4801 #[crate::test(self)]
4802 fn test_entity_release_hooks(cx: &mut AppContext) {
4803 struct Model {
4804 released: Rc<Cell<bool>>,
4805 }
4806
4807 struct View {
4808 released: Rc<Cell<bool>>,
4809 }
4810
4811 impl Entity for Model {
4812 type Event = ();
4813
4814 fn release(&mut self, _: &mut AppContext) {
4815 self.released.set(true);
4816 }
4817 }
4818
4819 impl Entity for View {
4820 type Event = ();
4821
4822 fn release(&mut self, _: &mut AppContext) {
4823 self.released.set(true);
4824 }
4825 }
4826
4827 impl super::View for View {
4828 fn ui_name() -> &'static str {
4829 "View"
4830 }
4831
4832 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
4833 Empty::new().into_any()
4834 }
4835 }
4836
4837 let model_released = Rc::new(Cell::new(false));
4838 let model_release_observed = Rc::new(Cell::new(false));
4839 let view_released = Rc::new(Cell::new(false));
4840 let view_release_observed = Rc::new(Cell::new(false));
4841
4842 let model = cx.add_model(|_| Model {
4843 released: model_released.clone(),
4844 });
4845 let (window_id, view) = cx.add_window(Default::default(), |_| View {
4846 released: view_released.clone(),
4847 });
4848 assert!(!model_released.get());
4849 assert!(!view_released.get());
4850
4851 cx.observe_release(&model, {
4852 let model_release_observed = model_release_observed.clone();
4853 move |_, _| model_release_observed.set(true)
4854 })
4855 .detach();
4856 cx.observe_release(&view, {
4857 let view_release_observed = view_release_observed.clone();
4858 move |_, _| view_release_observed.set(true)
4859 })
4860 .detach();
4861
4862 cx.update(move |_| {
4863 drop(model);
4864 });
4865 assert!(model_released.get());
4866 assert!(model_release_observed.get());
4867
4868 drop(view);
4869 cx.update_window(window_id, |cx| cx.remove_window());
4870 assert!(view_released.get());
4871 assert!(view_release_observed.get());
4872 }
4873
4874 #[crate::test(self)]
4875 fn test_view_events(cx: &mut TestAppContext) {
4876 struct Model;
4877
4878 impl Entity for Model {
4879 type Event = String;
4880 }
4881
4882 let (window_id, handle_1) = cx.add_window(|_| TestView::default());
4883 let handle_2 = cx.add_view(window_id, |_| TestView::default());
4884 let handle_3 = cx.add_model(|_| Model);
4885
4886 handle_1.update(cx, |_, cx| {
4887 cx.subscribe(&handle_2, move |me, emitter, event, cx| {
4888 me.events.push(event.clone());
4889
4890 cx.subscribe(&emitter, |me, _, event, _| {
4891 me.events.push(format!("{event} from inner"));
4892 })
4893 .detach();
4894 })
4895 .detach();
4896
4897 cx.subscribe(&handle_3, |me, _, event, _| {
4898 me.events.push(event.clone());
4899 })
4900 .detach();
4901 });
4902
4903 handle_2.update(cx, |_, c| c.emit("7".into()));
4904 handle_1.read_with(cx, |view, _| assert_eq!(view.events, ["7"]));
4905
4906 handle_2.update(cx, |_, c| c.emit("5".into()));
4907 handle_1.read_with(cx, |view, _| {
4908 assert_eq!(view.events, ["7", "5", "5 from inner"])
4909 });
4910
4911 handle_3.update(cx, |_, c| c.emit("9".into()));
4912 handle_1.read_with(cx, |view, _| {
4913 assert_eq!(view.events, ["7", "5", "5 from inner", "9"])
4914 });
4915 }
4916
4917 #[crate::test(self)]
4918 fn test_global_events(cx: &mut AppContext) {
4919 #[derive(Clone, Debug, Eq, PartialEq)]
4920 struct GlobalEvent(u64);
4921
4922 let events = Rc::new(RefCell::new(Vec::new()));
4923 let first_subscription;
4924 let second_subscription;
4925
4926 {
4927 let events = events.clone();
4928 first_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
4929 events.borrow_mut().push(("First", e.clone()));
4930 });
4931 }
4932
4933 {
4934 let events = events.clone();
4935 second_subscription = cx.subscribe_global(move |e: &GlobalEvent, _| {
4936 events.borrow_mut().push(("Second", e.clone()));
4937 });
4938 }
4939
4940 cx.update(|cx| {
4941 cx.emit_global(GlobalEvent(1));
4942 cx.emit_global(GlobalEvent(2));
4943 });
4944
4945 drop(first_subscription);
4946
4947 cx.update(|cx| {
4948 cx.emit_global(GlobalEvent(3));
4949 });
4950
4951 drop(second_subscription);
4952
4953 cx.update(|cx| {
4954 cx.emit_global(GlobalEvent(4));
4955 });
4956
4957 assert_eq!(
4958 &*events.borrow(),
4959 &[
4960 ("First", GlobalEvent(1)),
4961 ("Second", GlobalEvent(1)),
4962 ("First", GlobalEvent(2)),
4963 ("Second", GlobalEvent(2)),
4964 ("Second", GlobalEvent(3)),
4965 ]
4966 );
4967 }
4968
4969 #[crate::test(self)]
4970 fn test_global_events_emitted_before_subscription_in_same_update_cycle(cx: &mut AppContext) {
4971 let events = Rc::new(RefCell::new(Vec::new()));
4972 cx.update(|cx| {
4973 {
4974 let events = events.clone();
4975 drop(cx.subscribe_global(move |_: &(), _| {
4976 events.borrow_mut().push("dropped before emit");
4977 }));
4978 }
4979
4980 {
4981 let events = events.clone();
4982 cx.subscribe_global(move |_: &(), _| {
4983 events.borrow_mut().push("before emit");
4984 })
4985 .detach();
4986 }
4987
4988 cx.emit_global(());
4989
4990 {
4991 let events = events.clone();
4992 cx.subscribe_global(move |_: &(), _| {
4993 events.borrow_mut().push("after emit");
4994 })
4995 .detach();
4996 }
4997 });
4998
4999 assert_eq!(*events.borrow(), ["before emit"]);
5000 }
5001
5002 #[crate::test(self)]
5003 fn test_global_nested_events(cx: &mut AppContext) {
5004 #[derive(Clone, Debug, Eq, PartialEq)]
5005 struct GlobalEvent(u64);
5006
5007 let events = Rc::new(RefCell::new(Vec::new()));
5008
5009 {
5010 let events = events.clone();
5011 cx.subscribe_global(move |e: &GlobalEvent, cx| {
5012 events.borrow_mut().push(("Outer", e.clone()));
5013
5014 if e.0 == 1 {
5015 let events = events.clone();
5016 cx.subscribe_global(move |e: &GlobalEvent, _| {
5017 events.borrow_mut().push(("Inner", e.clone()));
5018 })
5019 .detach();
5020 }
5021 })
5022 .detach();
5023 }
5024
5025 cx.update(|cx| {
5026 cx.emit_global(GlobalEvent(1));
5027 cx.emit_global(GlobalEvent(2));
5028 cx.emit_global(GlobalEvent(3));
5029 });
5030 cx.update(|cx| {
5031 cx.emit_global(GlobalEvent(4));
5032 });
5033
5034 assert_eq!(
5035 &*events.borrow(),
5036 &[
5037 ("Outer", GlobalEvent(1)),
5038 ("Outer", GlobalEvent(2)),
5039 ("Outer", GlobalEvent(3)),
5040 ("Outer", GlobalEvent(4)),
5041 ("Inner", GlobalEvent(4)),
5042 ]
5043 );
5044 }
5045
5046 #[crate::test(self)]
5047 fn test_global(cx: &mut AppContext) {
5048 type Global = usize;
5049
5050 let observation_count = Rc::new(RefCell::new(0));
5051 let subscription = cx.observe_global::<Global, _>({
5052 let observation_count = observation_count.clone();
5053 move |_| {
5054 *observation_count.borrow_mut() += 1;
5055 }
5056 });
5057
5058 assert!(!cx.has_global::<Global>());
5059 assert_eq!(cx.default_global::<Global>(), &0);
5060 assert_eq!(*observation_count.borrow(), 1);
5061 assert!(cx.has_global::<Global>());
5062 assert_eq!(
5063 cx.update_global::<Global, _, _>(|global, _| {
5064 *global = 1;
5065 "Update Result"
5066 }),
5067 "Update Result"
5068 );
5069 assert_eq!(*observation_count.borrow(), 2);
5070 assert_eq!(cx.global::<Global>(), &1);
5071
5072 drop(subscription);
5073 cx.update_global::<Global, _, _>(|global, _| {
5074 *global = 2;
5075 });
5076 assert_eq!(*observation_count.borrow(), 2);
5077
5078 type OtherGlobal = f32;
5079
5080 let observation_count = Rc::new(RefCell::new(0));
5081 cx.observe_global::<OtherGlobal, _>({
5082 let observation_count = observation_count.clone();
5083 move |_| {
5084 *observation_count.borrow_mut() += 1;
5085 }
5086 })
5087 .detach();
5088
5089 assert_eq!(
5090 cx.update_default_global::<OtherGlobal, _, _>(|global, _| {
5091 assert_eq!(global, &0.0);
5092 *global = 2.0;
5093 "Default update result"
5094 }),
5095 "Default update result"
5096 );
5097 assert_eq!(cx.global::<OtherGlobal>(), &2.0);
5098 assert_eq!(*observation_count.borrow(), 1);
5099 }
5100
5101 #[crate::test(self)]
5102 fn test_dropping_subscribers(cx: &mut TestAppContext) {
5103 struct Model;
5104
5105 impl Entity for Model {
5106 type Event = ();
5107 }
5108
5109 let (window_id, _root_view) = cx.add_window(|_| TestView::default());
5110 let observing_view = cx.add_view(window_id, |_| TestView::default());
5111 let emitting_view = cx.add_view(window_id, |_| TestView::default());
5112 let observing_model = cx.add_model(|_| Model);
5113 let observed_model = cx.add_model(|_| Model);
5114
5115 observing_view.update(cx, |_, cx| {
5116 cx.subscribe(&emitting_view, |_, _, _, _| {}).detach();
5117 cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5118 });
5119 observing_model.update(cx, |_, cx| {
5120 cx.subscribe(&observed_model, |_, _, _, _| {}).detach();
5121 });
5122
5123 cx.update(|_| {
5124 drop(observing_view);
5125 drop(observing_model);
5126 });
5127
5128 emitting_view.update(cx, |_, cx| cx.emit(Default::default()));
5129 observed_model.update(cx, |_, cx| cx.emit(()));
5130 }
5131
5132 #[crate::test(self)]
5133 fn test_view_emit_before_subscribe_in_same_update_cycle(cx: &mut AppContext) {
5134 let (_, view) = cx.add_window::<TestView, _>(Default::default(), |cx| {
5135 drop(cx.subscribe(&cx.handle(), {
5136 move |this, _, _, _| this.events.push("dropped before flush".into())
5137 }));
5138 cx.subscribe(&cx.handle(), {
5139 move |this, _, _, _| this.events.push("before emit".into())
5140 })
5141 .detach();
5142 cx.emit("the event".into());
5143 cx.subscribe(&cx.handle(), {
5144 move |this, _, _, _| this.events.push("after emit".into())
5145 })
5146 .detach();
5147 TestView { events: Vec::new() }
5148 });
5149
5150 assert_eq!(view.read(cx).events, ["before emit"]);
5151 }
5152
5153 #[crate::test(self)]
5154 fn test_observe_and_notify_from_view(cx: &mut TestAppContext) {
5155 #[derive(Default)]
5156 struct Model {
5157 state: String,
5158 }
5159
5160 impl Entity for Model {
5161 type Event = ();
5162 }
5163
5164 let (_, view) = cx.add_window(|_| TestView::default());
5165 let model = cx.add_model(|_| Model {
5166 state: "old-state".into(),
5167 });
5168
5169 view.update(cx, |_, c| {
5170 c.observe(&model, |me, observed, cx| {
5171 me.events.push(observed.read(cx).state.clone())
5172 })
5173 .detach();
5174 });
5175
5176 model.update(cx, |model, cx| {
5177 model.state = "new-state".into();
5178 cx.notify();
5179 });
5180 view.read_with(cx, |view, _| assert_eq!(view.events, ["new-state"]));
5181 }
5182
5183 #[crate::test(self)]
5184 fn test_view_notify_before_observe_in_same_update_cycle(cx: &mut AppContext) {
5185 let (_, view) = cx.add_window::<TestView, _>(Default::default(), |cx| {
5186 drop(cx.observe(&cx.handle(), {
5187 move |this, _, _| this.events.push("dropped before flush".into())
5188 }));
5189 cx.observe(&cx.handle(), {
5190 move |this, _, _| this.events.push("before notify".into())
5191 })
5192 .detach();
5193 cx.notify();
5194 cx.observe(&cx.handle(), {
5195 move |this, _, _| this.events.push("after notify".into())
5196 })
5197 .detach();
5198 TestView { events: Vec::new() }
5199 });
5200
5201 assert_eq!(view.read(cx).events, ["before notify"]);
5202 }
5203
5204 #[crate::test(self)]
5205 fn test_notify_and_drop_observe_subscription_in_same_update_cycle(cx: &mut TestAppContext) {
5206 struct Model;
5207 impl Entity for Model {
5208 type Event = ();
5209 }
5210
5211 let model = cx.add_model(|_| Model);
5212 let (_, view) = cx.add_window(|_| TestView::default());
5213
5214 view.update(cx, |_, cx| {
5215 model.update(cx, |_, cx| cx.notify());
5216 drop(cx.observe(&model, move |this, _, _| {
5217 this.events.push("model notified".into());
5218 }));
5219 model.update(cx, |_, cx| cx.notify());
5220 });
5221
5222 for _ in 0..3 {
5223 model.update(cx, |_, cx| cx.notify());
5224 }
5225 view.read_with(cx, |view, _| assert_eq!(view.events, Vec::<&str>::new()));
5226 }
5227
5228 #[crate::test(self)]
5229 fn test_dropping_observers(cx: &mut TestAppContext) {
5230 struct Model;
5231
5232 impl Entity for Model {
5233 type Event = ();
5234 }
5235
5236 let (window_id, _root_view) = cx.add_window(|_| TestView::default());
5237 let observing_view = cx.add_view(window_id, |_| TestView::default());
5238 let observing_model = cx.add_model(|_| Model);
5239 let observed_model = cx.add_model(|_| Model);
5240
5241 observing_view.update(cx, |_, cx| {
5242 cx.observe(&observed_model, |_, _, _| {}).detach();
5243 });
5244 observing_model.update(cx, |_, cx| {
5245 cx.observe(&observed_model, |_, _, _| {}).detach();
5246 });
5247
5248 cx.update(|_| {
5249 drop(observing_view);
5250 drop(observing_model);
5251 });
5252
5253 observed_model.update(cx, |_, cx| cx.notify());
5254 }
5255
5256 #[crate::test(self)]
5257 fn test_dropping_subscriptions_during_callback(cx: &mut TestAppContext) {
5258 struct Model;
5259
5260 impl Entity for Model {
5261 type Event = u64;
5262 }
5263
5264 // Events
5265 let observing_model = cx.add_model(|_| Model);
5266 let observed_model = cx.add_model(|_| Model);
5267
5268 let events = Rc::new(RefCell::new(Vec::new()));
5269
5270 observing_model.update(cx, |_, cx| {
5271 let events = events.clone();
5272 let subscription = Rc::new(RefCell::new(None));
5273 *subscription.borrow_mut() = Some(cx.subscribe(&observed_model, {
5274 let subscription = subscription.clone();
5275 move |_, _, e, _| {
5276 subscription.borrow_mut().take();
5277 events.borrow_mut().push(*e);
5278 }
5279 }));
5280 });
5281
5282 observed_model.update(cx, |_, cx| {
5283 cx.emit(1);
5284 cx.emit(2);
5285 });
5286
5287 assert_eq!(*events.borrow(), [1]);
5288
5289 // Global Events
5290 #[derive(Clone, Debug, Eq, PartialEq)]
5291 struct GlobalEvent(u64);
5292
5293 let events = Rc::new(RefCell::new(Vec::new()));
5294
5295 {
5296 let events = events.clone();
5297 let subscription = Rc::new(RefCell::new(None));
5298 *subscription.borrow_mut() = Some(cx.subscribe_global({
5299 let subscription = subscription.clone();
5300 move |e: &GlobalEvent, _| {
5301 subscription.borrow_mut().take();
5302 events.borrow_mut().push(e.clone());
5303 }
5304 }));
5305 }
5306
5307 cx.update(|cx| {
5308 cx.emit_global(GlobalEvent(1));
5309 cx.emit_global(GlobalEvent(2));
5310 });
5311
5312 assert_eq!(*events.borrow(), [GlobalEvent(1)]);
5313
5314 // Model Observation
5315 let observing_model = cx.add_model(|_| Model);
5316 let observed_model = cx.add_model(|_| Model);
5317
5318 let observation_count = Rc::new(RefCell::new(0));
5319
5320 observing_model.update(cx, |_, cx| {
5321 let observation_count = observation_count.clone();
5322 let subscription = Rc::new(RefCell::new(None));
5323 *subscription.borrow_mut() = Some(cx.observe(&observed_model, {
5324 let subscription = subscription.clone();
5325 move |_, _, _| {
5326 subscription.borrow_mut().take();
5327 *observation_count.borrow_mut() += 1;
5328 }
5329 }));
5330 });
5331
5332 observed_model.update(cx, |_, cx| {
5333 cx.notify();
5334 });
5335
5336 observed_model.update(cx, |_, cx| {
5337 cx.notify();
5338 });
5339
5340 assert_eq!(*observation_count.borrow(), 1);
5341
5342 // View Observation
5343 struct View;
5344
5345 impl Entity for View {
5346 type Event = ();
5347 }
5348
5349 impl super::View for View {
5350 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5351 Empty::new().into_any()
5352 }
5353
5354 fn ui_name() -> &'static str {
5355 "View"
5356 }
5357 }
5358
5359 let (window_id, _root_view) = cx.add_window(|_| View);
5360 let observing_view = cx.add_view(window_id, |_| View);
5361 let observed_view = cx.add_view(window_id, |_| View);
5362
5363 let observation_count = Rc::new(RefCell::new(0));
5364 observing_view.update(cx, |_, cx| {
5365 let observation_count = observation_count.clone();
5366 let subscription = Rc::new(RefCell::new(None));
5367 *subscription.borrow_mut() = Some(cx.observe(&observed_view, {
5368 let subscription = subscription.clone();
5369 move |_, _, _| {
5370 subscription.borrow_mut().take();
5371 *observation_count.borrow_mut() += 1;
5372 }
5373 }));
5374 });
5375
5376 observed_view.update(cx, |_, cx| {
5377 cx.notify();
5378 });
5379
5380 observed_view.update(cx, |_, cx| {
5381 cx.notify();
5382 });
5383
5384 assert_eq!(*observation_count.borrow(), 1);
5385
5386 // Global Observation
5387 let observation_count = Rc::new(RefCell::new(0));
5388 let subscription = Rc::new(RefCell::new(None));
5389 *subscription.borrow_mut() = Some(cx.observe_global::<(), _>({
5390 let observation_count = observation_count.clone();
5391 let subscription = subscription.clone();
5392 move |_| {
5393 subscription.borrow_mut().take();
5394 *observation_count.borrow_mut() += 1;
5395 }
5396 }));
5397
5398 cx.update(|cx| {
5399 cx.default_global::<()>();
5400 cx.set_global(());
5401 });
5402 assert_eq!(*observation_count.borrow(), 1);
5403 }
5404
5405 #[crate::test(self)]
5406 fn test_focus(cx: &mut TestAppContext) {
5407 struct View {
5408 name: String,
5409 events: Arc<Mutex<Vec<String>>>,
5410 child: Option<AnyViewHandle>,
5411 }
5412
5413 impl Entity for View {
5414 type Event = ();
5415 }
5416
5417 impl super::View for View {
5418 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
5419 self.child
5420 .as_ref()
5421 .map(|child| ChildView::new(child, cx).into_any())
5422 .unwrap_or(Empty::new().into_any())
5423 }
5424
5425 fn ui_name() -> &'static str {
5426 "View"
5427 }
5428
5429 fn focus_in(&mut self, focused: AnyViewHandle, cx: &mut ViewContext<Self>) {
5430 if cx.handle().id() == focused.id() {
5431 self.events.lock().push(format!("{} focused", &self.name));
5432 }
5433 }
5434
5435 fn focus_out(&mut self, blurred: AnyViewHandle, cx: &mut ViewContext<Self>) {
5436 if cx.handle().id() == blurred.id() {
5437 self.events.lock().push(format!("{} blurred", &self.name));
5438 }
5439 }
5440 }
5441
5442 let view_events: Arc<Mutex<Vec<String>>> = Default::default();
5443 let (window_id, view_1) = cx.add_window(|_| View {
5444 events: view_events.clone(),
5445 name: "view 1".to_string(),
5446 child: None,
5447 });
5448 let view_2 = cx
5449 .update_window(window_id, |cx| {
5450 let view_2 = cx.add_view(|_| View {
5451 events: view_events.clone(),
5452 name: "view 2".to_string(),
5453 child: None,
5454 });
5455 view_1.update(cx, |view_1, cx| {
5456 view_1.child = Some(view_2.clone().into_any());
5457 cx.notify();
5458 });
5459 view_2
5460 })
5461 .unwrap();
5462
5463 let observed_events: Arc<Mutex<Vec<String>>> = Default::default();
5464 view_1.update(cx, |_, cx| {
5465 cx.observe_focus(&view_2, {
5466 let observed_events = observed_events.clone();
5467 move |this, view, focused, cx| {
5468 let label = if focused { "focus" } else { "blur" };
5469 observed_events.lock().push(format!(
5470 "{} observed {}'s {}",
5471 this.name,
5472 view.read(cx).name,
5473 label
5474 ))
5475 }
5476 })
5477 .detach();
5478 });
5479 view_2.update(cx, |_, cx| {
5480 cx.observe_focus(&view_1, {
5481 let observed_events = observed_events.clone();
5482 move |this, view, focused, cx| {
5483 let label = if focused { "focus" } else { "blur" };
5484 observed_events.lock().push(format!(
5485 "{} observed {}'s {}",
5486 this.name,
5487 view.read(cx).name,
5488 label
5489 ))
5490 }
5491 })
5492 .detach();
5493 });
5494 assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
5495 assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
5496
5497 view_1.update(cx, |_, cx| {
5498 // Ensure only the last focus event is honored.
5499 cx.focus(&view_2);
5500 cx.focus(&view_1);
5501 cx.focus(&view_2);
5502 });
5503
5504 assert_eq!(
5505 mem::take(&mut *view_events.lock()),
5506 ["view 1 blurred", "view 2 focused"],
5507 );
5508 assert_eq!(
5509 mem::take(&mut *observed_events.lock()),
5510 [
5511 "view 2 observed view 1's blur",
5512 "view 1 observed view 2's focus"
5513 ]
5514 );
5515
5516 view_1.update(cx, |_, cx| cx.focus(&view_1));
5517 assert_eq!(
5518 mem::take(&mut *view_events.lock()),
5519 ["view 2 blurred", "view 1 focused"],
5520 );
5521 assert_eq!(
5522 mem::take(&mut *observed_events.lock()),
5523 [
5524 "view 1 observed view 2's blur",
5525 "view 2 observed view 1's focus"
5526 ]
5527 );
5528
5529 view_1.update(cx, |_, cx| cx.focus(&view_2));
5530 assert_eq!(
5531 mem::take(&mut *view_events.lock()),
5532 ["view 1 blurred", "view 2 focused"],
5533 );
5534 assert_eq!(
5535 mem::take(&mut *observed_events.lock()),
5536 [
5537 "view 2 observed view 1's blur",
5538 "view 1 observed view 2's focus"
5539 ]
5540 );
5541
5542 println!("=====================");
5543 view_1.update(cx, |view, _| {
5544 drop(view_2);
5545 view.child = None;
5546 });
5547 assert_eq!(mem::take(&mut *view_events.lock()), ["view 1 focused"]);
5548 assert_eq!(mem::take(&mut *observed_events.lock()), Vec::<&str>::new());
5549 }
5550
5551 #[crate::test(self)]
5552 fn test_deserialize_actions(cx: &mut AppContext) {
5553 #[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
5554 pub struct ComplexAction {
5555 arg: String,
5556 count: usize,
5557 }
5558
5559 actions!(test::something, [SimpleAction]);
5560 impl_actions!(test::something, [ComplexAction]);
5561
5562 cx.add_global_action(move |_: &SimpleAction, _: &mut AppContext| {});
5563 cx.add_global_action(move |_: &ComplexAction, _: &mut AppContext| {});
5564
5565 let action1 = cx
5566 .deserialize_action(
5567 "test::something::ComplexAction",
5568 Some(r#"{"arg": "a", "count": 5}"#),
5569 )
5570 .unwrap();
5571 let action2 = cx
5572 .deserialize_action("test::something::SimpleAction", None)
5573 .unwrap();
5574 assert_eq!(
5575 action1.as_any().downcast_ref::<ComplexAction>().unwrap(),
5576 &ComplexAction {
5577 arg: "a".to_string(),
5578 count: 5,
5579 }
5580 );
5581 assert_eq!(
5582 action2.as_any().downcast_ref::<SimpleAction>().unwrap(),
5583 &SimpleAction
5584 );
5585 }
5586
5587 #[crate::test(self)]
5588 fn test_dispatch_action(cx: &mut AppContext) {
5589 struct ViewA {
5590 id: usize,
5591 child: Option<AnyViewHandle>,
5592 }
5593
5594 impl Entity for ViewA {
5595 type Event = ();
5596 }
5597
5598 impl View for ViewA {
5599 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
5600 self.child
5601 .as_ref()
5602 .map(|child| ChildView::new(child, cx).into_any())
5603 .unwrap_or(Empty::new().into_any())
5604 }
5605
5606 fn ui_name() -> &'static str {
5607 "View"
5608 }
5609 }
5610
5611 struct ViewB {
5612 id: usize,
5613 child: Option<AnyViewHandle>,
5614 }
5615
5616 impl Entity for ViewB {
5617 type Event = ();
5618 }
5619
5620 impl View for ViewB {
5621 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
5622 self.child
5623 .as_ref()
5624 .map(|child| ChildView::new(child, cx).into_any())
5625 .unwrap_or(Empty::new().into_any())
5626 }
5627
5628 fn ui_name() -> &'static str {
5629 "View"
5630 }
5631 }
5632
5633 #[derive(Clone, Default, Deserialize, PartialEq)]
5634 pub struct Action(pub String);
5635
5636 impl_actions!(test, [Action]);
5637
5638 let actions = Rc::new(RefCell::new(Vec::new()));
5639
5640 cx.add_global_action({
5641 let actions = actions.clone();
5642 move |_: &Action, _: &mut AppContext| {
5643 actions.borrow_mut().push("global".to_string());
5644 }
5645 });
5646
5647 cx.add_action({
5648 let actions = actions.clone();
5649 move |view: &mut ViewA, action: &Action, cx| {
5650 assert_eq!(action.0, "bar");
5651 cx.propagate_action();
5652 actions.borrow_mut().push(format!("{} a", view.id));
5653 }
5654 });
5655
5656 cx.add_action({
5657 let actions = actions.clone();
5658 move |view: &mut ViewA, _: &Action, cx| {
5659 if view.id != 1 {
5660 cx.add_view(|cx| {
5661 cx.propagate_action(); // Still works on a nested ViewContext
5662 ViewB { id: 5, child: None }
5663 });
5664 }
5665 actions.borrow_mut().push(format!("{} b", view.id));
5666 }
5667 });
5668
5669 cx.add_action({
5670 let actions = actions.clone();
5671 move |view: &mut ViewB, _: &Action, cx| {
5672 cx.propagate_action();
5673 actions.borrow_mut().push(format!("{} c", view.id));
5674 }
5675 });
5676
5677 cx.add_action({
5678 let actions = actions.clone();
5679 move |view: &mut ViewB, _: &Action, cx| {
5680 cx.propagate_action();
5681 actions.borrow_mut().push(format!("{} d", view.id));
5682 }
5683 });
5684
5685 cx.capture_action({
5686 let actions = actions.clone();
5687 move |view: &mut ViewA, _: &Action, cx| {
5688 cx.propagate_action();
5689 actions.borrow_mut().push(format!("{} capture", view.id));
5690 }
5691 });
5692
5693 let observed_actions = Rc::new(RefCell::new(Vec::new()));
5694 cx.observe_actions({
5695 let observed_actions = observed_actions.clone();
5696 move |action_id, _| observed_actions.borrow_mut().push(action_id)
5697 })
5698 .detach();
5699
5700 let (window_id, view_1) =
5701 cx.add_window(Default::default(), |_| ViewA { id: 1, child: None });
5702 let view_2 = cx
5703 .update_window(window_id, |cx| {
5704 let child = cx.add_view(|_| ViewB { id: 2, child: None });
5705 view_1.update(cx, |view, cx| {
5706 view.child = Some(child.clone().into_any());
5707 cx.notify();
5708 });
5709 child
5710 })
5711 .unwrap();
5712 let view_3 = cx
5713 .update_window(window_id, |cx| {
5714 let child = cx.add_view(|_| ViewA { id: 3, child: None });
5715 view_2.update(cx, |view, cx| {
5716 view.child = Some(child.clone().into_any());
5717 cx.notify();
5718 });
5719 child
5720 })
5721 .unwrap();
5722 let view_4 = cx
5723 .update_window(window_id, |cx| {
5724 let child = cx.add_view(|_| ViewB { id: 4, child: None });
5725 view_3.update(cx, |view, cx| {
5726 view.child = Some(child.clone().into_any());
5727 cx.notify();
5728 });
5729 child
5730 })
5731 .unwrap();
5732
5733 cx.update_window(window_id, |cx| {
5734 cx.dispatch_action(Some(view_4.id()), &Action("bar".to_string()))
5735 });
5736
5737 assert_eq!(
5738 *actions.borrow(),
5739 vec![
5740 "1 capture",
5741 "3 capture",
5742 "4 d",
5743 "4 c",
5744 "3 b",
5745 "3 a",
5746 "2 d",
5747 "2 c",
5748 "1 b"
5749 ]
5750 );
5751 assert_eq!(*observed_actions.borrow(), [Action::default().id()]);
5752
5753 // Remove view_1, which doesn't propagate the action
5754
5755 let (window_id, view_2) =
5756 cx.add_window(Default::default(), |_| ViewB { id: 2, child: None });
5757 let view_3 = cx
5758 .update_window(window_id, |cx| {
5759 let child = cx.add_view(|_| ViewA { id: 3, child: None });
5760 view_2.update(cx, |view, cx| {
5761 view.child = Some(child.clone().into_any());
5762 cx.notify();
5763 });
5764 child
5765 })
5766 .unwrap();
5767 let view_4 = cx
5768 .update_window(window_id, |cx| {
5769 let child = cx.add_view(|_| ViewB { id: 4, child: None });
5770 view_3.update(cx, |view, cx| {
5771 view.child = Some(child.clone().into_any());
5772 cx.notify();
5773 });
5774 child
5775 })
5776 .unwrap();
5777
5778 actions.borrow_mut().clear();
5779 cx.update_window(window_id, |cx| {
5780 cx.dispatch_action(Some(view_4.id()), &Action("bar".to_string()))
5781 });
5782
5783 assert_eq!(
5784 *actions.borrow(),
5785 vec![
5786 "3 capture",
5787 "4 d",
5788 "4 c",
5789 "3 b",
5790 "3 a",
5791 "2 d",
5792 "2 c",
5793 "global"
5794 ]
5795 );
5796 assert_eq!(
5797 *observed_actions.borrow(),
5798 [Action::default().id(), Action::default().id()]
5799 );
5800 }
5801
5802 #[crate::test(self)]
5803 fn test_dispatch_keystroke(cx: &mut AppContext) {
5804 #[derive(Clone, Deserialize, PartialEq)]
5805 pub struct Action(String);
5806
5807 impl_actions!(test, [Action]);
5808
5809 struct View {
5810 id: usize,
5811 keymap_context: KeymapContext,
5812 child: Option<AnyViewHandle>,
5813 }
5814
5815 impl Entity for View {
5816 type Event = ();
5817 }
5818
5819 impl super::View for View {
5820 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
5821 self.child
5822 .as_ref()
5823 .map(|child| ChildView::new(child, cx).into_any())
5824 .unwrap_or(Empty::new().into_any())
5825 }
5826
5827 fn ui_name() -> &'static str {
5828 "View"
5829 }
5830
5831 fn update_keymap_context(&self, keymap: &mut KeymapContext, _: &AppContext) {
5832 *keymap = self.keymap_context.clone();
5833 }
5834 }
5835
5836 impl View {
5837 fn new(id: usize) -> Self {
5838 View {
5839 id,
5840 keymap_context: KeymapContext::default(),
5841 child: None,
5842 }
5843 }
5844 }
5845
5846 let mut view_1 = View::new(1);
5847 let mut view_2 = View::new(2);
5848 let mut view_3 = View::new(3);
5849 view_1.keymap_context.add_identifier("a");
5850 view_2.keymap_context.add_identifier("a");
5851 view_2.keymap_context.add_identifier("b");
5852 view_3.keymap_context.add_identifier("a");
5853 view_3.keymap_context.add_identifier("b");
5854 view_3.keymap_context.add_identifier("c");
5855
5856 let (window_id, _view_1) = cx.add_window(Default::default(), |cx| {
5857 let view_2 = cx.add_view(|cx| {
5858 let view_3 = cx.add_view(|cx| {
5859 cx.focus_self();
5860 view_3
5861 });
5862 view_2.child = Some(view_3.into_any());
5863 view_2
5864 });
5865 view_1.child = Some(view_2.into_any());
5866 view_1
5867 });
5868
5869 // This binding only dispatches an action on view 2 because that view will have
5870 // "a" and "b" in its context, but not "c".
5871 cx.add_bindings(vec![Binding::new(
5872 "a",
5873 Action("a".to_string()),
5874 Some("a && b && !c"),
5875 )]);
5876
5877 cx.add_bindings(vec![Binding::new("b", Action("b".to_string()), None)]);
5878
5879 // This binding only dispatches an action on views 2 and 3, because they have
5880 // a parent view with a in its context
5881 cx.add_bindings(vec![Binding::new(
5882 "c",
5883 Action("c".to_string()),
5884 Some("b > c"),
5885 )]);
5886
5887 // This binding only dispatches an action on view 2, because they have
5888 // a parent view with a in its context
5889 cx.add_bindings(vec![Binding::new(
5890 "d",
5891 Action("d".to_string()),
5892 Some("a && !b > b"),
5893 )]);
5894
5895 let actions = Rc::new(RefCell::new(Vec::new()));
5896 cx.add_action({
5897 let actions = actions.clone();
5898 move |view: &mut View, action: &Action, cx| {
5899 actions
5900 .borrow_mut()
5901 .push(format!("{} {}", view.id, action.0));
5902
5903 if action.0 == "b" {
5904 cx.propagate_action();
5905 }
5906 }
5907 });
5908
5909 cx.add_global_action({
5910 let actions = actions.clone();
5911 move |action: &Action, _| {
5912 actions.borrow_mut().push(format!("global {}", action.0));
5913 }
5914 });
5915
5916 cx.update_window(window_id, |cx| {
5917 cx.dispatch_keystroke(&Keystroke::parse("a").unwrap())
5918 });
5919 assert_eq!(&*actions.borrow(), &["2 a"]);
5920 actions.borrow_mut().clear();
5921
5922 cx.update_window(window_id, |cx| {
5923 cx.dispatch_keystroke(&Keystroke::parse("b").unwrap());
5924 });
5925
5926 assert_eq!(&*actions.borrow(), &["3 b", "2 b", "1 b", "global b"]);
5927 actions.borrow_mut().clear();
5928
5929 cx.update_window(window_id, |cx| {
5930 cx.dispatch_keystroke(&Keystroke::parse("c").unwrap());
5931 });
5932 assert_eq!(&*actions.borrow(), &["3 c"]);
5933 actions.borrow_mut().clear();
5934
5935 cx.update_window(window_id, |cx| {
5936 cx.dispatch_keystroke(&Keystroke::parse("d").unwrap());
5937 });
5938 assert_eq!(&*actions.borrow(), &["2 d"]);
5939 actions.borrow_mut().clear();
5940 }
5941
5942 #[crate::test(self)]
5943 fn test_keystrokes_for_action(cx: &mut TestAppContext) {
5944 actions!(test, [Action1, Action2, GlobalAction]);
5945
5946 struct View1 {
5947 child: ViewHandle<View2>,
5948 }
5949 struct View2 {}
5950
5951 impl Entity for View1 {
5952 type Event = ();
5953 }
5954 impl Entity for View2 {
5955 type Event = ();
5956 }
5957
5958 impl super::View for View1 {
5959 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
5960 ChildView::new(&self.child, cx).into_any()
5961 }
5962 fn ui_name() -> &'static str {
5963 "View1"
5964 }
5965 }
5966 impl super::View for View2 {
5967 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
5968 Empty::new().into_any()
5969 }
5970 fn ui_name() -> &'static str {
5971 "View2"
5972 }
5973 }
5974
5975 let (window_id, view_1) = cx.add_window(|cx| {
5976 let view_2 = cx.add_view(|cx| {
5977 cx.focus_self();
5978 View2 {}
5979 });
5980 View1 { child: view_2 }
5981 });
5982 let view_2 = view_1.read_with(cx, |view, _| view.child.clone());
5983
5984 cx.update(|cx| {
5985 cx.add_action(|_: &mut View1, _: &Action1, _cx| {});
5986 cx.add_action(|_: &mut View2, _: &Action2, _cx| {});
5987 cx.add_global_action(|_: &GlobalAction, _| {});
5988 cx.add_bindings(vec![
5989 Binding::new("a", Action1, Some("View1")),
5990 Binding::new("b", Action2, Some("View1 > View2")),
5991 Binding::new("c", GlobalAction, Some("View3")), // View 3 does not exist
5992 ]);
5993 });
5994
5995 let view_1_id = view_1.id();
5996 view_1.update(cx, |_, cx| {
5997 view_2.update(cx, |_, cx| {
5998 // Sanity check
5999 let mut new_parents = Default::default();
6000 let mut notify_views_if_parents_change = Default::default();
6001 let mut layout_cx = LayoutContext::new(
6002 cx,
6003 &mut new_parents,
6004 &mut notify_views_if_parents_change,
6005 false,
6006 );
6007 assert_eq!(
6008 layout_cx
6009 .keystrokes_for_action(view_1_id, &Action1)
6010 .unwrap()
6011 .as_slice(),
6012 &[Keystroke::parse("a").unwrap()]
6013 );
6014 assert_eq!(
6015 layout_cx
6016 .keystrokes_for_action(view_2.id(), &Action2)
6017 .unwrap()
6018 .as_slice(),
6019 &[Keystroke::parse("b").unwrap()]
6020 );
6021
6022 // The 'a' keystroke propagates up the view tree from view_2
6023 // to view_1. The action, Action1, is handled by view_1.
6024 assert_eq!(
6025 layout_cx
6026 .keystrokes_for_action(view_2.id(), &Action1)
6027 .unwrap()
6028 .as_slice(),
6029 &[Keystroke::parse("a").unwrap()]
6030 );
6031
6032 // Actions that are handled below the current view don't have bindings
6033 assert_eq!(layout_cx.keystrokes_for_action(view_1_id, &Action2), None);
6034
6035 // Actions that are handled in other branches of the tree should not have a binding
6036 assert_eq!(
6037 layout_cx.keystrokes_for_action(view_2.id(), &GlobalAction),
6038 None
6039 );
6040 });
6041 });
6042
6043 // Check that global actions do not have a binding, even if a binding does exist in another view
6044 assert_eq!(
6045 &available_actions(window_id, view_1.id(), cx),
6046 &[
6047 ("test::Action1", vec![Keystroke::parse("a").unwrap()]),
6048 ("test::GlobalAction", vec![])
6049 ],
6050 );
6051
6052 // Check that view 1 actions and bindings are available even when called from view 2
6053 assert_eq!(
6054 &available_actions(window_id, view_2.id(), cx),
6055 &[
6056 ("test::Action1", vec![Keystroke::parse("a").unwrap()]),
6057 ("test::Action2", vec![Keystroke::parse("b").unwrap()]),
6058 ("test::GlobalAction", vec![]),
6059 ],
6060 );
6061
6062 // Produces a list of actions and key bindings
6063 fn available_actions(
6064 window_id: usize,
6065 view_id: usize,
6066 cx: &TestAppContext,
6067 ) -> Vec<(&'static str, Vec<Keystroke>)> {
6068 cx.available_actions(window_id, view_id)
6069 .into_iter()
6070 .map(|(action_name, _, bindings)| {
6071 (
6072 action_name,
6073 bindings
6074 .iter()
6075 .map(|binding| binding.keystrokes()[0].clone())
6076 .collect::<Vec<_>>(),
6077 )
6078 })
6079 .sorted_by(|(name1, _), (name2, _)| name1.cmp(name2))
6080 .collect()
6081 }
6082 }
6083
6084 #[crate::test(self)]
6085 async fn test_model_condition(cx: &mut TestAppContext) {
6086 struct Counter(usize);
6087
6088 impl super::Entity for Counter {
6089 type Event = ();
6090 }
6091
6092 impl Counter {
6093 fn inc(&mut self, cx: &mut ModelContext<Self>) {
6094 self.0 += 1;
6095 cx.notify();
6096 }
6097 }
6098
6099 let model = cx.add_model(|_| Counter(0));
6100
6101 let condition1 = model.condition(cx, |model, _| model.0 == 2);
6102 let condition2 = model.condition(cx, |model, _| model.0 == 3);
6103 smol::pin!(condition1, condition2);
6104
6105 model.update(cx, |model, cx| model.inc(cx));
6106 assert_eq!(poll_once(&mut condition1).await, None);
6107 assert_eq!(poll_once(&mut condition2).await, None);
6108
6109 model.update(cx, |model, cx| model.inc(cx));
6110 assert_eq!(poll_once(&mut condition1).await, Some(()));
6111 assert_eq!(poll_once(&mut condition2).await, None);
6112
6113 model.update(cx, |model, cx| model.inc(cx));
6114 assert_eq!(poll_once(&mut condition2).await, Some(()));
6115
6116 model.update(cx, |_, cx| cx.notify());
6117 }
6118
6119 #[crate::test(self)]
6120 #[should_panic]
6121 async fn test_model_condition_timeout(cx: &mut TestAppContext) {
6122 struct Model;
6123
6124 impl super::Entity for Model {
6125 type Event = ();
6126 }
6127
6128 let model = cx.add_model(|_| Model);
6129 model.condition(cx, |_, _| false).await;
6130 }
6131
6132 #[crate::test(self)]
6133 #[should_panic(expected = "model dropped with pending condition")]
6134 async fn test_model_condition_panic_on_drop(cx: &mut TestAppContext) {
6135 struct Model;
6136
6137 impl super::Entity for Model {
6138 type Event = ();
6139 }
6140
6141 let model = cx.add_model(|_| Model);
6142 let condition = model.condition(cx, |_, _| false);
6143 cx.update(|_| drop(model));
6144 condition.await;
6145 }
6146
6147 #[crate::test(self)]
6148 async fn test_view_condition(cx: &mut TestAppContext) {
6149 struct Counter(usize);
6150
6151 impl super::Entity for Counter {
6152 type Event = ();
6153 }
6154
6155 impl super::View for Counter {
6156 fn ui_name() -> &'static str {
6157 "test view"
6158 }
6159
6160 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6161 Empty::new().into_any()
6162 }
6163 }
6164
6165 impl Counter {
6166 fn inc(&mut self, cx: &mut ViewContext<Self>) {
6167 self.0 += 1;
6168 cx.notify();
6169 }
6170 }
6171
6172 let (_, view) = cx.add_window(|_| Counter(0));
6173
6174 let condition1 = view.condition(cx, |view, _| view.0 == 2);
6175 let condition2 = view.condition(cx, |view, _| view.0 == 3);
6176 smol::pin!(condition1, condition2);
6177
6178 view.update(cx, |view, cx| view.inc(cx));
6179 assert_eq!(poll_once(&mut condition1).await, None);
6180 assert_eq!(poll_once(&mut condition2).await, None);
6181
6182 view.update(cx, |view, cx| view.inc(cx));
6183 assert_eq!(poll_once(&mut condition1).await, Some(()));
6184 assert_eq!(poll_once(&mut condition2).await, None);
6185
6186 view.update(cx, |view, cx| view.inc(cx));
6187 assert_eq!(poll_once(&mut condition2).await, Some(()));
6188 view.update(cx, |_, cx| cx.notify());
6189 }
6190
6191 #[crate::test(self)]
6192 #[should_panic]
6193 async fn test_view_condition_timeout(cx: &mut TestAppContext) {
6194 let (_, view) = cx.add_window(|_| TestView::default());
6195 view.condition(cx, |_, _| false).await;
6196 }
6197
6198 #[crate::test(self)]
6199 #[should_panic(expected = "view dropped with pending condition")]
6200 async fn test_view_condition_panic_on_drop(cx: &mut TestAppContext) {
6201 let (window_id, _root_view) = cx.add_window(|_| TestView::default());
6202 let view = cx.add_view(window_id, |_| TestView::default());
6203
6204 let condition = view.condition(cx, |_, _| false);
6205 cx.update(|_| drop(view));
6206 condition.await;
6207 }
6208
6209 #[crate::test(self)]
6210 fn test_refresh_windows(cx: &mut AppContext) {
6211 struct View(usize);
6212
6213 impl super::Entity for View {
6214 type Event = ();
6215 }
6216
6217 impl super::View for View {
6218 fn ui_name() -> &'static str {
6219 "test view"
6220 }
6221
6222 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6223 Empty::new().into_any_named(format!("render count: {}", post_inc(&mut self.0)))
6224 }
6225 }
6226
6227 let (window_id, root_view) = cx.add_window(Default::default(), |_| View(0));
6228 cx.update_window(window_id, |cx| {
6229 assert_eq!(
6230 cx.window.rendered_views[&root_view.id()].name(),
6231 Some("render count: 0")
6232 );
6233 });
6234
6235 let view = cx
6236 .update_window(window_id, |cx| {
6237 cx.refresh_windows();
6238 cx.add_view(|_| View(0))
6239 })
6240 .unwrap();
6241
6242 cx.update_window(window_id, |cx| {
6243 assert_eq!(
6244 cx.window.rendered_views[&root_view.id()].name(),
6245 Some("render count: 1")
6246 );
6247 assert_eq!(
6248 cx.window.rendered_views[&view.id()].name(),
6249 Some("render count: 0")
6250 );
6251 });
6252
6253 cx.update(|cx| cx.refresh_windows());
6254
6255 cx.update_window(window_id, |cx| {
6256 assert_eq!(
6257 cx.window.rendered_views[&root_view.id()].name(),
6258 Some("render count: 2")
6259 );
6260 assert_eq!(
6261 cx.window.rendered_views[&view.id()].name(),
6262 Some("render count: 1")
6263 );
6264 });
6265
6266 cx.update(|cx| {
6267 cx.refresh_windows();
6268 drop(view);
6269 });
6270
6271 cx.update_window(window_id, |cx| {
6272 assert_eq!(
6273 cx.window.rendered_views[&root_view.id()].name(),
6274 Some("render count: 3")
6275 );
6276 assert_eq!(cx.window.rendered_views.len(), 1);
6277 });
6278 }
6279
6280 #[crate::test(self)]
6281 async fn test_labeled_tasks(cx: &mut TestAppContext) {
6282 assert_eq!(None, cx.update(|cx| cx.active_labeled_tasks().next()));
6283 let (mut sender, mut reciever) = postage::oneshot::channel::<()>();
6284 let task = cx
6285 .update(|cx| cx.spawn_labeled("Test Label", |_| async move { reciever.recv().await }));
6286
6287 assert_eq!(
6288 Some("Test Label"),
6289 cx.update(|cx| cx.active_labeled_tasks().next())
6290 );
6291 sender
6292 .send(())
6293 .await
6294 .expect("Could not send message to complete task");
6295 task.await;
6296
6297 assert_eq!(None, cx.update(|cx| cx.active_labeled_tasks().next()));
6298 }
6299
6300 #[crate::test(self)]
6301 async fn test_window_activation(cx: &mut TestAppContext) {
6302 struct View(&'static str);
6303
6304 impl super::Entity for View {
6305 type Event = ();
6306 }
6307
6308 impl super::View for View {
6309 fn ui_name() -> &'static str {
6310 "test view"
6311 }
6312
6313 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6314 Empty::new().into_any()
6315 }
6316 }
6317
6318 let events = Rc::new(RefCell::new(Vec::new()));
6319 let (window_1, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6320 cx.observe_window_activation({
6321 let events = events.clone();
6322 move |this, active, _| events.borrow_mut().push((this.0, active))
6323 })
6324 .detach();
6325 View("window 1")
6326 });
6327 assert_eq!(mem::take(&mut *events.borrow_mut()), [("window 1", true)]);
6328
6329 let (window_2, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6330 cx.observe_window_activation({
6331 let events = events.clone();
6332 move |this, active, _| events.borrow_mut().push((this.0, active))
6333 })
6334 .detach();
6335 View("window 2")
6336 });
6337 assert_eq!(
6338 mem::take(&mut *events.borrow_mut()),
6339 [("window 1", false), ("window 2", true)]
6340 );
6341
6342 let (window_3, _) = cx.add_window(|cx: &mut ViewContext<View>| {
6343 cx.observe_window_activation({
6344 let events = events.clone();
6345 move |this, active, _| events.borrow_mut().push((this.0, active))
6346 })
6347 .detach();
6348 View("window 3")
6349 });
6350 assert_eq!(
6351 mem::take(&mut *events.borrow_mut()),
6352 [("window 2", false), ("window 3", true)]
6353 );
6354
6355 cx.simulate_window_activation(Some(window_2));
6356 assert_eq!(
6357 mem::take(&mut *events.borrow_mut()),
6358 [("window 3", false), ("window 2", true)]
6359 );
6360
6361 cx.simulate_window_activation(Some(window_1));
6362 assert_eq!(
6363 mem::take(&mut *events.borrow_mut()),
6364 [("window 2", false), ("window 1", true)]
6365 );
6366
6367 cx.simulate_window_activation(Some(window_3));
6368 assert_eq!(
6369 mem::take(&mut *events.borrow_mut()),
6370 [("window 1", false), ("window 3", true)]
6371 );
6372
6373 cx.simulate_window_activation(Some(window_3));
6374 assert_eq!(mem::take(&mut *events.borrow_mut()), []);
6375 }
6376
6377 #[crate::test(self)]
6378 fn test_child_view(cx: &mut TestAppContext) {
6379 struct Child {
6380 rendered: Rc<Cell<bool>>,
6381 dropped: Rc<Cell<bool>>,
6382 }
6383
6384 impl super::Entity for Child {
6385 type Event = ();
6386 }
6387
6388 impl super::View for Child {
6389 fn ui_name() -> &'static str {
6390 "child view"
6391 }
6392
6393 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6394 self.rendered.set(true);
6395 Empty::new().into_any()
6396 }
6397 }
6398
6399 impl Drop for Child {
6400 fn drop(&mut self) {
6401 self.dropped.set(true);
6402 }
6403 }
6404
6405 struct Parent {
6406 child: Option<ViewHandle<Child>>,
6407 }
6408
6409 impl super::Entity for Parent {
6410 type Event = ();
6411 }
6412
6413 impl super::View for Parent {
6414 fn ui_name() -> &'static str {
6415 "parent view"
6416 }
6417
6418 fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
6419 if let Some(child) = self.child.as_ref() {
6420 ChildView::new(child, cx).into_any()
6421 } else {
6422 Empty::new().into_any()
6423 }
6424 }
6425 }
6426
6427 let child_rendered = Rc::new(Cell::new(false));
6428 let child_dropped = Rc::new(Cell::new(false));
6429 let (_, root_view) = cx.add_window(|cx| Parent {
6430 child: Some(cx.add_view(|_| Child {
6431 rendered: child_rendered.clone(),
6432 dropped: child_dropped.clone(),
6433 })),
6434 });
6435 assert!(child_rendered.take());
6436 assert!(!child_dropped.take());
6437
6438 root_view.update(cx, |view, cx| {
6439 view.child.take();
6440 cx.notify();
6441 });
6442 assert!(!child_rendered.take());
6443 assert!(child_dropped.take());
6444 }
6445
6446 #[derive(Default)]
6447 struct TestView {
6448 events: Vec<String>,
6449 }
6450
6451 impl Entity for TestView {
6452 type Event = String;
6453 }
6454
6455 impl View for TestView {
6456 fn ui_name() -> &'static str {
6457 "TestView"
6458 }
6459
6460 fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
6461 Empty::new().into_any()
6462 }
6463 }
6464}