1use crate::{
2 AnyView, AnyWindowHandle, AppContext, AsyncApp, DispatchPhase, Effect, EntityId, EventEmitter,
3 FocusHandle, FocusOutEvent, Focusable, Global, KeystrokeObserver, Reservation, SubscriberSet,
4 Subscription, Task, WeakEntity, WeakFocusHandle, Window, WindowHandle,
5};
6use anyhow::Result;
7use derive_more::{Deref, DerefMut};
8use futures::FutureExt;
9use std::{
10 any::{Any, TypeId},
11 borrow::{Borrow, BorrowMut},
12 future::Future,
13 sync::Arc,
14};
15use util::Deferred;
16
17use super::{App, AsyncWindowContext, Entity, KeystrokeEvent};
18
19/// The app context, with specialized behavior for the given entity.
20#[derive(Deref, DerefMut)]
21pub struct Context<'a, T> {
22 #[deref]
23 #[deref_mut]
24 app: &'a mut App,
25 entity_state: WeakEntity<T>,
26}
27
28impl<'a, T: 'static> Context<'a, T> {
29 pub(crate) fn new_context(app: &'a mut App, entity_state: WeakEntity<T>) -> Self {
30 Self { app, entity_state }
31 }
32
33 /// The entity id of the entity backing this context.
34 pub fn entity_id(&self) -> EntityId {
35 self.entity_state.entity_id
36 }
37
38 /// Returns a handle to the entity belonging to this context.
39 pub fn entity(&self) -> Entity<T> {
40 self.weak_entity()
41 .upgrade()
42 .expect("The entity must be alive if we have a entity context")
43 }
44
45 /// Returns a weak handle to the entity belonging to this context.
46 pub fn weak_entity(&self) -> WeakEntity<T> {
47 self.entity_state.clone()
48 }
49
50 /// Arranges for the given function to be called whenever [`Context::notify`] is
51 /// called with the given entity.
52 pub fn observe<W>(
53 &mut self,
54 entity: &Entity<W>,
55 mut on_notify: impl FnMut(&mut T, Entity<W>, &mut Context<T>) + 'static,
56 ) -> Subscription
57 where
58 T: 'static,
59 W: 'static,
60 {
61 let this = self.weak_entity();
62 self.app.observe_internal(entity, move |e, cx| {
63 if let Some(this) = this.upgrade() {
64 this.update(cx, |this, cx| on_notify(this, e, cx));
65 true
66 } else {
67 false
68 }
69 })
70 }
71
72 /// Subscribe to an event type from another entity
73 pub fn subscribe<T2, Evt>(
74 &mut self,
75 entity: &Entity<T2>,
76 mut on_event: impl FnMut(&mut T, Entity<T2>, &Evt, &mut Context<T>) + 'static,
77 ) -> Subscription
78 where
79 T: 'static,
80 T2: 'static + EventEmitter<Evt>,
81 Evt: 'static,
82 {
83 let this = self.weak_entity();
84 self.app.subscribe_internal(entity, move |e, event, cx| {
85 if let Some(this) = this.upgrade() {
86 this.update(cx, |this, cx| on_event(this, e, event, cx));
87 true
88 } else {
89 false
90 }
91 })
92 }
93
94 /// Subscribe to an event type from ourself
95 pub fn subscribe_self<Evt>(
96 &mut self,
97 mut on_event: impl FnMut(&mut T, &Evt, &mut Context<T>) + 'static,
98 ) -> Subscription
99 where
100 T: 'static + EventEmitter<Evt>,
101 Evt: 'static,
102 {
103 let this = self.entity();
104 self.app.subscribe(&this, move |this, evt, cx| {
105 this.update(cx, |this, cx| on_event(this, evt, cx))
106 })
107 }
108
109 /// Register a callback to be invoked when GPUI releases this entity.
110 pub fn on_release(&self, on_release: impl FnOnce(&mut T, &mut App) + 'static) -> Subscription
111 where
112 T: 'static,
113 {
114 let (subscription, activate) = self.app.release_listeners.insert(
115 self.entity_state.entity_id,
116 Box::new(move |this, cx| {
117 let this = this.downcast_mut().expect("invalid entity type");
118 on_release(this, cx);
119 }),
120 );
121 activate();
122 subscription
123 }
124
125 /// Register a callback to be run on the release of another entity
126 pub fn observe_release<T2>(
127 &self,
128 entity: &Entity<T2>,
129 on_release: impl FnOnce(&mut T, &mut T2, &mut Context<T>) + 'static,
130 ) -> Subscription
131 where
132 T: Any,
133 T2: 'static,
134 {
135 let entity_id = entity.entity_id();
136 let this = self.weak_entity();
137 let (subscription, activate) = self.app.release_listeners.insert(
138 entity_id,
139 Box::new(move |entity, cx| {
140 let entity = entity.downcast_mut().expect("invalid entity type");
141 if let Some(this) = this.upgrade() {
142 this.update(cx, |this, cx| on_release(this, entity, cx));
143 }
144 }),
145 );
146 activate();
147 subscription
148 }
149
150 /// Register a callback to for updates to the given global
151 pub fn observe_global<G: 'static>(
152 &mut self,
153 mut f: impl FnMut(&mut T, &mut Context<T>) + 'static,
154 ) -> Subscription
155 where
156 T: 'static,
157 {
158 let handle = self.weak_entity();
159 let (subscription, activate) = self.global_observers.insert(
160 TypeId::of::<G>(),
161 Box::new(move |cx| handle.update(cx, |view, cx| f(view, cx)).is_ok()),
162 );
163 self.defer(move |_| activate());
164 subscription
165 }
166
167 /// Arrange for the given function to be invoked whenever the application is quit.
168 /// The future returned from this callback will be polled for up to [crate::SHUTDOWN_TIMEOUT] until the app fully quits.
169 pub fn on_app_quit<Fut>(
170 &self,
171 mut on_quit: impl FnMut(&mut T, &mut Context<T>) -> Fut + 'static,
172 ) -> Subscription
173 where
174 Fut: 'static + Future<Output = ()>,
175 T: 'static,
176 {
177 let handle = self.weak_entity();
178 let (subscription, activate) = self.app.quit_observers.insert(
179 (),
180 Box::new(move |cx| {
181 let future = handle.update(cx, |entity, cx| on_quit(entity, cx)).ok();
182 async move {
183 if let Some(future) = future {
184 future.await;
185 }
186 }
187 .boxed_local()
188 }),
189 );
190 activate();
191 subscription
192 }
193
194 /// Tell GPUI that this entity has changed and observers of it should be notified.
195 pub fn notify(&mut self) {
196 self.app.notify(self.entity_state.entity_id);
197 }
198
199 /// Spawn the future returned by the given function.
200 /// The function is provided a weak handle to the entity owned by this context and a context that can be held across await points.
201 /// The returned task must be held or detached.
202 #[track_caller]
203 pub fn spawn<AsyncFn, R>(&self, f: AsyncFn) -> Task<R>
204 where
205 T: 'static,
206 AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncApp) -> R + 'static,
207 R: 'static,
208 {
209 let this = self.weak_entity();
210 self.app.spawn(async move |cx| f(this, cx).await)
211 }
212
213 /// Convenience method for accessing view state in an event callback.
214 ///
215 /// Many GPUI callbacks take the form of `Fn(&E, &mut Window, &mut App)`,
216 /// but it's often useful to be able to access view state in these
217 /// callbacks. This method provides a convenient way to do so.
218 pub fn listener<E: ?Sized>(
219 &self,
220 f: impl Fn(&mut T, &E, &mut Window, &mut Context<T>) + 'static,
221 ) -> impl Fn(&E, &mut Window, &mut App) + 'static {
222 let view = self.entity().downgrade();
223 move |e: &E, window: &mut Window, cx: &mut App| {
224 view.update(cx, |view, cx| f(view, e, window, cx)).ok();
225 }
226 }
227
228 /// Run something using this entity and cx, when the returned struct is dropped
229 pub fn on_drop(
230 &self,
231 f: impl FnOnce(&mut T, &mut Context<T>) + 'static,
232 ) -> Deferred<impl FnOnce()> {
233 let this = self.weak_entity();
234 let mut cx = self.to_async();
235 util::defer(move || {
236 this.update(&mut cx, f).ok();
237 })
238 }
239
240 /// Focus the given view in the given window. View type is required to implement Focusable.
241 pub fn focus_view<W: Focusable>(&mut self, view: &Entity<W>, window: &mut Window) {
242 window.focus(&view.focus_handle(self));
243 }
244
245 /// Sets a given callback to be run on the next frame.
246 pub fn on_next_frame(
247 &self,
248 window: &mut Window,
249 f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
250 ) where
251 T: 'static,
252 {
253 let view = self.entity();
254 window.on_next_frame(move |window, cx| view.update(cx, |view, cx| f(view, window, cx)));
255 }
256
257 /// Schedules the given function to be run at the end of the current effect cycle, allowing entities
258 /// that are currently on the stack to be returned to the app.
259 pub fn defer_in(
260 &mut self,
261 window: &Window,
262 f: impl FnOnce(&mut T, &mut Window, &mut Context<T>) + 'static,
263 ) {
264 let view = self.entity();
265 window.defer(self, move |window, cx| {
266 view.update(cx, |view, cx| f(view, window, cx))
267 });
268 }
269
270 /// Observe another entity for changes to its state, as tracked by [`Context::notify`].
271 pub fn observe_in<V2>(
272 &mut self,
273 observed: &Entity<V2>,
274 window: &mut Window,
275 mut on_notify: impl FnMut(&mut T, Entity<V2>, &mut Window, &mut Context<T>) + 'static,
276 ) -> Subscription
277 where
278 V2: 'static,
279 T: 'static,
280 {
281 let observed_id = observed.entity_id();
282 let observed = observed.downgrade();
283 let window_handle = window.handle;
284 let observer = self.weak_entity();
285 self.new_observer(
286 observed_id,
287 Box::new(move |cx| {
288 window_handle
289 .update(cx, |_, window, cx| {
290 if let Some((observer, observed)) =
291 observer.upgrade().zip(observed.upgrade())
292 {
293 observer.update(cx, |observer, cx| {
294 on_notify(observer, observed, window, cx);
295 });
296 true
297 } else {
298 false
299 }
300 })
301 .unwrap_or(false)
302 }),
303 )
304 }
305
306 /// Subscribe to events emitted by another entity.
307 /// The entity to which you're subscribing must implement the [`EventEmitter`] trait.
308 /// The callback will be invoked with a reference to the current view, a handle to the emitting `Entity`, the event, a mutable reference to the `Window`, and the context for the entity.
309 pub fn subscribe_in<Emitter, Evt>(
310 &mut self,
311 emitter: &Entity<Emitter>,
312 window: &Window,
313 mut on_event: impl FnMut(&mut T, &Entity<Emitter>, &Evt, &mut Window, &mut Context<T>) + 'static,
314 ) -> Subscription
315 where
316 Emitter: EventEmitter<Evt>,
317 Evt: 'static,
318 {
319 let emitter = emitter.downgrade();
320 let window_handle = window.handle;
321 let subscriber = self.weak_entity();
322 self.new_subscription(
323 emitter.entity_id(),
324 (
325 TypeId::of::<Evt>(),
326 Box::new(move |event, cx| {
327 window_handle
328 .update(cx, |_, window, cx| {
329 if let Some((subscriber, emitter)) =
330 subscriber.upgrade().zip(emitter.upgrade())
331 {
332 let event = event.downcast_ref().expect("invalid event type");
333 subscriber.update(cx, |subscriber, cx| {
334 on_event(subscriber, &emitter, event, window, cx);
335 });
336 true
337 } else {
338 false
339 }
340 })
341 .unwrap_or(false)
342 }),
343 ),
344 )
345 }
346
347 /// Register a callback to be invoked when the view is released.
348 ///
349 /// The callback receives a handle to the view's window. This handle may be
350 /// invalid, if the window was closed before the view was released.
351 pub fn on_release_in(
352 &mut self,
353 window: &Window,
354 on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static,
355 ) -> Subscription {
356 let entity = self.entity();
357 self.app.observe_release_in(&entity, window, on_release)
358 }
359
360 /// Register a callback to be invoked when the given Entity is released.
361 pub fn observe_release_in<T2>(
362 &self,
363 observed: &Entity<T2>,
364 window: &Window,
365 mut on_release: impl FnMut(&mut T, &mut T2, &mut Window, &mut Context<T>) + 'static,
366 ) -> Subscription
367 where
368 T: 'static,
369 T2: 'static,
370 {
371 let observer = self.weak_entity();
372 self.app
373 .observe_release_in(observed, window, move |observed, window, cx| {
374 observer
375 .update(cx, |observer, cx| {
376 on_release(observer, observed, window, cx)
377 })
378 .ok();
379 })
380 }
381
382 /// Register a callback to be invoked when the window is resized.
383 pub fn observe_window_bounds(
384 &self,
385 window: &mut Window,
386 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
387 ) -> Subscription {
388 let view = self.weak_entity();
389 let (subscription, activate) = window.bounds_observers.insert(
390 (),
391 Box::new(move |window, cx| {
392 view.update(cx, |view, cx| callback(view, window, cx))
393 .is_ok()
394 }),
395 );
396 activate();
397 subscription
398 }
399
400 /// Register a callback to be invoked when the window is activated or deactivated.
401 pub fn observe_window_activation(
402 &self,
403 window: &mut Window,
404 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
405 ) -> Subscription {
406 let view = self.weak_entity();
407 let (subscription, activate) = window.activation_observers.insert(
408 (),
409 Box::new(move |window, cx| {
410 view.update(cx, |view, cx| callback(view, window, cx))
411 .is_ok()
412 }),
413 );
414 activate();
415 subscription
416 }
417
418 /// Registers a callback to be invoked when the window appearance changes.
419 pub fn observe_window_appearance(
420 &self,
421 window: &mut Window,
422 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
423 ) -> Subscription {
424 let view = self.weak_entity();
425 let (subscription, activate) = window.appearance_observers.insert(
426 (),
427 Box::new(move |window, cx| {
428 view.update(cx, |view, cx| callback(view, window, cx))
429 .is_ok()
430 }),
431 );
432 activate();
433 subscription
434 }
435
436 /// Register a callback to be invoked when a keystroke is received by the application
437 /// in any window. Note that this fires after all other action and event mechanisms have resolved
438 /// and that this API will not be invoked if the event's propagation is stopped.
439 pub fn observe_keystrokes(
440 &mut self,
441 mut f: impl FnMut(&mut T, &KeystrokeEvent, &mut Window, &mut Context<T>) + 'static,
442 ) -> Subscription {
443 fn inner(
444 keystroke_observers: &SubscriberSet<(), KeystrokeObserver>,
445 handler: KeystrokeObserver,
446 ) -> Subscription {
447 let (subscription, activate) = keystroke_observers.insert((), handler);
448 activate();
449 subscription
450 }
451
452 let view = self.weak_entity();
453 inner(
454 &mut self.keystroke_observers,
455 Box::new(move |event, window, cx| {
456 if let Some(view) = view.upgrade() {
457 view.update(cx, |view, cx| f(view, event, window, cx));
458 true
459 } else {
460 false
461 }
462 }),
463 )
464 }
465
466 /// Register a callback to be invoked when the window's pending input changes.
467 pub fn observe_pending_input(
468 &self,
469 window: &mut Window,
470 mut callback: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
471 ) -> Subscription {
472 let view = self.weak_entity();
473 let (subscription, activate) = window.pending_input_observers.insert(
474 (),
475 Box::new(move |window, cx| {
476 view.update(cx, |view, cx| callback(view, window, cx))
477 .is_ok()
478 }),
479 );
480 activate();
481 subscription
482 }
483
484 /// Register a listener to be called when the given focus handle receives focus.
485 /// Returns a subscription and persists until the subscription is dropped.
486 pub fn on_focus(
487 &mut self,
488 handle: &FocusHandle,
489 window: &mut Window,
490 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
491 ) -> Subscription {
492 let view = self.weak_entity();
493 let focus_id = handle.id;
494 let (subscription, activate) =
495 window.new_focus_listener(Box::new(move |event, window, cx| {
496 view.update(cx, |view, cx| {
497 if event.previous_focus_path.last() != Some(&focus_id)
498 && event.current_focus_path.last() == Some(&focus_id)
499 {
500 listener(view, window, cx)
501 }
502 })
503 .is_ok()
504 }));
505 self.defer(|_| activate());
506 subscription
507 }
508
509 /// Register a listener to be called when the given focus handle or one of its descendants receives focus.
510 /// This does not fire if the given focus handle - or one of its descendants - was previously focused.
511 /// Returns a subscription and persists until the subscription is dropped.
512 pub fn on_focus_in(
513 &mut self,
514 handle: &FocusHandle,
515 window: &mut Window,
516 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
517 ) -> Subscription {
518 let view = self.weak_entity();
519 let focus_id = handle.id;
520 let (subscription, activate) =
521 window.new_focus_listener(Box::new(move |event, window, cx| {
522 view.update(cx, |view, cx| {
523 if event.is_focus_in(focus_id) {
524 listener(view, window, cx)
525 }
526 })
527 .is_ok()
528 }));
529 self.defer(|_| activate());
530 subscription
531 }
532
533 /// Register a listener to be called when the given focus handle loses focus.
534 /// Returns a subscription and persists until the subscription is dropped.
535 pub fn on_blur(
536 &mut self,
537 handle: &FocusHandle,
538 window: &mut Window,
539 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
540 ) -> Subscription {
541 let view = self.weak_entity();
542 let focus_id = handle.id;
543 let (subscription, activate) =
544 window.new_focus_listener(Box::new(move |event, window, cx| {
545 view.update(cx, |view, cx| {
546 if event.previous_focus_path.last() == Some(&focus_id)
547 && event.current_focus_path.last() != Some(&focus_id)
548 {
549 listener(view, window, cx)
550 }
551 })
552 .is_ok()
553 }));
554 self.defer(|_| activate());
555 subscription
556 }
557
558 /// Register a listener to be called when nothing in the window has focus.
559 /// This typically happens when the node that was focused is removed from the tree,
560 /// and this callback lets you chose a default place to restore the users focus.
561 /// Returns a subscription and persists until the subscription is dropped.
562 pub fn on_focus_lost(
563 &mut self,
564 window: &mut Window,
565 mut listener: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
566 ) -> Subscription {
567 let view = self.weak_entity();
568 let (subscription, activate) = window.focus_lost_listeners.insert(
569 (),
570 Box::new(move |window, cx| {
571 view.update(cx, |view, cx| listener(view, window, cx))
572 .is_ok()
573 }),
574 );
575 self.defer(|_| activate());
576 subscription
577 }
578
579 /// Register a listener to be called when the given focus handle or one of its descendants loses focus.
580 /// Returns a subscription and persists until the subscription is dropped.
581 pub fn on_focus_out(
582 &mut self,
583 handle: &FocusHandle,
584 window: &mut Window,
585 mut listener: impl FnMut(&mut T, FocusOutEvent, &mut Window, &mut Context<T>) + 'static,
586 ) -> Subscription {
587 let view = self.weak_entity();
588 let focus_id = handle.id;
589 let (subscription, activate) =
590 window.new_focus_listener(Box::new(move |event, window, cx| {
591 view.update(cx, |view, cx| {
592 if let Some(blurred_id) = event.previous_focus_path.last().copied() {
593 if event.is_focus_out(focus_id) {
594 let event = FocusOutEvent {
595 blurred: WeakFocusHandle {
596 id: blurred_id,
597 handles: Arc::downgrade(&cx.focus_handles),
598 },
599 };
600 listener(view, event, window, cx)
601 }
602 }
603 })
604 .is_ok()
605 }));
606 self.defer(|_| activate());
607 subscription
608 }
609
610 /// Schedule a future to be run asynchronously.
611 /// The given callback is invoked with a [`WeakEntity<V>`] to avoid leaking the entity for a long-running process.
612 /// It's also given an [`AsyncWindowContext`], which can be used to access the state of the entity across await points.
613 /// The returned future will be polled on the main thread.
614 #[track_caller]
615 pub fn spawn_in<AsyncFn, R>(&self, window: &Window, f: AsyncFn) -> Task<R>
616 where
617 R: 'static,
618 AsyncFn: AsyncFnOnce(WeakEntity<T>, &mut AsyncWindowContext) -> R + 'static,
619 {
620 let view = self.weak_entity();
621 window.spawn(self, async move |cx| f(view, cx).await)
622 }
623
624 /// Register a callback to be invoked when the given global state changes.
625 pub fn observe_global_in<G: Global>(
626 &mut self,
627 window: &Window,
628 mut f: impl FnMut(&mut T, &mut Window, &mut Context<T>) + 'static,
629 ) -> Subscription {
630 let window_handle = window.handle;
631 let view = self.weak_entity();
632 let (subscription, activate) = self.global_observers.insert(
633 TypeId::of::<G>(),
634 Box::new(move |cx| {
635 window_handle
636 .update(cx, |_, window, cx| {
637 view.update(cx, |view, cx| f(view, window, cx)).is_ok()
638 })
639 .unwrap_or(false)
640 }),
641 );
642 self.defer(move |_| activate());
643 subscription
644 }
645
646 /// Register a callback to be invoked when the given Action type is dispatched to the window.
647 pub fn on_action(
648 &mut self,
649 action_type: TypeId,
650 window: &mut Window,
651 listener: impl Fn(&mut T, &dyn Any, DispatchPhase, &mut Window, &mut Context<T>) + 'static,
652 ) {
653 let handle = self.weak_entity();
654 window.on_action(action_type, move |action, phase, window, cx| {
655 handle
656 .update(cx, |view, cx| {
657 listener(view, action, phase, window, cx);
658 })
659 .ok();
660 });
661 }
662
663 /// Move focus to the current view, assuming it implements [`Focusable`].
664 pub fn focus_self(&mut self, window: &mut Window)
665 where
666 T: Focusable,
667 {
668 let view = self.entity();
669 window.defer(self, move |window, cx| {
670 view.read(cx).focus_handle(cx).focus(window)
671 })
672 }
673}
674
675impl<T> Context<'_, T> {
676 /// Emit an event of the specified type, which can be handled by other entities that have subscribed via `subscribe` methods on their respective contexts.
677 pub fn emit<Evt>(&mut self, event: Evt)
678 where
679 T: EventEmitter<Evt>,
680 Evt: 'static,
681 {
682 self.app.pending_effects.push_back(Effect::Emit {
683 emitter: self.entity_state.entity_id,
684 event_type: TypeId::of::<Evt>(),
685 event: Box::new(event),
686 });
687 }
688}
689
690impl<T> AppContext for Context<'_, T> {
691 type Result<U> = U;
692
693 fn new<U: 'static>(&mut self, build_entity: impl FnOnce(&mut Context<U>) -> U) -> Entity<U> {
694 self.app.new(build_entity)
695 }
696
697 fn reserve_entity<U: 'static>(&mut self) -> Reservation<U> {
698 self.app.reserve_entity()
699 }
700
701 fn insert_entity<U: 'static>(
702 &mut self,
703 reservation: Reservation<U>,
704 build_entity: impl FnOnce(&mut Context<U>) -> U,
705 ) -> Self::Result<Entity<U>> {
706 self.app.insert_entity(reservation, build_entity)
707 }
708
709 fn update_entity<U: 'static, R>(
710 &mut self,
711 handle: &Entity<U>,
712 update: impl FnOnce(&mut U, &mut Context<U>) -> R,
713 ) -> R {
714 self.app.update_entity(handle, update)
715 }
716
717 fn read_entity<U, R>(
718 &self,
719 handle: &Entity<U>,
720 read: impl FnOnce(&U, &App) -> R,
721 ) -> Self::Result<R>
722 where
723 U: 'static,
724 {
725 self.app.read_entity(handle, read)
726 }
727
728 fn update_window<R, F>(&mut self, window: AnyWindowHandle, update: F) -> Result<R>
729 where
730 F: FnOnce(AnyView, &mut Window, &mut App) -> R,
731 {
732 self.app.update_window(window, update)
733 }
734
735 fn read_window<U, R>(
736 &self,
737 window: &WindowHandle<U>,
738 read: impl FnOnce(Entity<U>, &App) -> R,
739 ) -> Result<R>
740 where
741 U: 'static,
742 {
743 self.app.read_window(window, read)
744 }
745
746 fn background_spawn<R>(&self, future: impl Future<Output = R> + Send + 'static) -> Task<R>
747 where
748 R: Send + 'static,
749 {
750 self.app.background_executor.spawn(future)
751 }
752
753 fn read_global<G, R>(&self, callback: impl FnOnce(&G, &App) -> R) -> Self::Result<R>
754 where
755 G: Global,
756 {
757 self.app.read_global(callback)
758 }
759}
760
761impl<T> Borrow<App> for Context<'_, T> {
762 fn borrow(&self) -> &App {
763 self.app
764 }
765}
766
767impl<T> BorrowMut<App> for Context<'_, T> {
768 fn borrow_mut(&mut self) -> &mut App {
769 self.app
770 }
771}