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