Skip to main content

gpui/
app.rs

1use crate::{
2    Action, ActionBuildError, ActionRegistry, ActivationPolicy, ActivityGuard, Any, AnyView,
3    AnyWindowHandle, AppContext, AppLifecyclePhase, Arena, ArenaBox, Asset, AssetRegistry,
4    BackgroundExecutor, Bounds, ClipboardItem, ClipboardReadError, CursorStyle, DispatchPhase,
5    DisplayChanges, DisplayEvent, DisplayId, EventEmitter, ExternalDragPayload, FocusHandle,
6    FocusMap, ForegroundExecutor, Global, HapticFeedbackStyle, KeyBinding, KeyContext, Keymap,
7    Keystroke, LayoutId, Menu, MenuItem, OwnedMenu, PathPromptOptions, Pixels, Platform,
8    PlatformDisplay, PlatformKeyboardLayout, PlatformKeyboardMapper, Point, Priority,
9    PromptBuilder, PromptButton, PromptHandle, PromptLevel, Render, RenderImage,
10    RenderablePromptHandle, Reservation, ScreenCaptureSource, SharedString, SubscriberSet,
11    Subscription, SvgRenderer, SystemNotification, SystemNotificationResponse, Task,
12    TextRenderingMode, TextSystem, ThermalState, Window, WindowAppearance, WindowButtonLayout,
13    WindowHandle, WindowId, WindowInvalidator, WindowingRequest,
14    colors::{Colors, GlobalColors},
15    hash,
16    http_client::{HttpClient, NullHttpClient},
17    init_app_menus,
18};
19use anyhow::{Context as _, Result, anyhow};
20use collections::{FxHashMap, FxHashSet, HashMap, TypeIdHashMap, TypeIdHashSet, VecDeque};
21use derive_more::{Deref, DerefMut};
22use futures::{Future, FutureExt, channel::oneshot, future::LocalBoxFuture};
23use gpui_util::{ResultExt, debug_panic};
24use itertools::Itertools;
25use parking_lot::RwLock;
26use scheduler::Instant;
27use slotmap::SlotMap;
28use smallvec::SmallVec;
29use std::{
30    any::{TypeId, type_name},
31    cell::{BorrowMutError, Cell, Ref, RefCell, RefMut},
32    ffi::OsString,
33    marker::PhantomData,
34    mem,
35    ops::{Deref, DerefMut},
36    path::{Path, PathBuf},
37    rc::{Rc, Weak},
38    sync::Arc,
39    time::Duration,
40};
41
42#[cfg(any(feature = "inspector", debug_assertions))]
43use crate::InspectorElementRegistry;
44use crate::asset_cache::CachedLoad;
45pub use async_context::*;
46#[cfg(feature = "bench-support")]
47pub use bench_context::{
48    BenchAppContext, BenchMeasurement, BenchReport, BenchWindowContext, CountingAllocator,
49    MetricReport, bench_platform,
50};
51
52mod async_context;
53#[cfg(feature = "bench-support")]
54mod bench_context;
55mod context;
56mod entity_map;
57#[cfg(any(test, feature = "test-support"))]
58mod headless_app_context;
59#[cfg(any(test, feature = "test-support"))]
60mod test_app;
61#[cfg(any(test, feature = "test-support"))]
62mod test_context;
63#[cfg(all(target_os = "macos", any(test, feature = "test-support")))]
64mod visual_test_context;
65
66pub use context::*;
67pub use entity_map::*;
68#[cfg(any(test, feature = "test-support"))]
69pub use headless_app_context::*;
70#[cfg(any(test, feature = "test-support"))]
71pub use test_app::*;
72#[cfg(any(test, feature = "test-support"))]
73pub use test_context::*;
74#[cfg(all(target_os = "macos", any(test, feature = "test-support")))]
75pub use visual_test_context::*;
76
77/// The duration for which native applications wait for futures returned from
78/// [Context::on_app_quit] before fully quitting.
79pub const SHUTDOWN_TIMEOUT: Duration = Duration::from_millis(200);
80
81/// Temporary(?) wrapper around [`RefCell<App>`] to help us debug any double borrows.
82/// Strongly consider removing after stabilization.
83#[doc(hidden)]
84pub struct AppCell {
85    app: RefCell<App>,
86}
87
88impl AppCell {
89    #[doc(hidden)]
90    #[track_caller]
91    pub fn borrow(&self) -> AppRef<'_> {
92        if option_env!("TRACK_THREAD_BORROWS").is_some() {
93            let thread_id = std::thread::current().id();
94            eprintln!("borrowed {thread_id:?}");
95        }
96        AppRef(self.app.borrow())
97    }
98
99    #[doc(hidden)]
100    #[track_caller]
101    pub fn borrow_mut(&self) -> AppRefMut<'_> {
102        if option_env!("TRACK_THREAD_BORROWS").is_some() {
103            let thread_id = std::thread::current().id();
104            eprintln!("borrowed {thread_id:?}");
105        }
106        AppRefMut(self.app.borrow_mut())
107    }
108
109    #[doc(hidden)]
110    #[track_caller]
111    pub fn try_borrow_mut(&self) -> Result<AppRefMut<'_>, BorrowMutError> {
112        if option_env!("TRACK_THREAD_BORROWS").is_some() {
113            let thread_id = std::thread::current().id();
114            eprintln!("borrowed {thread_id:?}");
115        }
116        Ok(AppRefMut(self.app.try_borrow_mut()?))
117    }
118}
119
120#[doc(hidden)]
121#[derive(Deref, DerefMut)]
122pub struct AppRef<'a>(Ref<'a, App>);
123
124impl Drop for AppRef<'_> {
125    fn drop(&mut self) {
126        if option_env!("TRACK_THREAD_BORROWS").is_some() {
127            let thread_id = std::thread::current().id();
128            eprintln!("dropped borrow from {thread_id:?}");
129        }
130    }
131}
132
133#[doc(hidden)]
134#[derive(Deref, DerefMut)]
135pub struct AppRefMut<'a>(RefMut<'a, App>);
136
137impl Drop for AppRefMut<'_> {
138    fn drop(&mut self) {
139        if option_env!("TRACK_THREAD_BORROWS").is_some() {
140            let thread_id = std::thread::current().id();
141            eprintln!("dropped {thread_id:?}");
142        }
143    }
144}
145
146/// The entry point for a GPUI application. Configure it, then call [`Application::run`].
147///
148/// Get one from `gpui_platform::application()`, which picks the platform for the
149/// current target. Configure it with the `with_*` and `on_*` builder methods, then call
150/// [`Application::run`] from `main`. The callback you pass to `run` receives the
151/// [`App`] once the platform has finished launching. That is where you open windows,
152/// bind keys and set globals.
153///
154/// The `with_*` methods take the application by value and return it, so you can chain
155/// them. Call them before [`Application::run`].
156///
157/// `run` blocks until the app quits on native platforms, so anything after it in
158/// `main` runs only after the app exits. Once the app is running, you use [`App`]
159/// instead of `Application`.
160///
161/// # Examples
162///
163/// ```no_run
164/// use gpui::{App, Window, WindowOptions, div, prelude::*};
165///
166/// struct HelloWorld;
167///
168/// impl Render for HelloWorld {
169///     fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
170///         div().child("Hello, world!")
171///     }
172/// }
173///
174/// fn main() {
175///     gpui_platform::application().run(|cx: &mut App| {
176///         cx.open_window(WindowOptions::default(), |_, cx| cx.new(|_| HelloWorld))
177///             .unwrap();
178///     });
179/// }
180/// ```
181///
182/// See [the start a project guide](crate::_documentation::guides::start_a_project) for a
183/// complete app. `TestApp` runs app code without a display, and is available with the
184/// `test-support` feature.
185pub struct Application(Rc<AppCell>);
186
187/// A strong handle to an [`Application`] started with [`Application::run_embedded`].
188///
189/// Dropping this handle releases the app, so an embedder must hold it for as long as the
190/// app should run. While held, it is the embedder's entry point back into GPUI each time
191/// the external run loop gives it control.
192pub struct ApplicationHandle {
193    app: Rc<AppCell>,
194}
195
196impl ApplicationHandle {
197    /// Runs `f` with the app context, from outside the platform's run loop.
198    ///
199    /// Call this each time the external run loop gives GPUI control. Effects queued by `f`,
200    /// such as deferred callbacks, run before this returns. Don't call it from
201    /// inside an update on the same app: the app state is a `RefCell`, so a re-entrant
202    /// call panics with a double borrow.
203    pub fn update<R>(&self, f: impl FnOnce(&mut App) -> R) -> R {
204        let cx = &mut *self.app.borrow_mut();
205        cx.update(f)
206    }
207
208    /// Returns an [`AsyncApp`] for use across await points.
209    ///
210    /// The [`AsyncApp`] holds the app weakly. This handle must stay alive for the
211    /// [`AsyncApp`] to do anything useful.
212    pub fn to_async(&self) -> AsyncApp {
213        self.update(|cx| cx.to_async())
214    }
215}
216
217impl Application {
218    /// Creates an application that uses a platform implementation you provide.
219    ///
220    /// Most apps should use `gpui_platform::application()`, which chooses the platform
221    /// for you. Use this when you want a custom or test platform. The app starts with
222    /// an empty [`AssetRegistry`], an HTTP client that fails every request, and
223    /// [`QuitMode::Default`].
224    ///
225    /// # Panics
226    ///
227    /// Panics if called from a thread other than the main thread.
228    pub fn with_platform(platform: Rc<dyn Platform>) -> Self {
229        Self(App::new_app(
230            platform,
231            AssetRegistry::default().into(),
232            Arc::new(NullHttpClient),
233        ))
234    }
235
236    /// Builds an app with accessibility (AccessKit) integration forcibly
237    /// disabled.
238    ///
239    /// In this mode, accessibility APIs (e.g.
240    /// [`div().role()`][crate::StatefulInteractiveElement::role]) silently
241    /// no-op.
242    ///
243    /// See the [accessibility guide](crate::_documentation::guides::accessibility) for the
244    /// features this disables.
245    pub fn new_inaccessible(platform: Rc<dyn Platform>) -> Self {
246        let this = Self::with_platform(platform);
247        this.0.borrow_mut().accessibility_force_disabled = true;
248        this
249    }
250
251    /// Build every window's accessibility tree every frame, even when no
252    /// assistive technology is connected.
253    ///
254    /// For automation and tree inspection: [`crate::Window::debug_a11y_tree_json`]
255    /// otherwise reports nothing until a screen reader activates the platform
256    /// adapter. [`Application::new_inaccessible`] still wins when both are set.
257    pub fn with_accessibility_forced(self) -> Self {
258        self.0.borrow_mut().accessibility_forced = true;
259        self
260    }
261
262    /// Sets the source of assets (images, fonts and SVGs) that the app loads by path.
263    ///
264    /// The registry is returned by [`App::assets`], and the SVG renderer is rebuilt to
265    /// read from it. Set it before you open windows that load assets.
266    pub fn with_assets(self, assets: impl Into<AssetRegistry>) -> Self {
267        let mut context_lock = self.0.borrow_mut();
268        let asset_registry = Arc::new(assets.into());
269        context_lock.asset_registry = asset_registry.clone();
270        context_lock.svg_renderer = SvgRenderer::new(asset_registry);
271        drop(context_lock);
272        self
273    }
274
275    /// Sets the command-line arguments that [`App::restart`] passes to the new process.
276    pub fn with_restart_arguments(self, arguments: Vec<OsString>) -> Self {
277        self.0.borrow_mut().restart_arguments = arguments;
278        self
279    }
280
281    /// Sets the HTTP client that [`App::http_client`] returns.
282    ///
283    /// The default fails every request. Pass a real client to let the app fetch URLs,
284    /// for example for remote images.
285    pub fn with_http_client(self, http_client: Arc<dyn HttpClient>) -> Self {
286        let mut context_lock = self.0.borrow_mut();
287        context_lock.http_client = http_client;
288        drop(context_lock);
289        self
290    }
291
292    /// Sets when the app quits on its own. See [`QuitMode`] for the choices.
293    ///
294    /// Defaults to [`QuitMode::Default`]. You can also change it at runtime with
295    /// [`App::set_quit_mode`].
296    pub fn with_quit_mode(self, mode: QuitMode) -> Self {
297        self.0.borrow_mut().quit_mode = mode;
298        self
299    }
300
301    /// Sets the activation policy for the application (macOS only).
302    ///
303    /// This determines how the application appears in the system:
304    /// - `Regular`: Normal app with Dock icon and menu bar
305    /// - `Accessory`: Background app without Dock icon (LSUIElement)
306    /// - `Prohibited`: Runs in background, no UI allowed
307    ///
308    /// This must be called before the application finishes launching to take effect.
309    /// The method exists only on macOS, so cross-platform code calls it behind
310    /// `#[cfg(target_os = "macos")]`.
311    #[cfg(target_os = "macos")]
312    pub fn with_activation_policy(self, policy: ActivationPolicy) -> Self {
313        self.0.borrow().platform.set_activation_policy(policy);
314        self
315    }
316
317    /// Starts the event loop and calls `on_finish_launching` once the app has launched.
318    ///
319    /// The callback runs on the main thread with the [`App`], and runs once. Open your
320    /// first window there. On native platforms this method blocks until the app quits,
321    /// so code after it runs only after the app exits. On the web it returns right away,
322    /// and the app keeps running in the page.
323    ///
324    /// See the [`Application`] example for a complete `main`.
325    /// Sets the windowing mode the app starts in. See [`App::request_windowing`].
326    ///
327    /// Defaults to windowed. On Linux, the default environment is the process's own, and the app
328    /// starts headless if that names no allowed display server. On macOS, headless means the app
329    /// starts without a Dock icon or menu bar ([`ActivationPolicy::Accessory`]). Has no effect on
330    /// other platforms.
331    pub fn with_windowing(self, request: WindowingRequest) -> Self {
332        self.0.borrow().platform.set_initial_windowing(request);
333        self
334    }
335
336    /// Start the application. The provided callback will be called once the
337    /// app is fully launched.
338    ///
339    /// On WebAssembly, this returns immediately and retains the app for the lifetime
340    /// of the Wasm instance. Use [`Self::run_embedded`] to control its lifetime explicitly.
341    pub fn run<F>(self, on_finish_launching: F)
342    where
343        F: 'static + FnOnce(&mut App),
344    {
345        #[cfg(all(
346            feature = "hot-patching",
347            debug_assertions,
348            not(target_family = "wasm")
349        ))]
350        dioxus_devtools::connect_subsecond();
351
352        let this = self.0.clone();
353        let platform = self.0.borrow().platform.clone();
354        platform.run(Box::new(move || {
355            let cx = &mut *this.borrow_mut();
356            // Some platforms only connect to their display server in `run`.
357            cx.displays_changed();
358            on_finish_launching(cx);
359        }));
360
361        // Native platform run loops block until shutdown, keeping `self` alive for the
362        // application's lifetime. The web platform schedules startup and returns
363        // immediately, so retain the application until the browser tears down the page.
364        #[cfg(target_family = "wasm")]
365        std::mem::forget(self);
366    }
367
368    /// Start the application for an embedder that drives the run loop itself.
369    ///
370    /// On ordinary platforms `Platform::run` blocks for the lifetime of the app, and the
371    /// app state is kept alive by [`Application::run`]'s stack frame. Embedded platforms —
372    /// where the run loop belongs to someone else, e.g. GPUI compiled into a Wasm guest,
373    /// or a GPUI view hosted inside a foreign native application — implement
374    /// `Platform::run` to invoke the launch callback and return immediately. This method
375    /// supports that shape: it returns an [`ApplicationHandle`] that keeps the app alive
376    /// and lets the embedder re-enter it whenever the external run loop yields control.
377    pub fn run_embedded<F>(self, on_finish_launching: F) -> ApplicationHandle
378    where
379        F: 'static + FnOnce(&mut App),
380    {
381        let this = self.0.clone();
382        let platform = self.0.borrow().platform.clone();
383        platform.run(Box::new(move || {
384            let cx = &mut *this.borrow_mut();
385            // Some platforms only connect to their display server in `run`.
386            cx.displays_changed();
387            on_finish_launching(cx);
388        }));
389        ApplicationHandle { app: self.0 }
390    }
391
392    /// Registers a handler for URLs that the user asks the app to open.
393    ///
394    /// The handler receives the URLs as strings. Register a scheme with
395    /// [`App::register_url_scheme`] so the platform routes links with that scheme to
396    /// the app.
397    pub fn on_open_urls<F>(&self, mut callback: F) -> &Self
398    where
399        F: 'static + FnMut(Vec<String>),
400    {
401        self.0.borrow().platform.on_open_urls(Box::new(callback));
402        self
403    }
404
405    /// Registers a handler for a second launch while the app is already running.
406    ///
407    /// On macOS this happens when the user clicks the app icon in the Dock or in
408    /// Finder. A common response is to open a window if none is visible. The handler
409    /// receives the [`App`].
410    pub fn on_reopen<F>(&self, mut callback: F) -> &Self
411    where
412        F: 'static + FnMut(&mut App),
413    {
414        let this = Rc::downgrade(&self.0);
415        self.0.borrow_mut().platform.on_reopen(Box::new(move || {
416            if let Some(app) = this.upgrade() {
417                callback(&mut app.borrow_mut());
418            }
419        }));
420        self
421    }
422
423    /// Returns the executor for `Send` futures. See [`BackgroundExecutor`] for platform behavior.
424    pub fn background_executor(&self) -> BackgroundExecutor {
425        self.0.borrow().background_executor.clone()
426    }
427
428    /// Returns the executor for futures that run on the foreground thread.
429    pub fn foreground_executor(&self) -> ForegroundExecutor {
430        self.0.borrow().foreground_executor.clone()
431    }
432
433    /// Returns a shared handle to the app's [`TextSystem`], which shapes and rasterizes text.
434    pub fn text_system(&self) -> Arc<TextSystem> {
435        self.0.borrow().text_system.clone()
436    }
437
438    /// Returns the path to a helper executable named `name` that ships with the app.
439    ///
440    /// Use this to launch a companion binary, such as a CLI or a helper process. It
441    /// returns an error if the platform cannot find the executable.
442    pub fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
443        self.0.borrow().path_for_auxiliary_executable(name)
444    }
445}
446
447type Handler = Box<dyn FnMut(&mut App) -> bool + 'static>;
448type AppLifecycleHandler = Box<dyn FnMut(AppLifecyclePhase, &mut App) -> bool + 'static>;
449type DisplayHandler = Box<dyn FnMut(DisplayEvent, &mut App) -> bool + 'static>;
450
451/// The properties of a display that GPUI reports changes to.
452#[derive(Clone, Copy, PartialEq)]
453struct DisplayState {
454    bounds: Bounds<Pixels>,
455    refresh_interval: Option<Duration>,
456}
457
458impl DisplayState {
459    fn changes_from(&self, previous: &DisplayState) -> DisplayChanges {
460        let mut changes = DisplayChanges::empty();
461        changes.set(DisplayChanges::BOUNDS, self.bounds != previous.bounds);
462        changes.set(
463            DisplayChanges::REFRESH_INTERVAL,
464            self.refresh_interval != previous.refresh_interval,
465        );
466        changes
467    }
468}
469
470fn read_displays(platform: &dyn Platform) -> HashMap<DisplayId, DisplayState> {
471    platform
472        .displays()
473        .into_iter()
474        .map(|display| {
475            let state = DisplayState {
476                bounds: display.bounds(),
477                refresh_interval: display.refresh_interval(),
478            };
479            (display.id(), state)
480        })
481        .collect()
482}
483
484/// The events that turn one snapshot of the connected displays into the next.
485fn display_events(
486    previous: &HashMap<DisplayId, DisplayState>,
487    current: &HashMap<DisplayId, DisplayState>,
488) -> Vec<DisplayEvent> {
489    let removed = previous
490        .keys()
491        .filter(|id| !current.contains_key(id))
492        .map(|id| DisplayEvent::Removed(*id));
493    let added_or_changed = current.iter().filter_map(|(id, state)| {
494        let Some(previous_state) = previous.get(id) else {
495            return Some(DisplayEvent::Added(*id));
496        };
497        let changes = state.changes_from(previous_state);
498        (!changes.is_empty()).then_some(DisplayEvent::Changed { id: *id, changes })
499    });
500    removed.chain(added_or_changed).collect()
501}
502type Listener = Box<dyn FnMut(&dyn Any, &mut App) -> bool + 'static>;
503pub(crate) type KeystrokeObserver =
504    Box<dyn FnMut(&KeystrokeEvent, &mut Window, &mut App) -> bool + 'static>;
505type QuitHandler = Box<dyn FnOnce(&mut App) -> LocalBoxFuture<'static, ()> + 'static>;
506type WindowClosedHandler = Box<dyn FnMut(&mut App, WindowId)>;
507type ReleaseListener = Box<dyn FnOnce(&mut dyn Any, &mut App) + 'static>;
508type NewEntityListener = Box<dyn FnMut(AnyEntity, &mut Option<&mut Window>, &mut App) + 'static>;
509
510/// Controls whether the app quits on its own when its last window closes.
511///
512/// The check runs each time a window closes. With [`QuitMode::LastWindowClosed`], the
513/// app quits as soon as no windows remain. With [`QuitMode::Explicit`], closing the
514/// last window leaves the app running until you call [`App::quit`].
515///
516/// # Examples
517///
518/// ```
519/// # use gpui::QuitMode;
520/// assert_eq!(QuitMode::default(), QuitMode::Default);
521/// ```
522#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
523pub enum QuitMode {
524    /// Behaves like [`QuitMode::LastWindowClosed`] on Linux and Windows, and like
525    /// [`QuitMode::Explicit`] on macOS, where closing the last window is normal.
526    #[default]
527    Default,
528    /// Quit automatically when the last window is closed.
529    LastWindowClosed,
530    /// Quit only when requested via [`App::quit`].
531    Explicit,
532}
533
534/// Controls when GPUI hides the mouse cursor in response to keyboard input.
535///
536/// GPUI decides when to hide the cursor. The platform shows it again on mouse motion.
537/// Set the mode with [`App::set_cursor_hide_mode`].
538#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
539pub enum CursorHideMode {
540    /// Never hide the cursor automatically.
541    Never,
542    /// Hide on character-producing key presses (typing).
543    OnTyping,
544    /// Hide on character-producing key presses, *and* when a key binding
545    /// resolves to an action that consumes the keystroke.
546    #[default]
547    OnTypingAndAction,
548}
549
550/// A tab in a group of native window tabs. Used by [`SystemWindowTabController`].
551#[doc(hidden)]
552#[derive(Clone, PartialEq, Eq)]
553pub struct SystemWindowTab {
554    /// The ID of the window this tab shows.
555    pub id: WindowId,
556    /// The title shown on the tab.
557    pub title: SharedString,
558    /// The handle to the window.
559    pub handle: AnyWindowHandle,
560    /// When the tab was last active. Used to choose which tab in a group to show.
561    pub last_active_at: Instant,
562}
563
564impl SystemWindowTab {
565    /// Creates a tab for a window, with its current time as the last-active time.
566    pub fn new(title: SharedString, handle: AnyWindowHandle) -> Self {
567        Self {
568            id: handle.id,
569            title,
570            handle,
571            last_active_at: Instant::now(),
572        }
573    }
574}
575
576/// A global that tracks which windows are grouped into native window tabs.
577///
578/// Stored as a [`Global`]. Call [`SystemWindowTabController::init`] once at startup.
579/// The methods that take `cx` read and update this global.
580#[derive(Default)]
581pub struct SystemWindowTabController {
582    visible: Option<bool>,
583    tab_groups: FxHashMap<usize, Vec<SystemWindowTab>>,
584}
585
586impl Global for SystemWindowTabController {}
587
588impl SystemWindowTabController {
589    /// Creates an empty controller with no tab groups and tabs hidden.
590    pub fn new() -> Self {
591        Self {
592            visible: None,
593            tab_groups: FxHashMap::default(),
594        }
595    }
596
597    /// Sets the global [`SystemWindowTabController`] to a new, empty controller.
598    pub fn init(cx: &mut App) {
599        cx.set_global(SystemWindowTabController::new());
600    }
601
602    /// Returns every tab group, keyed by group ID.
603    pub fn tab_groups(&self) -> &FxHashMap<usize, Vec<SystemWindowTab>> {
604        &self.tab_groups
605    }
606
607    /// Returns the handle of the window in the tab group that follows the group containing `id`
608    /// in the iteration order of `tab_groups`. That order is arbitrary.
609    ///
610    /// The window chosen is the most recently active tab in that group. Returns `None`
611    /// if `id` is not in a group.
612    pub fn get_next_tab_group_window(cx: &mut App, id: WindowId) -> Option<&AnyWindowHandle> {
613        let controller = cx.global::<SystemWindowTabController>();
614        let current_group = controller
615            .tab_groups
616            .iter()
617            .find_map(|(group, tabs)| tabs.iter().find(|tab| tab.id == id).map(|_| group));
618
619        let current_group = current_group?;
620        // TODO: `.keys()` returns arbitrary order, what does "next" mean?
621        let mut group_ids: Vec<_> = controller.tab_groups.keys().collect();
622        let idx = group_ids.iter().position(|g| *g == current_group)?;
623        let next_idx = (idx + 1) % group_ids.len();
624
625        controller
626            .tab_groups
627            .get(group_ids[next_idx])
628            .and_then(|tabs| {
629                tabs.iter()
630                    .max_by_key(|tab| tab.last_active_at)
631                    .or_else(|| tabs.first())
632                    .map(|tab| &tab.handle)
633            })
634    }
635
636    /// Returns the handle of the window in the tab group that precedes the group containing `id`
637    /// in the iteration order of `tab_groups`. That order is arbitrary.
638    ///
639    /// The window chosen is the most recently active tab in that group. Returns `None`
640    /// if `id` is not in a group.
641    pub fn get_prev_tab_group_window(cx: &mut App, id: WindowId) -> Option<&AnyWindowHandle> {
642        let controller = cx.global::<SystemWindowTabController>();
643        let current_group = controller
644            .tab_groups
645            .iter()
646            .find_map(|(group, tabs)| tabs.iter().find(|tab| tab.id == id).map(|_| group));
647
648        let current_group = current_group?;
649        // TODO: `.keys()` returns arbitrary order, what does "previous" mean?
650        let mut group_ids: Vec<_> = controller.tab_groups.keys().collect();
651        let idx = group_ids.iter().position(|g| *g == current_group)?;
652        let prev_idx = if idx == 0 {
653            group_ids.len() - 1
654        } else {
655            idx - 1
656        };
657
658        controller
659            .tab_groups
660            .get(group_ids[prev_idx])
661            .and_then(|tabs| {
662                tabs.iter()
663                    .max_by_key(|tab| tab.last_active_at)
664                    .or_else(|| tabs.first())
665                    .map(|tab| &tab.handle)
666            })
667    }
668
669    /// Returns the tabs in the group that contains the window `id`, or `None` if it has none.
670    pub fn tabs(&self, id: WindowId) -> Option<&Vec<SystemWindowTab>> {
671        self.tab_groups
672            .values()
673            .find(|tabs| tabs.iter().any(|tab| tab.id == id))
674    }
675
676    /// Sets tab visibility to `visible`, but only if it has not been set yet.
677    pub fn init_visible(cx: &mut App, visible: bool) {
678        let mut controller = cx.global_mut::<SystemWindowTabController>();
679        if controller.visible.is_none() {
680            controller.visible = Some(visible);
681        }
682    }
683
684    /// Returns whether window tabs are shown. Defaults to `false` until set.
685    pub fn is_visible(&self) -> bool {
686        self.visible.unwrap_or(false)
687    }
688
689    /// Shows or hides window tabs.
690    pub fn set_visible(cx: &mut App, visible: bool) {
691        let mut controller = cx.global_mut::<SystemWindowTabController>();
692        controller.visible = Some(visible);
693    }
694
695    /// Records that the window `id` is now the active tab, for ordering tab groups.
696    pub fn update_last_active(cx: &mut App, id: WindowId) {
697        let mut controller = cx.global_mut::<SystemWindowTabController>();
698        for windows in controller.tab_groups.values_mut() {
699            for tab in windows.iter_mut() {
700                if tab.id == id {
701                    tab.last_active_at = Instant::now();
702                }
703            }
704        }
705    }
706
707    /// Moves the tab for window `id` to index `ix` within its group.
708    ///
709    /// Does nothing if `ix` is out of range or the tab is already there.
710    pub fn update_tab_position(cx: &mut App, id: WindowId, ix: usize) {
711        let mut controller = cx.global_mut::<SystemWindowTabController>();
712        for (_, windows) in controller.tab_groups.iter_mut() {
713            if let Some(current_pos) = windows.iter().position(|tab| tab.id == id) {
714                if ix < windows.len() && current_pos != ix {
715                    let window_tab = windows.remove(current_pos);
716                    windows.insert(ix, window_tab);
717                }
718                break;
719            }
720        }
721    }
722
723    /// Sets the title of the tab for window `id`. Does nothing if the title is unchanged.
724    pub fn update_tab_title(cx: &mut App, id: WindowId, title: SharedString) {
725        let controller = cx.global::<SystemWindowTabController>();
726        let tab = controller
727            .tab_groups
728            .values()
729            .flat_map(|windows| windows.iter())
730            .find(|tab| tab.id == id);
731
732        if tab.map_or(true, |t| t.title == title) {
733            return;
734        }
735
736        let mut controller = cx.global_mut::<SystemWindowTabController>();
737        for windows in controller.tab_groups.values_mut() {
738            for tab in windows.iter_mut() {
739                if tab.id == id {
740                    tab.title = title;
741                    return;
742                }
743            }
744        }
745    }
746
747    /// Adds the window `id` to the group that holds the other tabs in `tabs`.
748    ///
749    /// If no existing group holds exactly the other tabs, `tabs` becomes a new group.
750    /// Does nothing if `tabs` does not contain `id`.
751    pub fn add_tab(cx: &mut App, id: WindowId, tabs: Vec<SystemWindowTab>) {
752        let mut controller = cx.global_mut::<SystemWindowTabController>();
753        let Some(tab) = tabs.iter().find(|tab| tab.id == id).cloned() else {
754            return;
755        };
756
757        let mut expected_tab_ids: Vec<_> = tabs
758            .iter()
759            .filter(|tab| tab.id != id)
760            .map(|tab| tab.id)
761            .sorted()
762            .collect();
763
764        let mut tab_group_id = None;
765        for (group_id, group_tabs) in &controller.tab_groups {
766            let tab_ids: Vec<_> = group_tabs.iter().map(|tab| tab.id).sorted().collect();
767            if tab_ids == expected_tab_ids {
768                tab_group_id = Some(*group_id);
769                break;
770            }
771        }
772
773        if let Some(tab_group_id) = tab_group_id {
774            if let Some(tabs) = controller.tab_groups.get_mut(&tab_group_id) {
775                tabs.push(tab);
776            }
777        } else {
778            let new_group_id = controller.tab_groups.keys().max().map_or(0, |id| id + 1);
779            controller.tab_groups.insert(new_group_id, tabs);
780        }
781    }
782
783    /// Removes the tab for window `id` from its group and returns it.
784    ///
785    /// A group that becomes empty is removed. Returns `None` if `id` is in no group.
786    pub fn remove_tab(cx: &mut App, id: WindowId) -> Option<SystemWindowTab> {
787        let mut controller = cx.global_mut::<SystemWindowTabController>();
788        let mut removed_tab = None;
789
790        controller.tab_groups.retain(|_, tabs| {
791            if let Some(pos) = tabs.iter().position(|tab| tab.id == id) {
792                removed_tab = Some(tabs.remove(pos));
793            }
794            !tabs.is_empty()
795        });
796
797        removed_tab
798    }
799
800    /// Moves the tab for window `id` out of its group into a new group of its own.
801    pub fn move_tab_to_new_window(cx: &mut App, id: WindowId) {
802        let mut removed_tab = Self::remove_tab(cx, id);
803        let mut controller = cx.global_mut::<SystemWindowTabController>();
804
805        if let Some(tab) = removed_tab {
806            let new_group_id = controller.tab_groups.keys().max().map_or(0, |k| k + 1);
807            controller.tab_groups.insert(new_group_id, vec![tab]);
808        }
809    }
810
811    /// Merges every tab group into one group, starting with the group that holds `id`.
812    pub fn merge_all_windows(cx: &mut App, id: WindowId) {
813        let mut controller = cx.global_mut::<SystemWindowTabController>();
814        let Some(initial_tabs) = controller.tabs(id) else {
815            return;
816        };
817
818        let initial_tabs_len = initial_tabs.len();
819        let mut all_tabs = initial_tabs.clone();
820
821        for (_, mut tabs) in controller.tab_groups.drain() {
822            tabs.retain(|tab| !all_tabs[..initial_tabs_len].contains(tab));
823            all_tabs.extend(tabs);
824        }
825
826        controller.tab_groups.insert(0, all_tabs);
827    }
828
829    /// Activates the tab after window `id`'s tab in its group, wrapping around at the end.
830    pub fn select_next_tab(cx: &mut App, id: WindowId) {
831        let mut controller = cx.global_mut::<SystemWindowTabController>();
832        let Some(tabs) = controller.tabs(id) else {
833            return;
834        };
835
836        let current_index = tabs.iter().position(|tab| tab.id == id).unwrap();
837        let next_index = (current_index + 1) % tabs.len();
838
839        let _ = &tabs[next_index].handle.update(cx, |_, window, _| {
840            window.activate();
841        });
842    }
843
844    /// Activates the tab before window `id`'s tab in its group, wrapping around at the start.
845    pub fn select_previous_tab(cx: &mut App, id: WindowId) {
846        let mut controller = cx.global_mut::<SystemWindowTabController>();
847        let Some(tabs) = controller.tabs(id) else {
848            return;
849        };
850
851        let current_index = tabs.iter().position(|tab| tab.id == id).unwrap();
852        let previous_index = if current_index == 0 {
853            tabs.len() - 1
854        } else {
855            current_index - 1
856        };
857
858        let _ = &tabs[previous_index].handle.update(cx, |_, window, _| {
859            window.activate();
860        });
861    }
862}
863
864pub(crate) enum GpuiMode {
865    #[cfg(any(test, feature = "test-support"))]
866    Test {
867        skip_drawing: bool,
868    },
869    Production,
870}
871
872impl GpuiMode {
873    #[cfg(any(test, feature = "test-support"))]
874    pub fn test() -> Self {
875        GpuiMode::Test {
876            skip_drawing: false,
877        }
878    }
879
880    #[inline]
881    pub(crate) fn skip_drawing(&self) -> bool {
882        match self {
883            #[cfg(any(test, feature = "test-support"))]
884            GpuiMode::Test { skip_drawing } => *skip_drawing,
885            GpuiMode::Production => false,
886        }
887    }
888}
889
890struct PlatformOwnedDrag {
891    source_window: WindowId,
892    state: PlatformOwnedDragState,
893}
894
895enum PlatformOwnedDragState {
896    Suspended(AnyDrag),
897    // A source-window drop consumes `active_drag` before AppKit ends the dragging session, so this
898    // marker can outlive the active drag and is cleaned up by `FileDropEvent::Ended`.
899    RestoredInSourceWindow,
900}
901
902/// What a view read while it drew: entities, globals and handle revisions, with the revision
903/// each was at.
904#[derive(Default)]
905pub(crate) struct Dependencies {
906    entities: Vec<EntityId>,
907    globals: Vec<(TypeId, u64)>,
908    revisions: Vec<(Revision, u64)>,
909}
910
911impl Dependencies {
912    pub(crate) fn extend(&mut self, other: Dependencies) {
913        self.entities.extend(other.entities);
914        self.entities.sort_unstable();
915        self.entities.dedup();
916        self.globals.extend(other.globals);
917        self.globals.sort_unstable();
918        self.globals.dedup_by_key(|(global_type, _)| *global_type);
919        // A later phase saw the later revision, so it wins.
920        for (revision, seen) in other.revisions {
921            match self
922                .revisions
923                .iter_mut()
924                .find(|(known, _)| known.same(&revision))
925            {
926                Some(entry) => entry.1 = seen,
927                None => self.revisions.push((revision, seen)),
928            }
929        }
930    }
931}
932
933/// A counter for state that lives outside entities, such as a list's scroll position, so the
934/// views that read it are drawn again when it changes. The owner bumps it on every mutation.
935#[derive(Clone, Debug, Default)]
936pub(crate) struct Revision(Rc<Cell<u64>>);
937
938impl Revision {
939    pub(crate) fn bump(&self) {
940        self.0.set(self.0.get().wrapping_add(1));
941    }
942
943    fn same(&self, other: &Self) -> bool {
944        Rc::ptr_eq(&self.0, &other.0)
945    }
946}
947
948/// The state of a running application: its entities, windows, globals and key bindings.
949///
950/// You get a `&mut App` from the callback passed to [`Application::run`], from
951/// `TestApp::update`, and from any [`Context`], which derefs to `App`. Read an
952/// entity with [`Entity::read`], and create one with [`AppContext::new`]. Callbacks that
953/// run after an `await` can't hold the `App`, so they use an [`AsyncApp`] instead.
954///
955/// `App` is not `Clone`. Keep one per app, and use the references you are given. It
956/// is not `Send`, so it only runs on the main thread.
957///
958/// # Examples
959///
960/// ```
961/// # use gpui::{AppContext, TestApp};
962/// let mut app = TestApp::new();
963/// let count = app.update(|cx| cx.new(|_| 1));
964/// app.read(|cx| assert_eq!(*count.read(cx), 1));
965/// ```
966///
967/// See [contexts](crate::_documentation::concepts::contexts) for how `App` relates to the
968/// other context types.
969pub struct App {
970    pub(crate) this: Weak<AppCell>,
971    pub(crate) platform: Rc<dyn Platform>,
972    text_system: Arc<TextSystem>,
973
974    pub(crate) actions: Rc<ActionRegistry>,
975    pub(crate) active_drag: Option<AnyDrag>,
976    platform_owned_drag: Option<PlatformOwnedDrag>,
977    pub(crate) background_executor: BackgroundExecutor,
978    pub(crate) foreground_executor: ForegroundExecutor,
979    #[cfg(feature = "profiler")]
980    foreground_journal: crate::profiler::journal::ForegroundJournal,
981    #[cfg(all(feature = "profiler", not(target_family = "wasm")))]
982    hang_monitor: Option<crate::profiler::hang::HangMonitor>,
983    pub(crate) entities: EntityMap,
984    pub(crate) new_entity_observers: SubscriberSet<TypeId, NewEntityListener>,
985    pub(crate) windows: SlotMap<WindowId, Option<Box<Window>>>,
986    pub(crate) window_handles: FxHashMap<WindowId, AnyWindowHandle>,
987    pub(crate) focus_handles: Arc<RwLock<FocusMap>>,
988    pub(crate) keymap: Rc<RefCell<Keymap>>,
989    pub(crate) keyboard_layout: Box<dyn PlatformKeyboardLayout>,
990    pub(crate) keyboard_mapper: Rc<dyn PlatformKeyboardMapper>,
991    pub(crate) global_action_listeners:
992        TypeIdHashMap<Vec<Rc<dyn Fn(&dyn Any, DispatchPhase, &mut Self)>>>,
993    pending_effects: VecDeque<Effect>,
994
995    pub(crate) observers: SubscriberSet<EntityId, Handler>,
996    pub(crate) event_listeners: SubscriberSet<EntityId, (TypeId, Listener)>,
997    pub(crate) keystroke_observers: SubscriberSet<(), KeystrokeObserver>,
998    pub(crate) keystroke_interceptors: SubscriberSet<(), KeystrokeObserver>,
999    pub(crate) keyboard_layout_observers: SubscriberSet<(), Handler>,
1000    pub(crate) thermal_state_observers: SubscriberSet<(), Handler>,
1001    pub(crate) display_observers: SubscriberSet<(), DisplayHandler>,
1002    /// The connected displays, as of the platform's last display change
1003    /// notification.
1004    displays: HashMap<DisplayId, DisplayState>,
1005    pub(crate) system_sleep_observers: SubscriberSet<(), Handler>,
1006    pub(crate) system_wake_observers: SubscriberSet<(), Handler>,
1007    app_lifecycle_observers: SubscriberSet<(), AppLifecycleHandler>,
1008    memory_warning_observers: SubscriberSet<(), Handler>,
1009    pub(crate) release_listeners: SubscriberSet<EntityId, ReleaseListener>,
1010    pub(crate) global_observers: SubscriberSet<TypeId, Handler>,
1011    pub(crate) quit_observers: SubscriberSet<(), QuitHandler>,
1012    pub(crate) restart_observers: SubscriberSet<(), Handler>,
1013    pub(crate) window_closed_observers: SubscriberSet<(), WindowClosedHandler>,
1014
1015    /// Per-App element arena. This isolates element allocations between different
1016    /// App instances (important for tests where multiple Apps run concurrently).
1017    pub(crate) element_arena: RefCell<Arena>,
1018    /// Per-App event arena.
1019    pub(crate) event_arena: Arena,
1020
1021    // Drop globals last. We need to ensure all tasks owned by entities and
1022    // callbacks are marked cancelled at this point as this will also shutdown
1023    // the tokio runtime. As any task attempting to spawn a blocking tokio task,
1024    // might panic.
1025    pub(crate) globals_by_type: TypeIdHashMap<Box<dyn Any>>,
1026    global_revisions: TypeIdHashMap<u64>,
1027    global_reads: RefCell<Vec<TypeId>>,
1028    revision_reads: RefCell<Vec<Revision>>,
1029    // Entities which are retained until explicitly removed from the app or dropped at end of life-cycle.
1030    // This is an alternative way to define "global" data which uses entities.
1031    // There can be multiple entities of a given type & each `Entity<T>` is stored as `Box<dyn Any>`.
1032    global_entities: Vec<AnyEntity>,
1033
1034    // assets
1035    pub(crate) loading_assets: FxHashMap<(TypeId, u64), Box<dyn Any>>,
1036    asset_registry: Arc<AssetRegistry>,
1037    pub(crate) svg_renderer: SvgRenderer,
1038    http_client: Arc<dyn HttpClient>,
1039
1040    // below is plain data, the drop order is insignificant here
1041    pub(crate) pending_notifications: FxHashSet<EntityId>,
1042    pub(crate) pending_global_notifications: TypeIdHashSet,
1043    pub(crate) restart_path: Option<PathBuf>,
1044    pub(crate) restart_arguments: Vec<OsString>,
1045    pub(crate) layout_id_buffer: Vec<LayoutId>, // We recycle this memory across layout requests.
1046    pub(crate) propagate_event: bool,
1047    pub(crate) prompt_builder: Option<PromptBuilder>,
1048    pub(crate) window_invalidators_by_entity:
1049        FxHashMap<EntityId, FxHashMap<WindowId, WindowInvalidator>>,
1050    pub(crate) tracked_entities: FxHashMap<WindowId, FxHashSet<EntityId>>,
1051    pub(crate) current_window_by_entity: FxHashMap<EntityId, WindowId>,
1052    #[cfg(any(feature = "inspector", debug_assertions))]
1053    pub(crate) inspector_renderer: Option<crate::InspectorRenderer>,
1054    #[cfg(any(feature = "inspector", debug_assertions))]
1055    pub(crate) inspector_element_registry: InspectorElementRegistry,
1056    #[cfg(any(test, feature = "test-support", debug_assertions))]
1057    pub(crate) name: Option<&'static str>,
1058    pub(crate) text_rendering_mode: Rc<Cell<TextRenderingMode>>,
1059
1060    pub(crate) window_update_stack: Vec<WindowId>,
1061    pub(crate) mode: GpuiMode,
1062    pub(crate) cursor_hide_mode: CursorHideMode,
1063    pub(crate) reduce_motion: bool,
1064    /// Origin of the shared clock that phase-locks synced repeating animations.
1065    pub(crate) synced_animation_epoch: Instant,
1066    /// Whether the app was created by [`Application::new_inaccessible`]. No
1067    /// accesskit APIs will be called when this flag is set.
1068    pub(crate) accessibility_force_disabled: bool,
1069    /// Whether windows build their accessibility tree every frame without an
1070    /// assistive-technology client. See [`Application::with_accessibility_forced`].
1071    pub(crate) accessibility_forced: bool,
1072    pending_updates: usize,
1073    quit_mode: QuitMode,
1074    quitting: bool,
1075
1076    // We need to ensure the leak detector drops last, after all tasks, callbacks and things have been dropped.
1077    // Otherwise it may report false positives.
1078    #[cfg(any(test, gpui_leak_detection))]
1079    _ref_counts: Arc<RwLock<EntityRefCounts>>,
1080}
1081
1082impl App {
1083    #[allow(clippy::new_ret_no_self)]
1084    pub(crate) fn new_app(
1085        platform: Rc<dyn Platform>,
1086        asset_registry: Arc<AssetRegistry>,
1087        http_client: Arc<dyn HttpClient>,
1088    ) -> Rc<AppCell> {
1089        let background_executor = platform.background_executor();
1090        let foreground_executor = platform.foreground_executor();
1091        assert!(
1092            background_executor.is_main_thread(),
1093            "must construct App on main thread"
1094        );
1095        #[cfg(feature = "profiler")]
1096        let foreground_journal = crate::profiler::journal::install_foreground_journal();
1097        let synced_animation_epoch = background_executor.now();
1098
1099        let text_system = Arc::new(TextSystem::new(platform.text_system()));
1100        let entities = EntityMap::new();
1101        let keyboard_layout = platform.keyboard_layout();
1102        let keyboard_mapper = platform.keyboard_mapper();
1103
1104        #[cfg(any(test, gpui_leak_detection))]
1105        let _ref_counts = entities.ref_counts_drop_handle();
1106
1107        let app = Rc::new_cyclic(|this| AppCell {
1108            app: RefCell::new(App {
1109                this: this.clone(),
1110                platform: platform.clone(),
1111                text_system,
1112                text_rendering_mode: Rc::new(Cell::new(TextRenderingMode::default())),
1113                mode: GpuiMode::Production,
1114                actions: Rc::new(ActionRegistry::default()),
1115                pending_updates: 0,
1116                active_drag: None,
1117                platform_owned_drag: None,
1118                background_executor,
1119                foreground_executor,
1120                #[cfg(feature = "profiler")]
1121                foreground_journal,
1122                #[cfg(all(feature = "profiler", not(target_family = "wasm")))]
1123                hang_monitor: None,
1124                svg_renderer: SvgRenderer::new(asset_registry.clone()),
1125                loading_assets: Default::default(),
1126                asset_registry,
1127                http_client,
1128                globals_by_type: Default::default(),
1129                global_revisions: Default::default(),
1130                global_reads: Default::default(),
1131                revision_reads: Default::default(),
1132                global_entities: Default::default(),
1133                entities,
1134                new_entity_observers: SubscriberSet::new(),
1135                windows: SlotMap::with_key(),
1136                window_update_stack: Vec::new(),
1137                window_handles: FxHashMap::default(),
1138                focus_handles: Arc::new(RwLock::new(FocusMap::default())),
1139                keymap: Rc::new(RefCell::new(Keymap::default())),
1140                keyboard_layout,
1141                keyboard_mapper,
1142                global_action_listeners: Default::default(),
1143                pending_effects: VecDeque::new(),
1144                pending_notifications: FxHashSet::default(),
1145                pending_global_notifications: Default::default(),
1146                observers: SubscriberSet::new(),
1147                tracked_entities: FxHashMap::default(),
1148                window_invalidators_by_entity: FxHashMap::default(),
1149                current_window_by_entity: FxHashMap::default(),
1150                event_listeners: SubscriberSet::new(),
1151                release_listeners: SubscriberSet::new(),
1152                keystroke_observers: SubscriberSet::new(),
1153                keystroke_interceptors: SubscriberSet::new(),
1154                keyboard_layout_observers: SubscriberSet::new(),
1155                thermal_state_observers: SubscriberSet::new(),
1156                display_observers: SubscriberSet::new(),
1157                displays: read_displays(platform.as_ref()),
1158                system_sleep_observers: SubscriberSet::new(),
1159                system_wake_observers: SubscriberSet::new(),
1160                app_lifecycle_observers: SubscriberSet::new(),
1161                memory_warning_observers: SubscriberSet::new(),
1162                global_observers: SubscriberSet::new(),
1163                quit_observers: SubscriberSet::new(),
1164                restart_observers: SubscriberSet::new(),
1165                restart_path: None,
1166                restart_arguments: Vec::new(),
1167                window_closed_observers: SubscriberSet::new(),
1168                layout_id_buffer: Default::default(),
1169                propagate_event: true,
1170                prompt_builder: Some(PromptBuilder::Default),
1171                #[cfg(any(feature = "inspector", debug_assertions))]
1172                inspector_renderer: None,
1173                #[cfg(any(feature = "inspector", debug_assertions))]
1174                inspector_element_registry: InspectorElementRegistry::default(),
1175                quit_mode: QuitMode::default(),
1176                quitting: false,
1177                cursor_hide_mode: CursorHideMode::default(),
1178                reduce_motion: false,
1179                synced_animation_epoch,
1180                accessibility_force_disabled: false,
1181                accessibility_forced: false,
1182
1183                #[cfg(any(test, feature = "test-support", debug_assertions))]
1184                name: None,
1185                element_arena: RefCell::new(Arena::new(1024 * 1024)),
1186                event_arena: Arena::new(1024 * 1024),
1187
1188                #[cfg(any(test, gpui_leak_detection))]
1189                _ref_counts,
1190            }),
1191        });
1192
1193        init_app_menus(platform.as_ref(), &app.borrow());
1194        SystemWindowTabController::init(&mut app.borrow_mut());
1195        #[cfg(feature = "profiler")]
1196        crate::profiler::journal::observe_power(&app.borrow());
1197
1198        platform.on_keyboard_layout_change(Box::new({
1199            let app = Rc::downgrade(&app);
1200            move || {
1201                if let Some(app) = app.upgrade() {
1202                    let cx = &mut app.borrow_mut();
1203                    cx.keyboard_layout = cx.platform.keyboard_layout();
1204                    cx.keyboard_mapper = cx.platform.keyboard_mapper();
1205                    cx.keyboard_layout_observers
1206                        .clone()
1207                        .retain(&(), move |callback| (callback)(cx));
1208                }
1209            }
1210        }));
1211
1212        platform.on_thermal_state_change(Box::new({
1213            let app = Rc::downgrade(&app);
1214            move || {
1215                if let Some(app) = app.upgrade() {
1216                    let cx = &mut app.borrow_mut();
1217                    cx.thermal_state_observers
1218                        .clone()
1219                        .retain(&(), move |callback| (callback)(cx));
1220                }
1221            }
1222        }));
1223
1224        platform.on_displays_changed(Box::new({
1225            let app = Rc::downgrade(&app);
1226            move || {
1227                if let Some(app) = app.upgrade() {
1228                    app.borrow_mut().displays_changed();
1229                }
1230            }
1231        }));
1232
1233        platform.on_system_sleep(Box::new({
1234            let app = Rc::downgrade(&app);
1235            move || {
1236                if let Some(app) = app.upgrade() {
1237                    let cx = &mut app.borrow_mut();
1238                    cx.system_sleep_observers
1239                        .clone()
1240                        .retain(&(), move |callback| (callback)(cx));
1241                }
1242            }
1243        }));
1244
1245        platform.on_system_wake(Box::new({
1246            let app = Rc::downgrade(&app);
1247            move || {
1248                if let Some(app) = app.upgrade() {
1249                    let cx = &mut app.borrow_mut();
1250                    cx.system_wake_observers
1251                        .clone()
1252                        .retain(&(), move |callback| (callback)(cx));
1253                }
1254            }
1255        }));
1256
1257        platform.on_app_lifecycle(Box::new({
1258            let app = Rc::downgrade(&app);
1259            move |phase| {
1260                if let Some(app) = app.upgrade() {
1261                    app.borrow_mut().update(|cx| {
1262                        cx.app_lifecycle_observers
1263                            .clone()
1264                            .retain(&(), |callback| callback(phase, cx));
1265                    });
1266                }
1267            }
1268        }));
1269
1270        platform.on_memory_warning(Box::new({
1271            let app = Rc::downgrade(&app);
1272            move || {
1273                if let Some(app) = app.upgrade() {
1274                    app.borrow_mut().update(|cx| {
1275                        cx.memory_warning_observers
1276                            .clone()
1277                            .retain(&(), |callback| callback(cx));
1278                    });
1279                }
1280            }
1281        }));
1282
1283        platform.on_quit(Box::new({
1284            let cx = Rc::downgrade(&app);
1285            move || {
1286                let Some(cx) = cx.upgrade() else {
1287                    return true;
1288                };
1289                match cx.try_borrow_mut() {
1290                    Ok(mut cx) => {
1291                        cx.shutdown();
1292                        true
1293                    }
1294                    Err(_) => {
1295                        // Quit was requested while the AppCell was borrowed, so we can't shut down synchronously.
1296                        // The platform decides how to proceed.
1297                        false
1298                    }
1299                }
1300            }
1301        }));
1302
1303        app
1304    }
1305
1306    #[doc(hidden)]
1307    pub fn ref_counts_drop_handle(&self) -> impl Sized + use<> {
1308        self.entities.ref_counts_drop_handle()
1309    }
1310
1311    /// Captures a snapshot of all entities that currently have alive handles.
1312    ///
1313    /// The returned [`LeakDetectorSnapshot`] can later be passed to
1314    /// [`assert_no_new_leaks`](Self::assert_no_new_leaks) to verify that no
1315    /// entities created after the snapshot are still alive.
1316    #[cfg(any(test, gpui_leak_detection))]
1317    pub fn leak_detector_snapshot(&self) -> LeakDetectorSnapshot {
1318        self.entities.leak_detector_snapshot()
1319    }
1320
1321    /// Asserts that no entities created after `snapshot` still have alive handles.
1322    ///
1323    /// Entities that were already tracked at the time of the snapshot are ignored,
1324    /// even if they still have handles. Only *new* entities (those whose
1325    /// `EntityId` was not present in the snapshot) are considered leaks.
1326    ///
1327    /// # Panics
1328    ///
1329    /// Panics if any new entity handles exist. The panic message lists every
1330    /// leaked entity with its type name, and includes allocation-site backtraces
1331    /// when `LEAK_BACKTRACE` is set.
1332    #[cfg(any(test, gpui_leak_detection))]
1333    pub fn assert_no_new_leaks(&self, snapshot: &LeakDetectorSnapshot) {
1334        self.entities.assert_no_new_leaks(snapshot)
1335    }
1336
1337    /// Without leak detection compiled in, this records nothing.
1338    #[cfg(all(feature = "test-support", not(any(test, gpui_leak_detection))))]
1339    pub fn leak_detector_snapshot(&self) -> LeakDetectorSnapshot {
1340        LeakDetectorSnapshot::default()
1341    }
1342
1343    /// Without leak detection compiled in, this checks nothing. Set
1344    /// `GPUI_LEAK_DETECTION` when building to enable it.
1345    #[cfg(all(feature = "test-support", not(any(test, gpui_leak_detection))))]
1346    pub fn assert_no_new_leaks(&self, _snapshot: &LeakDetectorSnapshot) {}
1347
1348    /// Runs the quit handlers, closes every window and flushes pending effects.
1349    ///
1350    /// The platform calls this when the app quits. Handlers registered with
1351    /// [`Context::on_app_quit`] run first. Native apps wait up to [`SHUTDOWN_TIMEOUT`]
1352    /// for them to finish and log an error if they don't. On the web the handlers run
1353    /// asynchronously as best-effort cleanup, because the event loop cannot block.
1354    ///
1355    /// To quit from your own code, call [`App::quit`] instead.
1356    pub fn shutdown(&mut self) {
1357        // Requested first so the final hang poll overlaps with the quit
1358        // handlers. It's awaited alongside them, within `SHUTDOWN_TIMEOUT`.
1359        #[cfg(all(feature = "profiler", not(target_family = "wasm")))]
1360        let hang_monitor_flush = self
1361            .hang_monitor
1362            .as_ref()
1363            .and_then(|hang_monitor| hang_monitor.request_flush());
1364
1365        let mut futures: Vec<LocalBoxFuture<'static, ()>> = Vec::new();
1366
1367        for observer in self.quit_observers.remove(&()) {
1368            futures.push(observer(self));
1369        }
1370
1371        #[cfg(all(feature = "profiler", not(target_family = "wasm")))]
1372        if let Some(flushed) = hang_monitor_flush {
1373            futures.push(
1374                async move {
1375                    if flushed.await.is_err() {
1376                        log::warn!("hang monitor exited before flushing");
1377                    }
1378                }
1379                .boxed_local(),
1380            );
1381        }
1382
1383        self.windows.clear();
1384        self.window_handles.clear();
1385        self.flush_effects();
1386        self.quitting = true;
1387
1388        let futures = futures::future::join_all(futures);
1389        #[cfg(not(target_family = "wasm"))]
1390        if self
1391            .foreground_executor
1392            .block_with_timeout(SHUTDOWN_TIMEOUT, futures)
1393            .is_err()
1394        {
1395            log::error!("timed out waiting on app_will_quit");
1396        }
1397        #[cfg(target_family = "wasm")]
1398        self.foreground_executor.spawn(futures).detach();
1399
1400        self.quitting = false;
1401    }
1402
1403    /// Returns the keyboard layout that is active now.
1404    ///
1405    /// Use it to translate between keystrokes and the characters they produce. The
1406    /// value is updated when the layout changes, which [`App::on_keyboard_layout_change`]
1407    /// reports.
1408    pub fn keyboard_layout(&self) -> &dyn PlatformKeyboardLayout {
1409        self.keyboard_layout.as_ref()
1410    }
1411
1412    /// Returns the keyboard mapper for the active layout.
1413    pub fn keyboard_mapper(&self) -> &Rc<dyn PlatformKeyboardMapper> {
1414        &self.keyboard_mapper
1415    }
1416
1417    /// Calls `callback` each time the user switches the keyboard layout.
1418    ///
1419    /// The subscription stays active while you hold it. Drop it to stop receiving
1420    /// calls. By the time the callback runs, [`App::keyboard_layout`] already returns
1421    /// the new layout.
1422    pub fn on_keyboard_layout_change<F>(&self, mut callback: F) -> Subscription
1423    where
1424        F: 'static + FnMut(&mut App),
1425    {
1426        let (subscription, activate) = self.keyboard_layout_observers.insert(
1427            (),
1428            Box::new(move |cx| {
1429                callback(cx);
1430                true
1431            }),
1432        );
1433        activate();
1434        subscription
1435    }
1436
1437    /// Asks the platform to quit the app, the same as choosing Quit from the app menu.
1438    ///
1439    /// The quit happens later, not inside this call. The platform then calls
1440    /// [`App::shutdown`], which runs the [`Context::on_app_quit`] handlers and closes
1441    /// the windows. Use this to quit from your own code. [`QuitMode`] controls quits
1442    /// that happen when the last window closes.
1443    pub fn quit(&self) {
1444        self.platform.quit();
1445    }
1446
1447    /// Switches the platform between headless and windowed modes.
1448    ///
1449    /// On Linux, headless means no display server: windows opened afterwards lay out and handle
1450    /// input but draw nothing. Windowed, the platform connects to the display server the
1451    /// environment names. On macOS, the modes set the [`ActivationPolicy`]: headless is
1452    /// `Accessory` (no Dock icon or menu bar) and windowed is `Regular`. Switching to windowed
1453    /// doesn't activate the app: call [`App::activate`] for that.
1454    ///
1455    /// The returned task resolves once the switch has been applied. It fails if the platform is
1456    /// already in the requested mode (switching to another display server means going headless
1457    /// first), if the platform doesn't allow the mode or can't switch at all, if any window is
1458    /// open (a window belongs to the display server that opened it), or if the display server
1459    /// can't be reached.
1460    pub fn request_windowing(&self, request: WindowingRequest) -> Task<anyhow::Result<()>> {
1461        if !self.windows.is_empty() {
1462            return Task::ready(Err(anyhow::anyhow!(
1463                "cannot switch windowing modes while windows are open"
1464            )));
1465        }
1466        self.platform.request_windowing(request)
1467    }
1468
1469    /// The environment of the display server the platform is connected to, or `None` while
1470    /// headless. Its activation token is always unset, since the connection has used it.
1471    ///
1472    /// Programs an app launches inherit this process's environment, which may name another
1473    /// graphical session, or none if the app started headless. Pass them this one with
1474    /// [`GraphicalEnvironment::apply_to`](crate::GraphicalEnvironment::apply_to).
1475    ///
1476    /// On macOS, the environment carries nothing, and this is `None` while the activation
1477    /// policy is `Accessory`. Always `None` on platforms that can't switch windowing modes.
1478    pub fn graphical_environment(&self) -> Option<crate::GraphicalEnvironment> {
1479        self.platform.graphical_environment()
1480    }
1481
1482    /// Returns the policy that decides when GPUI hides the cursor while typing.
1483    ///
1484    /// Defaults to [`CursorHideMode::OnTypingAndAction`].
1485    pub fn cursor_hide_mode(&self) -> CursorHideMode {
1486        self.cursor_hide_mode
1487    }
1488
1489    /// Sets the policy that decides when GPUI hides the cursor while typing.
1490    ///
1491    /// Takes effect for the next keystroke. The cursor reappears when the mouse moves.
1492    pub fn set_cursor_hide_mode(&mut self, mode: CursorHideMode) {
1493        self.cursor_hide_mode = mode;
1494    }
1495
1496    /// Returns whether the cursor is currently visible according to the
1497    /// platform. This will report `false` after a keyboard input has hidden
1498    /// the cursor and the user has not yet moved the mouse to restore it.
1499    ///
1500    /// See [`App::set_cursor_hide_mode`].
1501    pub fn is_cursor_visible(&self) -> bool {
1502        self.platform.is_cursor_visible()
1503    }
1504
1505    /// Returns whether non-essential animations should render in a static state.
1506    ///
1507    /// Check this before you start a decorative animation, such as a spinner that only
1508    /// looks busy. The app sets it, and it defaults to `false`.
1509    pub fn reduce_motion(&self) -> bool {
1510        self.reduce_motion
1511    }
1512
1513    /// Sets whether non-essential animations should render in a static state.
1514    ///
1515    /// Setting a different value redraws all windows. Animations that are needed to
1516    /// show state, such as a progress bar, should keep running.
1517    pub fn set_reduce_motion(&mut self, reduce_motion: bool) {
1518        if self.reduce_motion != reduce_motion {
1519            self.reduce_motion = reduce_motion;
1520            self.refresh_windows();
1521        }
1522    }
1523
1524    /// Redraws every window once the current update finishes.
1525    ///
1526    /// Calling it several times in one update still causes a single redraw per window.
1527    /// Use [`Context::notify`] on the entity that changed instead when you can. Use this
1528    /// when state outside any entity changes what is drawn.
1529    pub fn refresh_windows(&mut self) {
1530        self.pending_effects.push_back(Effect::RefreshWindows);
1531    }
1532
1533    #[inline(always)]
1534    pub(crate) fn update<R>(&mut self, update: impl FnOnce(&mut Self) -> R) -> R {
1535        self.start_update();
1536        let result = update(self);
1537        self.finish_update();
1538        result
1539    }
1540
1541    pub(crate) fn start_update(&mut self) {
1542        self.pending_updates += 1;
1543    }
1544
1545    #[inline(never)]
1546    pub(crate) fn finish_update(&mut self) {
1547        if self.pending_updates == 1 {
1548            self.flush_effects();
1549        }
1550        self.pending_updates -= 1;
1551    }
1552
1553    /// Calls `on_notify` each time `entity` calls [`Context::notify`].
1554    ///
1555    /// The callback receives the entity and the [`App`]. It runs when the update that
1556    /// called `notify` finishes, not during that call. Keep the returned [`Subscription`]
1557    /// alive, because dropping it ends the observation.
1558    ///
1559    /// # Examples
1560    ///
1561    /// ```
1562    /// # use gpui::{AppContext, TestApp};
1563    /// # use std::{cell::Cell, rc::Rc};
1564    /// # let mut app = TestApp::new();
1565    /// let seen = Rc::new(Cell::new(0));
1566    /// let counter = app.update(|cx| cx.new(|_| 0));
1567    /// let _subscription = app.update(|cx| {
1568    ///     cx.observe(&counter, {
1569    ///         let seen = seen.clone();
1570    ///         move |counter, cx| seen.set(*counter.read(cx))
1571    ///     })
1572    /// });
1573    /// app.update(|cx| {
1574    ///     counter.update(cx, |count, cx| {
1575    ///         *count = 2;
1576    ///         cx.notify();
1577    ///     })
1578    /// });
1579    /// assert_eq!(seen.get(), 2);
1580    /// ```
1581    ///
1582    /// See [ownership and data flow](crate::_documentation::concepts::ownership).
1583    pub fn observe<W>(
1584        &mut self,
1585        entity: &Entity<W>,
1586        mut on_notify: impl FnMut(Entity<W>, &mut App) + 'static,
1587    ) -> Subscription
1588    where
1589        W: 'static,
1590    {
1591        self.observe_internal(entity, move |e, cx| {
1592            on_notify(e, cx);
1593            true
1594        })
1595    }
1596
1597    /// Runs `callback` and returns what it read: the entities, and the globals at their
1598    /// current revisions. Reads by nested recordings count for the enclosing ones too.
1599    pub(crate) fn record_dependencies<R>(
1600        &mut self,
1601        callback: impl FnOnce(&mut App) -> R,
1602    ) -> (R, Dependencies) {
1603        let entities_start = self.entities.access_log.get_mut().len();
1604        let globals_start = self.global_reads.get_mut().len();
1605        let revisions_start = self.revision_reads.get_mut().len();
1606        *self.entities.recordings.get_mut() += 1;
1607        let result = callback(self);
1608        let recordings = self.entities.recordings.get_mut();
1609        *recordings -= 1;
1610        let outermost = *recordings == 0;
1611
1612        let log = self.entities.access_log.get_mut();
1613        let mut entities = log[entities_start..].to_vec();
1614        entities.sort_unstable();
1615        entities.dedup();
1616        let reads = self.global_reads.get_mut();
1617        let mut globals: Vec<(TypeId, u64)> = reads[globals_start..]
1618            .iter()
1619            .map(|global_type| (*global_type, 0))
1620            .collect();
1621        let revision_reads = self.revision_reads.get_mut();
1622        let mut revisions: Vec<(Revision, u64)> = Vec::new();
1623        for revision in revision_reads.drain(revisions_start..) {
1624            if !revisions.iter().any(|(known, _)| known.same(&revision)) {
1625                let seen = revision.0.get();
1626                revisions.push((revision, seen));
1627            }
1628        }
1629        if !outermost {
1630            // Enclosing recordings depend on these too.
1631            revision_reads.extend(revisions.iter().map(|(revision, _)| revision.clone()));
1632        }
1633        if outermost {
1634            log.clear();
1635            reads.clear();
1636        }
1637        globals.sort_unstable();
1638        globals.dedup();
1639        for (global_type, revision) in &mut globals {
1640            *revision = self.global_revision(*global_type);
1641        }
1642        (
1643            result,
1644            Dependencies {
1645                entities,
1646                globals,
1647                revisions,
1648            },
1649        )
1650    }
1651
1652    /// Counts `dependencies` as read again, as when a view's output is reused.
1653    pub(crate) fn replay_dependencies(&mut self, dependencies: &Dependencies) {
1654        for entity_id in &dependencies.entities {
1655            self.entities.note_access(*entity_id);
1656        }
1657        for (global_type, _) in &dependencies.globals {
1658            self.note_global_read(*global_type);
1659        }
1660        for (revision, _) in &dependencies.revisions {
1661            self.note_revision(revision);
1662        }
1663    }
1664
1665    /// Records that the drawing view read state versioned by `revision`.
1666    pub(crate) fn note_revision(&self, revision: &Revision) {
1667        if self.entities.recordings.get() > 0 {
1668            self.revision_reads.borrow_mut().push(revision.clone());
1669        }
1670    }
1671
1672    /// Returns whether anything in `dependencies` changed: an entity in `dirty`, or a global
1673    /// written since it was read.
1674    pub(crate) fn dependencies_changed(
1675        &self,
1676        dependencies: &Dependencies,
1677        dirty: &FxHashSet<EntityId>,
1678    ) -> bool {
1679        dependencies.entities.iter().any(|id| dirty.contains(id))
1680            || dependencies
1681                .globals
1682                .iter()
1683                .any(|(global_type, revision)| self.global_revision(*global_type) != *revision)
1684            || dependencies
1685                .revisions
1686                .iter()
1687                .any(|(revision, seen)| revision.0.get() != *seen)
1688    }
1689
1690    fn note_global_read(&self, global_type: TypeId) {
1691        if self.entities.recordings.get() > 0 {
1692            self.global_reads.borrow_mut().push(global_type);
1693        }
1694    }
1695
1696    fn global_revision(&self, global_type: TypeId) -> u64 {
1697        self.global_revisions
1698            .get(&global_type)
1699            .copied()
1700            .unwrap_or(0)
1701    }
1702
1703    fn global_changed(&mut self, global_type: TypeId) {
1704        *self.global_revisions.entry(global_type).or_default() += 1;
1705        self.push_effect(Effect::NotifyGlobalObservers { global_type });
1706    }
1707
1708    pub(crate) fn record_entities_accessed(
1709        &mut self,
1710        window_handle: AnyWindowHandle,
1711        invalidator: WindowInvalidator,
1712        entities: &FxHashSet<EntityId>,
1713    ) {
1714        let mut tracked_entities =
1715            std::mem::take(self.tracked_entities.entry(window_handle.id).or_default());
1716        for entity in tracked_entities.iter() {
1717            self.window_invalidators_by_entity
1718                .entry(*entity)
1719                .and_modify(|windows| {
1720                    windows.remove(&window_handle.id);
1721                });
1722        }
1723        for entity in entities.iter() {
1724            self.window_invalidators_by_entity
1725                .entry(*entity)
1726                .or_default()
1727                .insert(window_handle.id, invalidator.clone());
1728            self.current_window_by_entity
1729                .insert(*entity, window_handle.id);
1730        }
1731        tracked_entities.clear();
1732        tracked_entities.extend(entities.iter().copied());
1733        self.tracked_entities
1734            .insert(window_handle.id, tracked_entities);
1735    }
1736
1737    pub(crate) fn new_observer(&mut self, key: EntityId, value: Handler) -> Subscription {
1738        let (subscription, activate) = self.observers.insert(key, value);
1739        self.defer(move |_| activate());
1740        subscription
1741    }
1742
1743    pub(crate) fn observe_internal<W>(
1744        &mut self,
1745        entity: &Entity<W>,
1746        mut on_notify: impl FnMut(Entity<W>, &mut App) -> bool + 'static,
1747    ) -> Subscription
1748    where
1749        W: 'static,
1750    {
1751        let entity_id = entity.entity_id();
1752        let handle = entity.downgrade();
1753        self.new_observer(
1754            entity_id,
1755            Box::new(move |cx| {
1756                if let Some(entity) = handle.upgrade() {
1757                    on_notify(entity, cx)
1758                } else {
1759                    false
1760                }
1761            }),
1762        )
1763    }
1764
1765    /// Calls `on_event` each time `entity` emits an event of type `Event`.
1766    ///
1767    /// The callback receives the entity, a reference to the event and the [`App`]. The
1768    /// entity emits with [`Context::emit`]. Callbacks run when the update that emitted
1769    /// the event finishes. Keep the returned [`Subscription`] alive, because dropping it
1770    /// ends the subscription. Use [`App::observe`] when the entity only calls
1771    /// [`Context::notify`] and doesn't send a payload.
1772    ///
1773    /// # Examples
1774    ///
1775    /// ```
1776    /// # use gpui::{AppContext, EventEmitter, TestApp};
1777    /// # use std::{cell::Cell, rc::Rc};
1778    /// struct Counter;
1779    /// struct Incremented(usize);
1780    /// impl EventEmitter<Incremented> for Counter {}
1781    ///
1782    /// # let mut app = TestApp::new();
1783    /// let counter = app.update(|cx| cx.new(|_| Counter));
1784    /// let total = Rc::new(Cell::new(0));
1785    /// let _subscription = app.update(|cx| {
1786    ///     cx.subscribe(&counter, {
1787    ///         let total = total.clone();
1788    ///         move |_, event: &Incremented, _| total.set(total.get() + event.0)
1789    ///     })
1790    /// });
1791    /// app.update(|cx| counter.update(cx, |_, cx| cx.emit(Incremented(3))));
1792    /// assert_eq!(total.get(), 3);
1793    /// ```
1794    pub fn subscribe<T, Event>(
1795        &mut self,
1796        entity: &Entity<T>,
1797        mut on_event: impl FnMut(Entity<T>, &Event, &mut App) + 'static,
1798    ) -> Subscription
1799    where
1800        T: 'static + EventEmitter<Event>,
1801        Event: 'static,
1802    {
1803        self.subscribe_internal(entity, move |entity, event, cx| {
1804            on_event(entity, event, cx);
1805            true
1806        })
1807    }
1808
1809    pub(crate) fn new_subscription(
1810        &mut self,
1811        key: EntityId,
1812        value: (TypeId, Listener),
1813    ) -> Subscription {
1814        let (subscription, activate) = self.event_listeners.insert(key, value);
1815        self.defer(move |_| activate());
1816        subscription
1817    }
1818    pub(crate) fn subscribe_internal<T, Evt>(
1819        &mut self,
1820        entity: &Entity<T>,
1821        mut on_event: impl FnMut(Entity<T>, &Evt, &mut App) -> bool + 'static,
1822    ) -> Subscription
1823    where
1824        T: 'static + EventEmitter<Evt>,
1825        Evt: 'static,
1826    {
1827        let entity_id = entity.entity_id();
1828        let handle = entity.downgrade();
1829        self.new_subscription(
1830            entity_id,
1831            (
1832                TypeId::of::<Evt>(),
1833                Box::new(move |event, cx| {
1834                    let event: &Evt = event.downcast_ref().expect("invalid event type");
1835                    if let Some(entity) = handle.upgrade() {
1836                        on_event(entity, event, cx)
1837                    } else {
1838                        false
1839                    }
1840                }),
1841            ),
1842        )
1843    }
1844
1845    /// Returns handles to every open window.
1846    ///
1847    /// Each handle is untyped. [`AnyWindowHandle::downcast`] checks the root type recorded in
1848    /// the handle. If the root may have been replaced, use [`AnyWindowHandle::update`] to
1849    /// inspect the live root; the recorded type does not change with it.
1850    pub fn windows(&self) -> Vec<AnyWindowHandle> {
1851        self.windows
1852            .keys()
1853            .flat_map(|window_id| self.window_handles.get(&window_id).copied())
1854            .collect()
1855    }
1856
1857    /// Returns the window handles ordered by their appearance on screen, front to back.
1858    ///
1859    /// The first window in the returned list is the active/topmost window of the application.
1860    ///
1861    /// This method returns None if the platform doesn't implement the method yet.
1862    pub fn window_stack(&self) -> Option<Vec<AnyWindowHandle>> {
1863        self.platform.window_stack()
1864    }
1865
1866    /// Sets the GPU device requirements (extra features and limits) for the renderer.
1867    /// Only macOS uses them.
1868    ///
1869    /// Call this before opening any window. The argument must be a
1870    /// `gpui_wgpu::WgpuDeviceRequirements` boxed as `Box<dyn Any>`.
1871    pub fn set_gpu_requirements(&self, requirements: Box<dyn std::any::Any>) {
1872        self.platform.set_gpu_requirements(requirements);
1873    }
1874
1875    /// Sets the label applied to credentials stored in the system keyring.
1876    /// Call before writing credentials. Only Linux/FreeBSD apply the label.
1877    pub fn set_keyring_label(&self, label: impl Into<SharedString>) {
1878        self.platform.set_keyring_label(label.into());
1879    }
1880
1881    /// Returns the handle of the window that the platform reports as active, if any.
1882    ///
1883    /// Returns `None` when no window of this app has focus, for example when another
1884    /// application is in front.
1885    pub fn active_window(&self) -> Option<AnyWindowHandle> {
1886        self.platform.active_window()
1887    }
1888
1889    /// Opens a window and builds its root view.
1890    ///
1891    /// `build_root_view` runs once, with the new [`Window`] and the [`App`], and returns
1892    /// the root entity. The window is drawn once before this method returns. Use the
1893    /// returned [`WindowHandle`] to update or read the root view later.
1894    ///
1895    /// In tests, `TestApp::open_window` opens a window without a display.
1896    ///
1897    /// # Errors
1898    ///
1899    /// Returns an error if the platform cannot create the window. In that case
1900    /// `build_root_view` is not called.
1901    ///
1902    /// # Examples
1903    ///
1904    /// ```
1905    /// # use gpui::{AppContext, Context, Render, TestApp, Window, WindowOptions, div, prelude::*};
1906    /// struct Hello;
1907    ///
1908    /// impl Render for Hello {
1909    ///     fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
1910    ///         div().child("Hello")
1911    ///     }
1912    /// }
1913    ///
1914    /// # let mut app = TestApp::new();
1915    /// let window = app.update(|cx| {
1916    ///     cx.open_window(WindowOptions::default(), |_, cx| cx.new(|_| Hello))
1917    ///         .unwrap()
1918    /// });
1919    /// app.read(|cx| assert_eq!(cx.windows().len(), 1));
1920    /// # let _ = window;
1921    /// ```
1922    pub fn open_window<V: 'static + Render>(
1923        &mut self,
1924        options: crate::WindowOptions,
1925        build_root_view: impl FnOnce(&mut Window, &mut App) -> Entity<V>,
1926    ) -> anyhow::Result<WindowHandle<V>> {
1927        self.update(|cx| {
1928            let id = cx.windows.insert(None);
1929            let handle = WindowHandle::new(id);
1930            match Window::new(handle.into(), options, cx) {
1931                Ok(mut window) => {
1932                    cx.window_update_stack.push(id);
1933                    let root_view = build_root_view(&mut window, cx);
1934                    cx.window_update_stack.pop();
1935                    window.root.replace(root_view.into());
1936                    window.defer(cx, |window: &mut Window, cx| window.appearance_changed(cx));
1937
1938                    // allow a window to draw at least once before returning
1939                    // this didn't cause any issues on non windows platforms as it seems we always won the race to on_request_frame
1940                    // on windows we quite frequently lose the race and return a window that has never rendered, which leads to a crash
1941                    // where DispatchTree::root_node_id asserts on empty nodes
1942                    let clear = window.draw(cx);
1943                    clear.clear(cx);
1944
1945                    cx.window_handles.insert(id, window.handle);
1946                    cx.windows.get_mut(id).unwrap().replace(Box::new(window));
1947                    Ok(handle)
1948                }
1949                Err(e) => {
1950                    cx.windows.remove(id);
1951                    Err(e)
1952                }
1953            }
1954        })
1955    }
1956
1957    /// Brings the app to the front.
1958    ///
1959    /// Pass `ignoring_other_apps: true` to activate the app even when another app is in front.
1960    /// Use it sparingly, because it moves the user's focus.
1961    pub fn activate(&self, ignoring_other_apps: bool) {
1962        self.platform.activate(ignoring_other_apps);
1963    }
1964
1965    /// Hides the app, the same as choosing Hide from the app menu.
1966    pub fn hide(&self) {
1967        self.platform.hide();
1968    }
1969
1970    /// Hides all other applications.
1971    pub fn hide_other_apps(&self) {
1972        self.platform.hide_other_apps();
1973    }
1974
1975    /// Shows the applications hidden by [`App::hide_other_apps`].
1976    pub fn unhide_other_apps(&self) {
1977        self.platform.unhide_other_apps();
1978    }
1979
1980    /// Returns the connected displays.
1981    pub fn displays(&self) -> Vec<Rc<dyn PlatformDisplay>> {
1982        self.platform.displays()
1983    }
1984
1985    /// Returns the primary display, or `None` if the platform reports none.
1986    pub fn primary_display(&self) -> Option<Rc<dyn PlatformDisplay>> {
1987        self.platform.primary_display()
1988    }
1989
1990    /// Returns whether [`App::screen_capture_sources`] can return sources on this platform.
1991    pub fn is_screen_capture_supported(&self) -> bool {
1992        self.platform.is_screen_capture_supported()
1993    }
1994
1995    /// Asks the platform for the screens and windows that can be captured.
1996    ///
1997    /// The list arrives on the returned channel, so the call doesn't block. The channel
1998    /// yields an error if the platform can't list sources. Check
1999    /// [`App::is_screen_capture_supported`] first.
2000    pub fn screen_capture_sources(
2001        &self,
2002    ) -> oneshot::Receiver<Result<Vec<Rc<dyn ScreenCaptureSource>>>> {
2003        self.platform.screen_capture_sources()
2004    }
2005
2006    /// Returns the display with the given [`DisplayId`], or `None` if it is not connected.
2007    pub fn find_display(&self, id: DisplayId) -> Option<Rc<dyn PlatformDisplay>> {
2008        self.displays()
2009            .iter()
2010            .find(|display| display.id() == id)
2011            .cloned()
2012    }
2013
2014    /// Returns the system's current [`ThermalState`].
2015    ///
2016    /// Check it before heavy work, such as a long animation or a background
2017    /// computation, and reduce the work when the system is hot.
2018    pub fn thermal_state(&self) -> ThermalState {
2019        self.platform.thermal_state()
2020    }
2021
2022    /// Prevents idle sleep while the returned guard is held.
2023    pub fn prevent_idle_sleep(&self, reason: &str) -> Task<Result<ActivityGuard>> {
2024        self.platform.prevent_idle_sleep(reason)
2025    }
2026
2027    /// Calls `callback` when the system's thermal state changes.
2028    ///
2029    /// The subscription stays active while you hold it.
2030    pub fn on_thermal_state_change<F>(&self, mut callback: F) -> Subscription
2031    where
2032        F: 'static + FnMut(&mut App),
2033    {
2034        let (subscription, activate) = self.thermal_state_observers.insert(
2035            (),
2036            Box::new(move |cx| {
2037                callback(cx);
2038                true
2039            }),
2040        );
2041        activate();
2042        subscription
2043    }
2044
2045    /// Invokes a handler when the system is about to sleep.
2046    ///
2047    /// The platform gives the process only a short time before suspending, so
2048    /// handlers should record state or cancel work rather than start it.
2049    pub fn on_system_sleep<F>(&self, mut callback: F) -> Subscription
2050    where
2051        F: 'static + FnMut(&mut App),
2052    {
2053        let (subscription, activate) = self.system_sleep_observers.insert(
2054            (),
2055            Box::new(move |cx| {
2056                callback(cx);
2057                true
2058            }),
2059        );
2060        activate();
2061        subscription
2062    }
2063
2064    pub(crate) fn displays_changed(&mut self) {
2065        let current = read_displays(self.platform.as_ref());
2066        let events = display_events(&self.displays, &current);
2067        self.displays = current;
2068        for event in &events {
2069            let DisplayEvent::Changed { id, .. } = *event else {
2070                continue;
2071            };
2072            for handle in self.windows() {
2073                self.update_window(handle, |_, window, cx| {
2074                    if window.display_id == Some(id) {
2075                        window.notify_display_observers(cx);
2076                    }
2077                })
2078                .log_err();
2079            }
2080        }
2081        for event in events {
2082            self.display_observers
2083                .clone()
2084                .retain(&(), |callback| (callback)(event, self));
2085        }
2086    }
2087
2088    pub(crate) fn knows_display(&self, id: DisplayId) -> bool {
2089        self.displays.contains_key(&id)
2090    }
2091
2092    /// The refresh interval of a connected display, as of the platform's last
2093    /// display change notification.
2094    pub(crate) fn display_refresh_interval(&self, id: DisplayId) -> Option<Duration> {
2095        self.displays.get(&id)?.refresh_interval
2096    }
2097
2098    /// Invokes a handler when a display is connected, disconnected, or its
2099    /// properties change.
2100    pub fn observe_displays<F>(&self, mut callback: F) -> Subscription
2101    where
2102        F: 'static + FnMut(DisplayEvent, &mut App),
2103    {
2104        let (subscription, activate) = self.display_observers.insert(
2105            (),
2106            Box::new(move |event, cx| {
2107                callback(event, cx);
2108                true
2109            }),
2110        );
2111        activate();
2112        subscription
2113    }
2114
2115    /// Calls `callback` when the system wakes from sleep.
2116    ///
2117    /// Use it to reconnect to network services or refresh data that went stale
2118    /// while the machine slept. The subscription stays active while you hold it.
2119    pub fn on_system_wake<F>(&self, mut callback: F) -> Subscription
2120    where
2121        F: 'static + FnMut(&mut App),
2122    {
2123        let (subscription, activate) = self.system_wake_observers.insert(
2124            (),
2125            Box::new(move |cx| {
2126                callback(cx);
2127                true
2128            }),
2129        );
2130        activate();
2131        subscription
2132    }
2133
2134    /// Observes mobile application lifecycle changes. Desktop platforms do not
2135    /// emit these events. On iOS these currently describe the single connected
2136    /// scene, not individual windows.
2137    ///
2138    /// Save important changes incrementally: neither disconnection nor quit is
2139    /// guaranteed before the system terminates a backgrounded application.
2140    /// Dropping the returned subscription removes the observer.
2141    pub fn on_app_lifecycle(
2142        &self,
2143        mut callback: impl FnMut(AppLifecyclePhase, &mut App) + 'static,
2144    ) -> Subscription {
2145        let (subscription, activate) = self.app_lifecycle_observers.insert(
2146            (),
2147            Box::new(move |phase, cx| {
2148                callback(phase, cx);
2149                true
2150            }),
2151        );
2152        activate();
2153        subscription
2154    }
2155
2156    /// Observes mobile memory-pressure warnings so applications can release
2157    /// expendable caches. Dropping the subscription removes the observer.
2158    pub fn on_memory_warning(&self, mut callback: impl FnMut(&mut App) + 'static) -> Subscription {
2159        let (subscription, activate) = self.memory_warning_observers.insert(
2160            (),
2161            Box::new(move |cx| {
2162                callback(cx);
2163                true
2164            }),
2165        );
2166        activate();
2167        subscription
2168    }
2169
2170    /// Returns whether the windows use the light or dark appearance.
2171    ///
2172    /// This is the system setting unless [`App::set_window_appearance`] overrides it.
2173    pub fn window_appearance(&self) -> WindowAppearance {
2174        self.platform.window_appearance()
2175    }
2176
2177    /// Overrides the appearance (light/dark) applied to the app's windows, independent of
2178    /// the OS-wide setting. Pass `None` to clear the override and follow the system again.
2179    /// The current value is reported by [`App::window_appearance`].
2180    ///
2181    /// On macOS this sets the underlying `NSApplication.appearance`, which controls the
2182    /// native window chrome (the window border and titlebar) of every window. Use this
2183    /// when the app uses a dark theme while the system is in light mode (or vice versa)
2184    /// so the window edges render to match the theme. While an appearance is forced,
2185    /// windows stop tracking system light/dark changes; pass `None` to resume following
2186    /// the system. On other platforms this is a no-op.
2187    pub fn set_window_appearance(&self, appearance: Option<WindowAppearance>) {
2188        self.platform.set_window_appearance(appearance);
2189    }
2190
2191    /// Returns whether [`App::play_haptic_feedback`] does anything on this platform.
2192    pub fn supports_haptic_feedback(&self) -> bool {
2193        self.platform.supports_haptic_feedback()
2194    }
2195
2196    /// Plays a haptic feedback pulse of the given style.
2197    ///
2198    /// Call it from the main thread, for example in response to a click or a drop that
2199    /// the user should feel. It does nothing on platforms without haptics. Check
2200    /// [`App::supports_haptic_feedback`] to decide whether to show a haptic option.
2201    /// Styles correspond to
2202    /// [`NSHapticFeedbackPattern`](https://developer.apple.com/documentation/appkit/nshapticfeedbackmanager/feedbackpattern)
2203    /// values on macOS.
2204    pub fn play_haptic_feedback(&self, style: HapticFeedbackStyle) {
2205        self.platform.play_haptic_feedback(style)
2206    }
2207
2208    /// Returns the window button layout (the position of close, minimize and maximize), if the platform reports one.
2209    ///
2210    /// Returns `None` when the platform has no custom layout. Use it to draw your own
2211    /// window controls in the same place as the native ones.
2212    pub fn button_layout(&self) -> Option<WindowButtonLayout> {
2213        self.platform.button_layout()
2214    }
2215
2216    /// Reads the current contents of the system clipboard.
2217    ///
2218    /// Returns `None` if the clipboard is empty or holds nothing GPUI can read. On
2219    /// the web, use [`App::read_from_clipboard_async`] instead, because this method
2220    /// cannot wait for permission.
2221    pub fn read_from_clipboard(&self) -> Option<ClipboardItem> {
2222        self.platform.read_from_clipboard()
2223    }
2224
2225    /// Reads the system clipboard and resolves once the contents are available.
2226    ///
2227    /// Prefer this over [`App::read_from_clipboard`] in code that can await. On
2228    /// platforms where clipboard access is asynchronous and permission-gated (such as
2229    /// the web), the synchronous read always returns `None` while this method performs
2230    /// a real read. The task resolves to an error if the read fails.
2231    pub fn read_from_clipboard_async(
2232        &self,
2233    ) -> Task<Result<Option<ClipboardItem>, ClipboardReadError>> {
2234        self.platform.read_from_clipboard_async()
2235    }
2236
2237    /// Sets how text is rasterized for every window in the app.
2238    ///
2239    /// The default is [`TextRenderingMode::PlatformDefault`]. The new mode applies to
2240    /// text drawn after this call.
2241    pub fn set_text_rendering_mode(&mut self, mode: TextRenderingMode) {
2242        self.text_rendering_mode.set(mode);
2243    }
2244
2245    /// Returns how text is currently rasterized. See [`App::set_text_rendering_mode`].
2246    pub fn text_rendering_mode(&self) -> TextRenderingMode {
2247        self.text_rendering_mode.get()
2248    }
2249
2250    /// Replaces the contents of the system clipboard with `item`.
2251    ///
2252    /// # Examples
2253    ///
2254    /// ```
2255    /// # use gpui::{AppContext, ClipboardItem, TestApp};
2256    /// # let mut app = TestApp::new();
2257    /// app.update(|cx| cx.write_to_clipboard(ClipboardItem::new_string("copied".into())));
2258    /// app.read(|cx| {
2259    ///     let item = cx.read_from_clipboard().unwrap();
2260    ///     assert_eq!(item.text().as_deref(), Some("copied"));
2261    /// });
2262    /// ```
2263    pub fn write_to_clipboard(&self, item: ClipboardItem) {
2264        self.platform.write_to_clipboard(item)
2265    }
2266
2267    /// Reads data from the primary selection buffer.
2268    /// Only available on Linux and FreeBSD.
2269    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
2270    pub fn read_from_primary(&self) -> Option<ClipboardItem> {
2271        self.platform.read_from_primary()
2272    }
2273
2274    /// Writes data to the primary selection buffer.
2275    /// Only available on Linux and FreeBSD.
2276    #[cfg(any(target_os = "linux", target_os = "freebsd"))]
2277    pub fn write_to_primary(&self, item: ClipboardItem) {
2278        self.platform.write_to_primary(item)
2279    }
2280
2281    /// Reads data from macOS's "Find" pasteboard.
2282    ///
2283    /// Used to share the current search string between apps.
2284    ///
2285    /// <https://developer.apple.com/documentation/appkit/nspasteboard/name-swift.struct/find>
2286    #[cfg(target_os = "macos")]
2287    pub fn read_from_find_pasteboard(&self) -> Option<ClipboardItem> {
2288        self.platform.read_from_find_pasteboard()
2289    }
2290
2291    /// Writes data to macOS's "Find" pasteboard.
2292    ///
2293    /// Used to share the current search string between apps.
2294    ///
2295    /// <https://developer.apple.com/documentation/appkit/nspasteboard/name-swift.struct/find>
2296    #[cfg(target_os = "macos")]
2297    pub fn write_to_find_pasteboard(&self, item: ClipboardItem) {
2298        self.platform.write_to_find_pasteboard(item)
2299    }
2300
2301    /// Stores a username and password for `url` in the platform keychain.
2302    ///
2303    /// The task resolves once the store finishes, or to an error if it fails. Await it
2304    /// from a task spawned with [`App::spawn`].
2305    pub fn write_credentials(
2306        &self,
2307        url: &str,
2308        username: &str,
2309        password: &[u8],
2310    ) -> Task<Result<()>> {
2311        self.platform.write_credentials(url, username, password)
2312    }
2313
2314    /// Reads the username and password stored for `url`.
2315    ///
2316    /// The task resolves to `None` when nothing is stored for `url`. Use the same `url`
2317    /// that you passed to [`App::write_credentials`].
2318    pub fn read_credentials(&self, url: &str) -> Task<Result<Option<(String, Vec<u8>)>>> {
2319        self.platform.read_credentials(url)
2320    }
2321
2322    /// Removes the credentials stored for `url` from the platform keychain.
2323    pub fn delete_credentials(&self, url: &str) -> Task<Result<()>> {
2324        self.platform.delete_credentials(url)
2325    }
2326
2327    /// Opens `url` in the platform's default browser or handler.
2328    ///
2329    /// The call returns immediately. In tests, `TestApp::opened_url` reports the last
2330    /// URL passed here.
2331    pub fn open_url(&self, url: &str) {
2332        self.platform.open_url(url);
2333    }
2334
2335    /// Registers `scheme` (for example `zed` for `zed://` links) so that links with it open this app.
2336    ///
2337    /// Use [`Application::on_open_urls`] to receive the links. On some platforms you
2338    /// declare schemes when you package the app. This method registers them at runtime.
2339    pub fn register_url_scheme(&self, scheme: &str) -> Task<Result<()>> {
2340        self.platform.register_url_scheme(scheme)
2341    }
2342
2343    /// Sets the app's identifier and user-visible name for the operating system.
2344    ///
2345    /// The identifier is used for platform identity mechanisms such as the Windows
2346    /// AppUserModelID. The name is shown wherever the operating system presents the app.
2347    pub fn set_app_identity(&self, identifier: &str, name: &str) {
2348        self.platform.set_app_identity(identifier, name);
2349    }
2350
2351    /// Posts a notification to the operating system's notification center.
2352    ///
2353    /// Posting a notification whose [`SystemNotification::tag`] matches an
2354    /// earlier one replaces that notification where the platform supports it.
2355    /// No-op on platforms without notification support, or when delivery is
2356    /// unavailable (e.g. authorization was denied).
2357    pub fn show_system_notification(&self, notification: SystemNotification) {
2358        self.platform.show_system_notification(notification);
2359    }
2360
2361    /// Removes the delivered or pending notification with this tag.
2362    ///
2363    /// Best-effort: some platforms cannot retract a notification once shown,
2364    /// in which case it ages out of the notification center on its own.
2365    pub fn dismiss_system_notification(&self, tag: &str) {
2366        self.platform.dismiss_system_notification(tag);
2367    }
2368
2369    /// Registers the handler invoked when the user activates a system
2370    /// notification, either by clicking its body or one of its action
2371    /// buttons. Subsequent registrations replace the handler.
2372    pub fn on_system_notification_response<F>(&self, mut callback: F)
2373    where
2374        F: 'static + FnMut(SystemNotificationResponse, &mut App),
2375    {
2376        let this = self.this.clone();
2377        self.platform
2378            .on_system_notification_response(Box::new(move |response| {
2379                if let Some(app) = this.upgrade() {
2380                    callback(response, &mut app.borrow_mut());
2381                }
2382            }));
2383    }
2384
2385    /// Returns the full pathname of the current app bundle.
2386    ///
2387    /// Returns an error if the app is not being run from a bundle.
2388    pub fn app_path(&self) -> Result<PathBuf> {
2389        self.platform.app_path()
2390    }
2391
2392    /// On Linux, returns the name of the compositor in use. On the web, returns `"Web"`.
2393    ///
2394    /// Returns an empty string on other platforms.
2395    pub fn compositor_name(&self) -> &'static str {
2396        self.platform.compositor_name()
2397    }
2398
2399    /// Returns the path to a helper executable named `name` that ships with the app.
2400    ///
2401    /// See [`Application::path_for_auxiliary_executable`].
2402    pub fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
2403        self.platform.path_for_auxiliary_executable(name)
2404    }
2405
2406    /// Shows the platform's file or folder picker and returns the user's choice.
2407    ///
2408    /// The result arrives on the returned channel once the user picks paths or cancels.
2409    /// Cancelling yields `Ok(None)`. The picker is shown without blocking the caller.
2410    /// On Linux the channel yields an error if the picker can't be opened.
2411    pub fn prompt_for_paths(
2412        &self,
2413        options: PathPromptOptions,
2414    ) -> oneshot::Receiver<Result<Option<Vec<PathBuf>>>> {
2415        self.platform.prompt_for_paths(options)
2416    }
2417
2418    /// Shows the platform's save dialog and returns the path the user chose.
2419    ///
2420    /// `directory` is the folder the dialog opens in, and `suggested_name` pre-fills the
2421    /// file name. The result arrives on the returned channel. Cancelling yields
2422    /// `Ok(None)`. On Linux the channel yields an error if the dialog can't be opened.
2423    pub fn prompt_for_new_path(
2424        &self,
2425        directory: &Path,
2426        suggested_name: Option<&str>,
2427    ) -> oneshot::Receiver<Result<Option<PathBuf>>> {
2428        self.platform.prompt_for_new_path(directory, suggested_name)
2429    }
2430
2431    /// Shows `path` in the platform's file manager, such as Finder on macOS.
2432    pub fn reveal_path(&self, path: &Path) {
2433        self.platform.reveal_path(path)
2434    }
2435
2436    /// Opens `path` with the system's default application for its file type.
2437    pub fn open_with_system(&self, path: &Path) {
2438        self.platform.open_with_system(path)
2439    }
2440
2441    /// Returns whether the user has configured scrollbars to auto-hide at the platform level.
2442    pub fn should_auto_hide_scrollbars(&self) -> bool {
2443        self.platform.should_auto_hide_scrollbars()
2444    }
2445
2446    /// Restarts the app. Runs the handlers from [`App::on_app_restart`], then asks the
2447    /// platform to relaunch it.
2448    ///
2449    /// The relaunch uses the path from [`App::set_restart_path`] and the arguments from
2450    /// [`Application::with_restart_arguments`].
2451    pub fn restart(&mut self) {
2452        self.restart_observers
2453            .clone()
2454            .retain(&(), |observer| observer(self));
2455        self.platform.restart(
2456            self.restart_path.take(),
2457            std::mem::take(&mut self.restart_arguments),
2458        )
2459    }
2460
2461    /// Sets the executable path that [`App::restart`] launches. The path is used once, by the next restart.
2462    pub fn set_restart_path(&mut self, path: PathBuf) {
2463        self.restart_path = Some(path);
2464    }
2465
2466    /// Returns the app's HTTP client. See [`Application::with_http_client`].
2467    pub fn http_client(&self) -> Arc<dyn HttpClient> {
2468        self.http_client.clone()
2469    }
2470
2471    /// Replaces the HTTP client that [`App::http_client`] returns.
2472    pub fn set_http_client(&mut self, new_client: Arc<dyn HttpClient>) {
2473        self.http_client = new_client;
2474    }
2475
2476    /// Sets when the app quits on its own. See [`QuitMode`].
2477    ///
2478    /// Defaults to [`QuitMode::Default`].
2479    pub fn set_quit_mode(&mut self, mode: QuitMode) {
2480        self.quit_mode = mode;
2481    }
2482
2483    /// Sets whether the application participates in the system's foreground UI.
2484    ///
2485    /// Only has an effect on macOS, where [`Self::request_windowing`] normally sets it. Use this
2486    /// for an accessory app that shows windows, such as a menu bar utility. It overrides the
2487    /// policy until the next [`Self::request_windowing`], and the app counts as headless while
2488    /// `Accessory`. After switching to [`ActivationPolicy::Regular`], activate the app yourself
2489    /// with [`Self::activate`]; otherwise its menu bar may not appear until the app is
2490    /// reactivated.
2491    pub fn set_activation_policy(&mut self, policy: ActivationPolicy) {
2492        self.platform.set_activation_policy(policy);
2493    }
2494
2495    /// Returns the SVG renderer that draws the app's SVG assets.
2496    pub fn svg_renderer(&self) -> SvgRenderer {
2497        self.svg_renderer.clone()
2498    }
2499
2500    pub(crate) fn push_effect(&mut self, effect: Effect) {
2501        match &effect {
2502            Effect::Notify { emitter } => {
2503                if !self.pending_notifications.insert(*emitter) {
2504                    return;
2505                }
2506            }
2507            Effect::NotifyGlobalObservers { global_type } => {
2508                if !self.pending_global_notifications.insert(*global_type) {
2509                    return;
2510                }
2511            }
2512            _ => {}
2513        };
2514
2515        self.pending_effects.push_back(effect);
2516    }
2517
2518    /// Called at the end of [`App::update`] to complete any side effects
2519    /// such as notifying observers, emitting events, etc. Effects can themselves
2520    /// cause effects, so we continue looping until all effects are processed.
2521    fn flush_effects(&mut self) {
2522        loop {
2523            self.release_dropped_entities();
2524            self.release_dropped_focus_handles();
2525            if let Some(effect) = self.pending_effects.pop_front() {
2526                match effect {
2527                    Effect::Notify { emitter } => {
2528                        self.apply_notify_effect(emitter);
2529                    }
2530
2531                    Effect::Emit {
2532                        emitter,
2533                        event_type,
2534                        event,
2535                    } => self.apply_emit_effect(emitter, event_type, &*event),
2536
2537                    Effect::RefreshWindows => {
2538                        self.apply_refresh_effect();
2539                    }
2540
2541                    Effect::NotifyGlobalObservers { global_type } => {
2542                        self.apply_notify_global_observers_effect(global_type);
2543                    }
2544
2545                    Effect::Defer { callback } => {
2546                        self.apply_defer_effect(callback);
2547                    }
2548                    Effect::EntityCreated {
2549                        entity,
2550                        tid,
2551                        window,
2552                    } => {
2553                        self.apply_entity_created_effect(entity, tid, window);
2554                    }
2555                }
2556            } else {
2557                #[cfg(any(test, feature = "test-support"))]
2558                if matches!(self.mode, GpuiMode::Test { .. }) {
2559                    for window in self
2560                        .windows
2561                        .values()
2562                        .filter_map(|window| {
2563                            let window = window.as_deref()?;
2564                            window.invalidator.is_dirty().then_some(window.handle)
2565                        })
2566                        .collect::<Vec<_>>()
2567                    {
2568                        self.update_window(window, |_, window, cx| window.draw(cx).clear(cx))
2569                            .unwrap();
2570                    }
2571                }
2572
2573                if self.pending_effects.is_empty() {
2574                    for window in self.windows.values().filter_map(|window| window.as_deref()) {
2575                        if window.invalidator.is_dirty()
2576                            || window.needs_present.get()
2577                            || !window.next_frame_callbacks.borrow().is_empty()
2578                        {
2579                            window.platform_window.schedule_frame();
2580                        }
2581                    }
2582
2583                    self.event_arena.clear();
2584                    break;
2585                }
2586            }
2587        }
2588    }
2589
2590    /// Repeatedly called during `flush_effects` to release any entities whose
2591    /// reference count has become zero. We invoke any release observers before dropping
2592    /// each entity.
2593    fn release_dropped_entities(&mut self) {
2594        loop {
2595            let dropped = self.entities.take_dropped();
2596            if dropped.is_empty() {
2597                break;
2598            }
2599
2600            for (entity_id, mut entity) in dropped {
2601                self.observers.remove(&entity_id);
2602                self.event_listeners.remove(&entity_id);
2603                self.window_invalidators_by_entity.remove(&entity_id);
2604                self.current_window_by_entity.remove(&entity_id);
2605                for release_callback in self.release_listeners.remove(&entity_id) {
2606                    release_callback(entity.as_mut(), self);
2607                }
2608            }
2609        }
2610    }
2611
2612    /// Repeatedly called during `flush_effects` to handle a focused handle being dropped.
2613    fn release_dropped_focus_handles(&mut self) {
2614        let focus_handles = self.focus_handles.clone();
2615        let mut focus_handles = focus_handles.write();
2616        let FocusMap {
2617            handles,
2618            dropped_handles,
2619        } = &mut *focus_handles;
2620        if dropped_handles.is_empty() {
2621            return;
2622        }
2623
2624        let windows = self
2625            .windows
2626            .values()
2627            .filter_map(|window| {
2628                let window = window.as_ref()?;
2629                dropped_handles
2630                    .contains(&window.focus?)
2631                    .then_some(window.handle)
2632            })
2633            .collect::<SmallVec<[_; 1]>>();
2634        for handle_id in dropped_handles.drain(..) {
2635            handles.remove(handle_id);
2636        }
2637        drop(focus_handles);
2638
2639        for window_handle in windows {
2640            window_handle
2641                .update(self, |_, window, cx| window.blur(cx))
2642                .ok();
2643        }
2644    }
2645
2646    fn apply_notify_effect(&mut self, emitter: EntityId) {
2647        self.pending_notifications.remove(&emitter);
2648
2649        self.observers
2650            .clone()
2651            .retain(&emitter, |handler| handler(self));
2652    }
2653
2654    fn apply_emit_effect(&mut self, emitter: EntityId, event_type: TypeId, event: &dyn Any) {
2655        self.event_listeners
2656            .clone()
2657            .retain(&emitter, |(stored_type, handler)| {
2658                if *stored_type == event_type {
2659                    handler(event, self)
2660                } else {
2661                    true
2662                }
2663            });
2664    }
2665
2666    fn apply_refresh_effect(&mut self) {
2667        for window in self.windows.values_mut() {
2668            if let Some(window) = window.as_deref_mut() {
2669                window.refreshing = true;
2670                window.invalidator.set_dirty(true);
2671            }
2672        }
2673    }
2674
2675    fn apply_notify_global_observers_effect(&mut self, type_id: TypeId) {
2676        self.pending_global_notifications.remove(&type_id);
2677        self.global_observers
2678            .clone()
2679            .retain(&type_id, |observer| observer(self));
2680    }
2681
2682    fn apply_defer_effect(&mut self, callback: Box<dyn FnOnce(&mut Self) + 'static>) {
2683        callback(self);
2684    }
2685
2686    fn apply_entity_created_effect(
2687        &mut self,
2688        entity: AnyEntity,
2689        tid: TypeId,
2690        window: Option<WindowId>,
2691    ) {
2692        // Seed the entity's current window from its creation context so
2693        // `with_window` resolves correctly before the entity has ever been
2694        // rendered.
2695        if let Some(id) = window {
2696            self.current_window_by_entity.insert(entity.entity_id(), id);
2697        }
2698
2699        self.new_entity_observers.clone().retain(&tid, |observer| {
2700            if let Some(id) = window {
2701                self.update_window_id(id, {
2702                    let entity = entity.clone();
2703                    |_, window, cx| (observer)(entity, &mut Some(window), cx)
2704                })
2705                .expect("All windows should be off the stack when flushing effects");
2706            } else {
2707                (observer)(entity.clone(), &mut None, self)
2708            }
2709            true
2710        });
2711    }
2712
2713    /// Runs `f` with the window that most recently drew the entity `entity_id`.
2714    ///
2715    /// If the entity has not been drawn yet, the window it was created in is used. The
2716    /// callback receives the [`Window`] and the [`App`]. Returns `None` if the entity has
2717    /// no current window, if that window has closed, or if the window is already being
2718    /// updated higher up the call stack.
2719    #[inline(always)]
2720    pub fn with_window<R>(
2721        &mut self,
2722        entity_id: EntityId,
2723        f: impl FnOnce(&mut Window, &mut App) -> R,
2724    ) -> Option<R> {
2725        let window_id = *self.current_window_by_entity.get(&entity_id)?;
2726        self.update_window_id(window_id, |_, window, cx| f(window, cx))
2727            .ok()
2728    }
2729
2730    fn ensure_window(&mut self, entity_id: EntityId, window: WindowId) {
2731        self.current_window_by_entity
2732            .entry(entity_id)
2733            .or_insert(window);
2734    }
2735
2736    #[inline(always)]
2737    pub(crate) fn update_window_id<T, F>(&mut self, id: WindowId, update: F) -> Result<T>
2738    where
2739        F: FnOnce(AnyView, &mut Window, &mut App) -> T,
2740    {
2741        let mut update = Some(update);
2742        let mut result = None;
2743        self.update_window_erased(id, &mut |arguments| {
2744            if let Some((root_view, window, cx)) = arguments {
2745                result = Some(update.take().unwrap()(root_view, window, cx));
2746            } else {
2747                drop(update.take());
2748                drop(result.take());
2749            }
2750        });
2751        result.context("window not found")
2752    }
2753
2754    /// Returns an [`AsyncApp`] that can be held across `await` points.
2755    ///
2756    /// The [`AsyncApp`] holds the app weakly, so it does not keep the app alive. Use
2757    /// it in tasks that outlive the current update.
2758    pub fn to_async(&self) -> AsyncApp {
2759        AsyncApp {
2760            app: self.this.clone(),
2761            background_executor: self.background_executor.clone(),
2762            foreground_executor: self.foreground_executor.clone(),
2763        }
2764    }
2765
2766    /// Returns the [`BackgroundExecutor`] for `Send` futures.
2767    ///
2768    /// Native backends use worker threads; single-threaded web builds use the main thread.
2769    pub fn background_executor(&self) -> &BackgroundExecutor {
2770        &self.background_executor
2771    }
2772
2773    /// Whether this app runs on the deterministic test scheduler. See
2774    /// [`BackgroundExecutor::is_test`].
2775    pub fn is_test(&self) -> bool {
2776        self.background_executor.is_test()
2777    }
2778
2779    /// Returns the [`ForegroundExecutor`], which runs futures on the main thread.
2780    ///
2781    /// # Panics
2782    ///
2783    /// Panics if called after the quit handlers have started running (from
2784    /// [`App::on_app_quit`]).
2785    pub fn foreground_executor(&self) -> &ForegroundExecutor {
2786        if self.quitting {
2787            panic!("Can't spawn on main thread after on_app_quit")
2788        };
2789        &self.foreground_executor
2790    }
2791
2792    /// Returns the foreground work journal for this app's foreground thread.
2793    /// Apps constructed on the same thread share the stream.
2794    #[cfg(feature = "profiler")]
2795    pub fn foreground_journal(&self) -> crate::profiler::journal::ForegroundJournal {
2796        self.foreground_journal.clone()
2797    }
2798
2799    /// Starts detecting foreground hangs on a dedicated thread.
2800    ///
2801    /// Nothing is spawned unless the app calls this. The thread polls a
2802    /// detector over this app's foreground journal every `config.interval`
2803    /// and passes each poll's incidents, including empty polls, to `on_poll`
2804    /// on that thread. When the app quits, a final poll with
2805    /// [`HangMonitorPollReason::Flush`] runs during shutdown, concurrently
2806    /// with quit handlers and within [`SHUTDOWN_TIMEOUT`], so `on_poll` can
2807    /// deliver batched results.
2808    ///
2809    /// # Errors
2810    ///
2811    /// Fails if the monitor was already started or its thread can't be
2812    /// spawned.
2813    ///
2814    /// [`HangMonitorPollReason::Flush`]: crate::profiler::hang::HangMonitorPollReason::Flush
2815    #[cfg(all(feature = "profiler", not(target_family = "wasm")))]
2816    pub fn start_hang_monitor(
2817        &mut self,
2818        config: crate::profiler::hang::HangMonitorConfig,
2819        on_poll: impl FnMut(crate::profiler::hang::HangMonitorPoll) + Send + 'static,
2820    ) -> Result<(), crate::profiler::hang::HangMonitorError> {
2821        use crate::profiler::hang::{HangDetector, HangMonitor, HangMonitorError};
2822
2823        if self.hang_monitor.is_some() {
2824            debug_assert!(false, "the hang monitor was started twice");
2825            return Err(HangMonitorError::AlreadyStarted);
2826        }
2827        let detector = HangDetector::new(
2828            self.foreground_journal(),
2829            config.threshold,
2830            config.frame_budget,
2831        );
2832        let monitor = HangMonitor::spawn(detector, config.interval, on_poll)
2833            .map_err(HangMonitorError::Spawn)?;
2834        self.hang_monitor = Some(monitor);
2835        Ok(())
2836    }
2837
2838    /// Runs an async block on the main thread, with an [`AsyncApp`] for access to app state.
2839    ///
2840    /// The closure receives `&mut AsyncApp`. Use it to update entities and windows after
2841    /// an `await`. The future doesn't need to be `Send`, because it stays on the main
2842    /// thread. Dropping the returned [`Task`] cancels it, so store it or call
2843    /// [`Task::detach`] to let it run to completion in the background.
2844    ///
2845    /// Use [`App::background_executor`] for CPU-heavy or blocking work, and send the
2846    /// result back to the main thread with a `spawn` task.
2847    ///
2848    /// # Panics
2849    ///
2850    /// In debug builds this panics if called after the quit handlers have started
2851    /// running. Release builds log a debug message and continue.
2852    ///
2853    /// # Examples
2854    ///
2855    /// ```
2856    /// # use gpui::{AppContext, TestApp};
2857    /// # use std::{cell::Cell, rc::Rc};
2858    /// # let mut app = TestApp::new();
2859    /// let ran = Rc::new(Cell::new(false));
2860    /// app.update(|cx| {
2861    ///     let ran = ran.clone();
2862    ///     cx.spawn(async move |_cx| ran.set(true)).detach();
2863    /// });
2864    /// app.read(|_| assert!(ran.get()));
2865    /// ```
2866    ///
2867    /// See [async work](crate::_documentation::guides::async_work) for the executors and
2868    /// how to share state across tasks.
2869    #[track_caller]
2870    #[inline(always)]
2871    pub fn spawn<AsyncFn, R>(&self, f: AsyncFn) -> Task<R>
2872    where
2873        AsyncFn: AsyncFnOnce(&mut AsyncApp) -> R + 'static,
2874        R: 'static,
2875    {
2876        let mut cx = self.prepare_spawn();
2877
2878        self.foreground_executor
2879            .spawn(async move { f(&mut cx).await }.boxed_local())
2880    }
2881
2882    /// Like [`App::spawn`], but schedules the task with the given [`Priority`].
2883    pub fn spawn_with_priority<AsyncFn, R>(&self, priority: Priority, f: AsyncFn) -> Task<R>
2884    where
2885        AsyncFn: AsyncFnOnce(&mut AsyncApp) -> R + 'static,
2886        R: 'static,
2887    {
2888        if self.quitting {
2889            debug_panic!("Can't spawn on main thread after on_app_quit")
2890        };
2891
2892        let mut cx = self.to_async();
2893
2894        self.foreground_executor
2895            .spawn_with_priority(priority, async move { f(&mut cx).await }.boxed_local())
2896    }
2897
2898    /// Runs `f` after the current effect cycle finishes, with the [`App`].
2899    ///
2900    /// Use it to act on state that is borrowed right now. For example, you can change
2901    /// an entity from inside its own `update`, which would otherwise be a double borrow.
2902    /// The callback runs once the outermost update returns.
2903    ///
2904    /// ```
2905    /// # use gpui::{AppContext, TestApp};
2906    /// let mut app = TestApp::new();
2907    /// let count = app.update(|cx| cx.new(|_| 0));
2908    /// app.update(|cx| {
2909    ///     let count = count.clone();
2910    ///     cx.defer(move |cx| {
2911    ///         count.update(cx, |count, _| *count += 1);
2912    ///     });
2913    /// });
2914    /// app.read(|cx| assert_eq!(*count.read(cx), 1));
2915    /// ```
2916    pub fn defer(&mut self, f: impl FnOnce(&mut App) + 'static) {
2917        self.push_effect(Effect::Defer {
2918            callback: Box::new(f),
2919        });
2920    }
2921
2922    /// Returns the asset registry that the app loads assets from. See [`Application::with_assets`].
2923    pub fn assets(&self) -> &Arc<AssetRegistry> {
2924        &self.asset_registry
2925    }
2926
2927    /// Returns the app's [`TextSystem`], which shapes and rasterizes text.
2928    pub fn text_system(&self) -> &Arc<TextSystem> {
2929        &self.text_system
2930    }
2931
2932    /// Returns whether a global of type `G` has been set.
2933    pub fn has_global<G: Global>(&self) -> bool {
2934        self.note_global_read(TypeId::of::<G>());
2935        self.globals_by_type.contains_key(&TypeId::of::<G>())
2936    }
2937
2938    /// Returns the global of type `G`.
2939    ///
2940    /// # Panics
2941    ///
2942    /// Panics if no global of type `G` has been set. Use [`App::try_global`] when the
2943    /// global may be missing.
2944    #[track_caller]
2945    pub fn global<G: Global>(&self) -> &G {
2946        self.note_global_read(TypeId::of::<G>());
2947        self.globals_by_type
2948            .get(&TypeId::of::<G>())
2949            .map(|any_state| any_state.downcast_ref::<G>().unwrap())
2950            .unwrap_or_else(|| panic!("no state of type {} exists", type_name::<G>()))
2951    }
2952
2953    /// Returns the global of type `G`, or `None` if it has not been set.
2954    pub fn try_global<G: Global>(&self) -> Option<&G> {
2955        self.note_global_read(TypeId::of::<G>());
2956        self.globals_by_type
2957            .get(&TypeId::of::<G>())
2958            .map(|any_state| any_state.downcast_ref::<G>().unwrap())
2959    }
2960
2961    /// Returns the global of type `G` for mutation, and notifies global observers.
2962    ///
2963    /// Observers registered with [`App::observe_global`] run when the current update
2964    /// finishes. The notification happens on every call, even if you don't change the
2965    /// value.
2966    ///
2967    /// # Panics
2968    ///
2969    /// Panics if no global of type `G` has been set. Use [`App::default_global`] to
2970    /// create one on first use.
2971    #[track_caller]
2972    pub fn global_mut<G: Global>(&mut self) -> &mut G {
2973        let global_type = TypeId::of::<G>();
2974        self.global_changed(global_type);
2975        self.globals_by_type
2976            .get_mut(&global_type)
2977            .and_then(|any_state| any_state.downcast_mut::<G>())
2978            .unwrap_or_else(|| panic!("no state of type {} exists", type_name::<G>()))
2979    }
2980
2981    /// Returns the global of type `G` for mutation, first setting `G::default()` if it is missing.
2982    ///
2983    /// Like [`App::global_mut`], this notifies global observers.
2984    pub fn default_global<G: Global + Default>(&mut self) -> &mut G {
2985        let global_type = TypeId::of::<G>();
2986        self.global_changed(global_type);
2987        self.globals_by_type
2988            .entry(global_type)
2989            .or_insert_with(|| Box::<G>::default())
2990            .downcast_mut::<G>()
2991            .unwrap()
2992    }
2993
2994    /// Sets the global of type `G` to `global`, replacing any previous value.
2995    ///
2996    /// Notifies global observers when the current update finishes.
2997    ///
2998    /// # Examples
2999    ///
3000    /// ```
3001    /// # use gpui::{AppContext, Global, TestApp};
3002    /// struct Theme {
3003    ///     name: &'static str,
3004    /// }
3005    /// impl Global for Theme {}
3006    ///
3007    /// # let mut app = TestApp::new();
3008    /// app.update(|cx| cx.set_global(Theme { name: "dark" }));
3009    /// app.read(|cx| assert_eq!(cx.global::<Theme>().name, "dark"));
3010    /// ```
3011    pub fn set_global<G: Global>(&mut self, global: G) {
3012        let global_type = TypeId::of::<G>();
3013        self.global_changed(global_type);
3014        self.globals_by_type.insert(global_type, Box::new(global));
3015    }
3016
3017    /// Clear all stored globals. Does not notify global observers.
3018    #[cfg(any(test, feature = "test-support"))]
3019    pub fn clear_globals(&mut self) {
3020        self.globals_by_type.drain();
3021    }
3022
3023    /// Removes the global of type `G` and returns it.
3024    ///
3025    /// Notifies global observers when the current update finishes.
3026    ///
3027    /// # Panics
3028    ///
3029    /// Panics if no global of type `G` has been set.
3030    pub fn remove_global<G: Global>(&mut self) -> G {
3031        let global_type = TypeId::of::<G>();
3032        self.global_changed(global_type);
3033        *self
3034            .globals_by_type
3035            .remove(&global_type)
3036            .unwrap_or_else(|| panic!("no global added for {}", type_name::<G>()))
3037            .downcast()
3038            .unwrap()
3039    }
3040
3041    /// Calls `f` each time the global of type `G` is set, changed or removed.
3042    ///
3043    /// The observer is active once the current update finishes. Keep the returned
3044    /// [`Subscription`] alive, because dropping it stops the observer.
3045    ///
3046    /// # Examples
3047    ///
3048    /// ```
3049    /// # use gpui::{AppContext, Global, TestApp};
3050    /// # use std::{cell::Cell, rc::Rc};
3051    /// struct Count(usize);
3052    /// impl Global for Count {}
3053    ///
3054    /// # let mut app = TestApp::new();
3055    /// let calls = Rc::new(Cell::new(0));
3056    /// let _subscription = app.update(|cx| {
3057    ///     cx.set_global(Count(0));
3058    ///     cx.observe_global::<Count>({
3059    ///         let calls = calls.clone();
3060    ///         move |_| calls.set(calls.get() + 1)
3061    ///     })
3062    /// });
3063    /// app.update(|cx| cx.global_mut::<Count>().0 += 1);
3064    /// assert_eq!(calls.get(), 1);
3065    /// ```
3066    pub fn observe_global<G: Global>(
3067        &mut self,
3068        mut f: impl FnMut(&mut Self) + 'static,
3069    ) -> Subscription {
3070        let (subscription, activate) = self.global_observers.insert(
3071            TypeId::of::<G>(),
3072            Box::new(move |cx| {
3073                f(cx);
3074                true
3075            }),
3076        );
3077        self.defer(move |_| activate());
3078        subscription
3079    }
3080
3081    /// Move the global of the given type to the stack.
3082    #[track_caller]
3083    pub(crate) fn lease_global<G: Global>(&mut self) -> GlobalLease<G> {
3084        GlobalLease::new(
3085            self.globals_by_type
3086                .remove(&TypeId::of::<G>())
3087                .with_context(|| format!("no global registered of type {}", type_name::<G>()))
3088                .unwrap(),
3089        )
3090    }
3091
3092    /// Restore the global of the given type after it is moved to the stack.
3093    pub(crate) fn end_global_lease<G: Global>(&mut self, lease: GlobalLease<G>) {
3094        let global_type = TypeId::of::<G>();
3095
3096        self.global_changed(global_type);
3097        self.globals_by_type.insert(global_type, lease.global);
3098    }
3099
3100    pub(crate) fn new_entity_observer(
3101        &self,
3102        key: TypeId,
3103        value: NewEntityListener,
3104    ) -> Subscription {
3105        let (subscription, activate) = self.new_entity_observers.insert(key, value);
3106        activate();
3107        subscription
3108    }
3109
3110    /// Calls `on_new` each time an entity of type `T` is created.
3111    ///
3112    /// The callback receives the new state, the [`Window`] if the entity was created with
3113    /// one, and a [`Context`] for it. Use it to set up behavior for every instance of a
3114    /// type, such as registering an observer. Keep the returned [`Subscription`] alive
3115    /// for the callback to keep running.
3116    pub fn observe_new<T: 'static>(
3117        &self,
3118        on_new: impl 'static + Fn(&mut T, Option<&mut Window>, &mut Context<T>),
3119    ) -> Subscription {
3120        self.new_entity_observer(
3121            TypeId::of::<T>(),
3122            Box::new(
3123                move |any_entity: AnyEntity, window: &mut Option<&mut Window>, cx: &mut App| {
3124                    any_entity
3125                        .downcast::<T>()
3126                        .unwrap()
3127                        .update(cx, |entity_state, cx| {
3128                            on_new(entity_state, window.as_deref_mut(), cx)
3129                        })
3130                },
3131            ),
3132        )
3133    }
3134
3135    /// Calls `on_release` when the entity behind `handle` is released.
3136    ///
3137    /// The callback runs after the entity's last strong handle is dropped, and before the
3138    /// entity's state is dropped. It receives the state as `&mut T`. Keep the returned
3139    /// [`Subscription`] alive for the callback to run.
3140    pub fn observe_release<T>(
3141        &self,
3142        handle: &Entity<T>,
3143        on_release: impl FnOnce(&mut T, &mut App) + 'static,
3144    ) -> Subscription
3145    where
3146        T: 'static,
3147    {
3148        let (subscription, activate) = self.release_listeners.insert(
3149            handle.entity_id(),
3150            Box::new(move |entity, cx| {
3151                let entity = entity.downcast_mut().expect("invalid entity type");
3152                on_release(entity, cx)
3153            }),
3154        );
3155        activate();
3156        subscription
3157    }
3158
3159    /// Calls `on_release` when the entity behind `handle` is released, inside `window`.
3160    ///
3161    /// Like [`App::observe_release`], but the callback also receives `window`. The
3162    /// callback doesn't run if `window` has already closed when the entity is released.
3163    pub fn observe_release_in<T>(
3164        &self,
3165        handle: &Entity<T>,
3166        window: &Window,
3167        on_release: impl FnOnce(&mut T, &mut Window, &mut App) + 'static,
3168    ) -> Subscription
3169    where
3170        T: 'static,
3171    {
3172        let window_handle = window.handle;
3173        self.observe_release(handle, move |entity, cx| {
3174            let _ = window_handle.update(cx, |_, window, cx| on_release(entity, window, cx));
3175        })
3176    }
3177
3178    /// Calls `f` for every keystroke that reaches any window of the app.
3179    ///
3180    /// The callback runs after action and event handling has finished, and the event
3181    /// names the action that handled the keystroke, if any. Keystrokes consumed by an
3182    /// interceptor or a raw keyboard event handler are not observed, and a modifier
3183    /// pressed on its own is observed when it is released. Use
3184    /// [`App::intercept_keystrokes`] to see keystrokes before they are dispatched. Keep
3185    /// the returned [`Subscription`] alive.
3186    pub fn observe_keystrokes(
3187        &mut self,
3188        mut f: impl FnMut(&KeystrokeEvent, &mut Window, &mut App) + 'static,
3189    ) -> Subscription {
3190        fn inner(
3191            keystroke_observers: &SubscriberSet<(), KeystrokeObserver>,
3192            handler: KeystrokeObserver,
3193        ) -> Subscription {
3194            let (subscription, activate) = keystroke_observers.insert((), handler);
3195            activate();
3196            subscription
3197        }
3198
3199        inner(
3200            &self.keystroke_observers,
3201            Box::new(move |event, window, cx| {
3202                f(event, window, cx);
3203                true
3204            }),
3205        )
3206    }
3207
3208    /// Calls `f` for every key-down that reaches any window, before it is dispatched.
3209    ///
3210    /// Unlike [`App::observe_keystrokes`], which runs after handling, the interceptor runs
3211    /// first. Calling [`App::stop_propagation`] inside it stops the keystroke from reaching
3212    /// action dispatch. Keep the returned [`Subscription`] alive.
3213    pub fn intercept_keystrokes(
3214        &mut self,
3215        mut f: impl FnMut(&KeystrokeEvent, &mut Window, &mut App) + 'static,
3216    ) -> Subscription {
3217        fn inner(
3218            keystroke_interceptors: &SubscriberSet<(), KeystrokeObserver>,
3219            handler: KeystrokeObserver,
3220        ) -> Subscription {
3221            let (subscription, activate) = keystroke_interceptors.insert((), handler);
3222            activate();
3223            subscription
3224        }
3225
3226        inner(
3227            &self.keystroke_interceptors,
3228            Box::new(move |event, window, cx| {
3229                f(event, window, cx);
3230                true
3231            }),
3232        )
3233    }
3234
3235    /// Adds key bindings to the app's keymap and redraws the windows.
3236    ///
3237    /// A binding maps a keystroke, optionally limited to a [`KeyContext`], to an action.
3238    /// Bindings are matched during key dispatch. Calling this again adds to the existing
3239    /// bindings, and [`App::clear_key_bindings`] removes them all.
3240    ///
3241    /// # Examples
3242    ///
3243    /// ```standalone_crate
3244    /// use gpui::{AppContext, KeyBinding, Keystroke, TestApp, actions};
3245    ///
3246    /// actions!(app_bind_keys, [Save]);
3247    ///
3248    /// let mut app = TestApp::new();
3249    /// app.update(|cx| cx.bind_keys([KeyBinding::new("ctrl-s", Save, None)]));
3250    /// app.read(|cx| {
3251    ///     let bindings = cx.all_bindings_for_input(&[Keystroke::parse("ctrl-s").unwrap()]);
3252    ///     assert_eq!(bindings.len(), 1);
3253    ///     assert_eq!(bindings[0].action().name(), "app_bind_keys::Save");
3254    /// });
3255    /// ```
3256    ///
3257    /// See [keyboard](crate::_documentation::guides::keyboard) for context rules and
3258    /// [input dispatch](crate::_documentation::concepts::input_dispatch) for how a keystroke
3259    /// picks an action.
3260    pub fn bind_keys(&mut self, bindings: impl IntoIterator<Item = KeyBinding>) {
3261        self.keymap.borrow_mut().add_bindings(bindings);
3262        self.pending_effects.push_back(Effect::RefreshWindows);
3263    }
3264
3265    /// Removes every key binding from the app's keymap.
3266    pub fn clear_key_bindings(&mut self) {
3267        self.keymap.borrow_mut().clear();
3268        self.pending_effects.push_back(Effect::RefreshWindows);
3269    }
3270
3271    /// Returns the app's keymap, shared with the app.
3272    ///
3273    /// Borrow it to inspect bindings. Don't hold the borrow across a call that changes
3274    /// bindings, such as [`App::bind_keys`], because the borrow panics.
3275    pub fn key_bindings(&self) -> Rc<RefCell<Keymap>> {
3276        self.keymap.clone()
3277    }
3278
3279    /// Registers a handler that runs when an action is dispatched. Global handlers run in
3280    /// the bubble phase, after the handlers in the element tree, and only if no earlier
3281    /// handler stopped the propagation. Use it for app-wide
3282    /// commands such as Quit, which should work with no window focused. Dispatch an action
3283    /// with [`App::dispatch_action`].
3284    ///
3285    /// # Examples
3286    ///
3287    /// ```standalone_crate
3288    /// use gpui::{AppContext, TestApp, actions};
3289    /// use std::{cell::Cell, rc::Rc};
3290    ///
3291    /// actions!(app_on_action, [Ping]);
3292    ///
3293    /// let mut app = TestApp::new();
3294    /// let pings = Rc::new(Cell::new(0));
3295    /// app.update(|cx| {
3296    ///     let pings = pings.clone();
3297    ///     cx.on_action(move |_: &Ping, _| pings.set(pings.get() + 1));
3298    /// });
3299    /// app.update(|cx| cx.dispatch_action(&Ping));
3300    /// assert_eq!(pings.get(), 1);
3301    /// ```
3302    pub fn on_action<A: Action>(
3303        &mut self,
3304        listener: impl Fn(&A, &mut Self) + 'static,
3305    ) -> &mut Self {
3306        self.global_action_listeners
3307            .entry(TypeId::of::<A>())
3308            .or_default()
3309            .push(Rc::new(move |action, phase, cx| {
3310                if phase == DispatchPhase::Bubble {
3311                    let action = action.downcast_ref().unwrap();
3312                    listener(action, cx)
3313                }
3314            }));
3315        self
3316    }
3317
3318    /// Stops the current event or action from reaching later handlers.
3319    ///
3320    /// Handlers for mouse events further down the z-order, and keyboard handlers higher
3321    /// in the tree, don't run after this. Call [`App::propagate`] to undo it before the
3322    /// effects are flushed.
3323    pub fn stop_propagation(&mut self) {
3324        self.propagate_event = false;
3325    }
3326
3327    /// Lets the current event or action continue to later handlers.
3328    ///
3329    /// Use it in a handler to pass the event on to the next handler, for example an
3330    /// action listener on a parent element or a global handler from [`App::on_action`].
3331    /// It cancels an earlier [`App::stop_propagation`] in the same dispatch.
3332    pub fn propagate(&mut self) {
3333        self.propagate_event = true;
3334    }
3335
3336    /// Builds an action by its registered name, from JSON data such as a keymap entry.
3337    ///
3338    /// `data` is the action's parameters, or `None` for an action with no parameters.
3339    /// Returns an [`ActionBuildError`] if the name is unknown or the data doesn't match
3340    /// the action's type. Use it to load actions from a keymap file.
3341    pub fn build_action(
3342        &self,
3343        name: &str,
3344        data: Option<serde_json::Value>,
3345    ) -> std::result::Result<Box<dyn Action>, ActionBuildError> {
3346        self.actions.build_action(name, data)
3347    }
3348
3349    /// Returns the names of every action type that has been registered.
3350    ///
3351    /// Registration makes an action buildable by name with [`App::build_action`]. It
3352    /// does not bind the action to a key or a handler. For that, use [`App::bind_keys`]
3353    /// and [`App::on_action`].
3354    pub fn all_action_names(&self) -> &[&'static str] {
3355        self.actions.all_action_names()
3356    }
3357
3358    /// Returns the bindings that match `input`, ignoring key context.
3359    ///
3360    /// The bindings come back in the order they were added. When you show one to the user,
3361    /// use the last one, because it takes precedence.
3362    pub fn all_bindings_for_input(&self, input: &[Keystroke]) -> Vec<KeyBinding> {
3363        RefCell::borrow(&self.keymap).all_bindings_for_input(input)
3364    }
3365
3366    /// Returns each registered action name with its JSON schema, if it has one.
3367    ///
3368    /// Use it to generate editor completions or to validate keymap files.
3369    pub fn action_schemas(
3370        &self,
3371        generator: &mut schemars::SchemaGenerator,
3372    ) -> Vec<(&'static str, Option<schemars::Schema>)> {
3373        self.actions.action_schemas(generator)
3374    }
3375
3376    /// Returns the JSON schema for the action named `name`.
3377    ///
3378    /// Returns `None` if no action has that name. Returns `Some(None)` if the action
3379    /// exists but has no schema, and `Some(Some(schema))` if it has one.
3380    pub fn action_schema_by_name(
3381        &self,
3382        name: &str,
3383        generator: &mut schemars::SchemaGenerator,
3384    ) -> Option<Option<schemars::Schema>> {
3385        self.actions.action_schema_by_name(name, generator)
3386    }
3387
3388    /// Returns a map from each deprecated action name to the name that replaces it.
3389    pub fn deprecated_actions_to_preferred_actions(&self) -> &HashMap<&'static str, &'static str> {
3390        self.actions.deprecated_aliases()
3391    }
3392
3393    /// Returns a map from each deprecated action name to its deprecation message.
3394    pub fn action_deprecation_messages(&self) -> &HashMap<&'static str, &'static str> {
3395        self.actions.deprecation_messages()
3396    }
3397
3398    /// Returns a map from each action name to its documentation string.
3399    pub fn action_documentation(&self) -> &HashMap<&'static str, &'static str> {
3400        self.actions.documentation()
3401    }
3402
3403    /// Calls `on_quit` when the app is about to quit, and waits for the returned future.
3404    ///
3405    /// Use it to flush data to disk or close connections. The quit can't be cancelled
3406    /// at this point. Native apps wait up to [`SHUTDOWN_TIMEOUT`] for the futures, so
3407    /// keep the work short. Keep the returned [`Subscription`] alive for the callback to
3408    /// run.
3409    pub fn on_app_quit<Fut>(
3410        &self,
3411        mut on_quit: impl FnMut(&mut App) -> Fut + 'static,
3412    ) -> Subscription
3413    where
3414        Fut: 'static + Future<Output = ()>,
3415    {
3416        let (subscription, activate) = self.quit_observers.insert(
3417            (),
3418            Box::new(move |cx| {
3419                let future = on_quit(cx);
3420                future.boxed_local()
3421            }),
3422        );
3423        activate();
3424        subscription
3425    }
3426
3427    /// Calls `on_restart` when the app is about to restart, before any [`App::on_app_quit`] handlers run.
3428    ///
3429    /// Keep the returned [`Subscription`] alive for the callback to run.
3430    pub fn on_app_restart(&self, mut on_restart: impl 'static + FnMut(&mut App)) -> Subscription {
3431        let (subscription, activate) = self.restart_observers.insert(
3432            (),
3433            Box::new(move |cx| {
3434                on_restart(cx);
3435                true
3436            }),
3437        );
3438        activate();
3439        subscription
3440    }
3441
3442    /// Calls `on_closed` with the [`WindowId`] each time a window closes.
3443    ///
3444    /// The window is no longer accessible when the callback runs. Keep the returned
3445    /// [`Subscription`] alive for the callback to run.
3446    pub fn on_window_closed(
3447        &self,
3448        mut on_closed: impl FnMut(&mut App, WindowId) + 'static,
3449    ) -> Subscription {
3450        let (subscription, activate) = self.window_closed_observers.insert((), Box::new(on_closed));
3451        activate();
3452        subscription
3453    }
3454
3455    pub(crate) fn clear_pending_keystrokes(&mut self) {
3456        for window in self.windows() {
3457            window
3458                .update(self, |_, window, cx| {
3459                    window.clear_pending_keystrokes(cx);
3460                })
3461                .ok();
3462        }
3463    }
3464
3465    /// Returns whether `action` would be handled if it were dispatched now.
3466    ///
3467    /// Checks the active window's focus path and its bindings, then the global listeners
3468    /// from [`App::on_action`]. Use it to enable or disable menu items.
3469    pub fn is_action_available(&mut self, action: &dyn Action) -> bool {
3470        let mut action_available = false;
3471        if let Some(window) = self.active_window()
3472            && let Ok(window_action_available) =
3473                window.update(self, |_, window, cx| window.is_action_available(action, cx))
3474        {
3475            action_available = window_action_available;
3476        }
3477
3478        action_available
3479            || self
3480                .global_action_listeners
3481                .contains_key(&action.as_any().type_id())
3482    }
3483
3484    /// Replaces the app's menu bar with `menus`.
3485    ///
3486    /// Menu items that name an action show the key bindings from the keymap.
3487    pub fn set_menus(&self, menus: impl IntoIterator<Item = Menu>) {
3488        let menus: Vec<Menu> = menus.into_iter().collect();
3489        self.platform.set_menus(menus, &self.keymap.borrow());
3490    }
3491
3492    /// Returns the menu bar most recently set with [`App::set_menus`], or `None` if none was set.
3493    pub fn get_menus(&self) -> Option<Vec<OwnedMenu>> {
3494        self.platform.get_menus()
3495    }
3496
3497    /// Sets the menu that appears when the user right-clicks the app's Dock icon.
3498    pub fn set_dock_menu(&self, menus: Vec<MenuItem>) {
3499        self.platform.set_dock_menu(menus, &self.keymap.borrow())
3500    }
3501
3502    /// Runs the dock menu item at index `action`, as set with [`App::set_dock_menu`].
3503    ///
3504    /// Only Windows uses this path.
3505    pub fn perform_dock_menu_action(&self, action: usize) {
3506        self.platform.perform_dock_menu_action(action);
3507    }
3508
3509    /// On macOS, adds `path` to the recent documents list, which the Dock menu shows.
3510    /// Other platforms do nothing.
3511    ///
3512    /// Call this when the user opens a document, so it appears in the recent list next time.
3513    pub fn add_recent_document(&self, path: &Path) {
3514        self.platform.add_recent_document(path);
3515    }
3516
3517    /// Replaces the Windows jump list with `menus` and the recent `entries`.
3518    ///
3519    /// Only Windows uses this. It also sets the dock menu.
3520    pub fn update_jump_list(
3521        &self,
3522        menus: Vec<MenuItem>,
3523        entries: Vec<SmallVec<[PathBuf; 2]>>,
3524    ) -> Task<Vec<SmallVec<[PathBuf; 2]>>> {
3525        self.platform.update_jump_list(menus, entries)
3526    }
3527
3528    /// Dispatches `action` to the active window, or to the global listeners if no window is active.
3529    ///
3530    /// In a window, the action follows the focus path, as a keystroke bound to it would.
3531    /// Without an active window, it goes to the listeners from [`App::on_action`]. See
3532    /// [`crate::Action`] for how actions work.
3533    pub fn dispatch_action(&mut self, action: &dyn Action) {
3534        if let Some(active_window) = self.active_window() {
3535            active_window
3536                .update(self, |_, window, cx| {
3537                    window.dispatch_action(action.boxed_clone(), cx)
3538                })
3539                .log_err();
3540        } else {
3541            self.dispatch_global_action(action);
3542        }
3543    }
3544
3545    fn dispatch_global_action(&mut self, action: &dyn Action) {
3546        self.propagate_event = true;
3547
3548        if let Some(mut global_listeners) = self
3549            .global_action_listeners
3550            .remove(&action.as_any().type_id())
3551        {
3552            for listener in &global_listeners {
3553                listener(action.as_any(), DispatchPhase::Capture, self);
3554                if !self.propagate_event {
3555                    break;
3556                }
3557            }
3558
3559            global_listeners.extend(
3560                self.global_action_listeners
3561                    .remove(&action.as_any().type_id())
3562                    .unwrap_or_default(),
3563            );
3564
3565            self.global_action_listeners
3566                .insert(action.as_any().type_id(), global_listeners);
3567        }
3568
3569        if self.propagate_event
3570            && let Some(mut global_listeners) = self
3571                .global_action_listeners
3572                .remove(&action.as_any().type_id())
3573        {
3574            for listener in global_listeners.iter().rev() {
3575                listener(action.as_any(), DispatchPhase::Bubble, self);
3576                if !self.propagate_event {
3577                    break;
3578                }
3579            }
3580
3581            global_listeners.extend(
3582                self.global_action_listeners
3583                    .remove(&action.as_any().type_id())
3584                    .unwrap_or_default(),
3585            );
3586
3587            self.global_action_listeners
3588                .insert(action.as_any().type_id(), global_listeners);
3589        }
3590    }
3591
3592    /// Returns whether a drag is in progress.
3593    pub fn has_active_drag(&self) -> bool {
3594        self.active_drag.is_some()
3595    }
3596
3597    /// Returns the payload of the drag in progress, if any.
3598    pub fn active_drag(&self) -> Option<&AnyDrag> {
3599        self.active_drag.as_ref()
3600    }
3601
3602    /// Returns the cursor style of the drag in progress, if it set one.
3603    pub fn active_drag_cursor_style(&self) -> Option<CursorStyle> {
3604        self.active_drag.as_ref().and_then(|drag| drag.cursor_style)
3605    }
3606
3607    /// Starts a drag with `drag` as its payload. Refresh the windows after calling this, so the drag shows.
3608    ///
3609    /// # Panics
3610    ///
3611    /// Debug builds panic if a drag is already in progress.
3612    pub fn start_drag(&mut self, drag: AnyDrag) {
3613        debug_assert!(self.active_drag.is_none());
3614        self.active_drag = Some(drag);
3615    }
3616
3617    /// Ends the drag in progress and returns its payload, if there was one.
3618    ///
3619    /// Refresh the windows after calling this.
3620    pub fn stop_drag(&mut self, window: &Window) -> Option<Arc<dyn Any>> {
3621        let drag = self.active_drag.take();
3622        if drag.is_some()
3623            && let Some(platform_drag) = self.platform_owned_drag.as_ref()
3624        {
3625            if platform_drag.source_window == window.window_handle().window_id()
3626                && matches!(
3627                    &platform_drag.state,
3628                    PlatformOwnedDragState::RestoredInSourceWindow
3629                )
3630            {
3631                self.platform_owned_drag = None;
3632            }
3633        }
3634        Some(drag?.value)
3635    }
3636
3637    /// Stops active drag and clears any related effects.
3638    pub fn stop_active_drag(&mut self, window: &mut Window) -> bool {
3639        if self.stop_drag(window).is_some() {
3640            window.refresh();
3641            true
3642        } else {
3643            false
3644        }
3645    }
3646
3647    pub(crate) fn hand_active_drag_to_platform(&mut self, source_window: WindowId) -> bool {
3648        let Some(drag) = self.active_drag.take() else {
3649            return false;
3650        };
3651        self.platform_owned_drag = Some(PlatformOwnedDrag {
3652            source_window,
3653            state: PlatformOwnedDragState::Suspended(drag),
3654        });
3655        true
3656    }
3657
3658    pub(crate) fn restore_platform_drag(&mut self, source_window: WindowId) -> bool {
3659        let Some(platform_drag) = self
3660            .platform_owned_drag
3661            .as_mut()
3662            .filter(|drag| drag.source_window == source_window)
3663        else {
3664            return false;
3665        };
3666        let state = std::mem::replace(
3667            &mut platform_drag.state,
3668            PlatformOwnedDragState::RestoredInSourceWindow,
3669        );
3670        let PlatformOwnedDragState::Suspended(drag) = state else {
3671            return false;
3672        };
3673        self.active_drag = Some(drag);
3674        true
3675    }
3676
3677    pub(crate) fn hand_restored_drag_to_platform(&mut self, source_window: WindowId) -> bool {
3678        let Some(platform_drag) = self.platform_owned_drag.as_mut().filter(|drag| {
3679            drag.source_window == source_window
3680                && matches!(&drag.state, PlatformOwnedDragState::RestoredInSourceWindow)
3681        }) else {
3682            return false;
3683        };
3684        let Some(drag) = self.active_drag.take() else {
3685            return false;
3686        };
3687        platform_drag.state = PlatformOwnedDragState::Suspended(drag);
3688        true
3689    }
3690
3691    pub(crate) fn end_platform_drag(&mut self, source_window: WindowId) -> bool {
3692        if !self
3693            .platform_owned_drag
3694            .as_ref()
3695            .is_some_and(|drag| drag.source_window == source_window)
3696        {
3697            return false;
3698        }
3699        self.platform_owned_drag = None;
3700        self.active_drag = None;
3701        true
3702    }
3703
3704    /// Sets the cursor shown during the active drag. Returns `false` if no drag is in progress.
3705    pub fn set_active_drag_cursor_style(
3706        &mut self,
3707        cursor_style: CursorStyle,
3708        window: &mut Window,
3709    ) -> bool {
3710        if let Some(ref mut drag) = self.active_drag {
3711            drag.cursor_style = Some(cursor_style);
3712            window.refresh();
3713            true
3714        } else {
3715            false
3716        }
3717    }
3718
3719    /// Replaces the default and platform prompts with `renderer`.
3720    ///
3721    /// The renderer is called for each prompt the app shows. It receives the prompt's
3722    /// level, message, detail and buttons, and returns the handle that the window renders.
3723    /// Use [`App::reset_prompt_builder`] to go back to the default prompts.
3724    pub fn set_prompt_builder(
3725        &mut self,
3726        renderer: impl Fn(
3727            PromptLevel,
3728            &str,
3729            Option<&str>,
3730            &[PromptButton],
3731            PromptHandle,
3732            &mut Window,
3733            &mut App,
3734        ) -> RenderablePromptHandle
3735        + 'static,
3736    ) {
3737        self.prompt_builder = Some(PromptBuilder::Custom(Box::new(renderer)));
3738    }
3739
3740    /// Reset the prompt builder to the default implementation.
3741    pub fn reset_prompt_builder(&mut self) {
3742        self.prompt_builder = Some(PromptBuilder::Default);
3743    }
3744
3745    /// Removes the cached result for `source`, so the next [`App::fetch_asset`] loads it again.
3746    pub fn remove_asset<A: Asset>(&mut self, source: &A::Source) {
3747        let asset_id = (TypeId::of::<A>(), hash(source));
3748        self.loading_assets.remove(&asset_id);
3749    }
3750
3751    /// Returns whether `source` is cached for asset type `A`, either loading or loaded.
3752    ///
3753    /// This doesn't start a load. Only available in tests and with the `test-support` feature.
3754    #[cfg(any(test, feature = "test-support"))]
3755    pub fn has_asset<A: Asset>(&self, source: &A::Source) -> bool {
3756        let asset_id = (TypeId::of::<A>(), hash(source));
3757        self.loading_assets.contains_key(&asset_id)
3758    }
3759
3760    /// Starts loading an uncached asset and returns its result once available.
3761    ///
3762    /// Pending loads and completed results are cached until [`Self::remove_asset`].
3763    /// This method does not subscribe a view to completion notifications.
3764    pub fn fetch_asset<A: Asset>(&mut self, source: &A::Source) -> Option<A::Output> {
3765        self.asset_entry::<A>(source).get()
3766    }
3767
3768    pub(crate) fn asset_entry<A: Asset>(&mut self, source: &A::Source) -> &CachedLoad<A::Output> {
3769        let asset_id = (TypeId::of::<A>(), hash(source));
3770        if !self.loading_assets.contains_key(&asset_id) {
3771            let future = A::load(source.clone(), self);
3772            let entry = CachedLoad::new(future, self);
3773            self.loading_assets.insert(asset_id, Box::new(entry));
3774        }
3775        self.loading_assets
3776            .get(&asset_id)
3777            .and_then(|entry| entry.downcast_ref())
3778            .expect("asset cache entries are keyed by their asset type")
3779    }
3780
3781    /// Creates a new [`FocusHandle`] for tracking keyboard focus.
3782    ///
3783    /// Attach the handle to an element with `track_focus`, and move focus to it with
3784    /// [`Window::focus`].
3785    #[track_caller]
3786    pub fn focus_handle(&self) -> FocusHandle {
3787        FocusHandle::new(&self.focus_handles)
3788    }
3789
3790    /// Returns the debugging name of this app, if one was set.
3791    ///
3792    /// Only available in tests, with the `test-support` feature, or in debug builds.
3793    #[cfg(any(test, feature = "test-support", debug_assertions))]
3794    pub fn get_name(&self) -> Option<&'static str> {
3795        self.name
3796    }
3797
3798    /// Returns `true` if the platform file picker supports selecting a mix of files and directories.
3799    pub fn can_select_mixed_files_and_dirs(&self) -> bool {
3800        self.platform.can_select_mixed_files_and_dirs()
3801    }
3802
3803    /// Removes an image from the sprite atlas on all windows.
3804    ///
3805    /// A window that is being updated is not in `App.windows`, so pass it as `current_window` to
3806    /// remove the image from it too.
3807    /// This is a no-op if the image is not in the sprite atlas.
3808    pub fn drop_image(&mut self, image: Arc<RenderImage>, current_window: Option<&mut Window>) {
3809        // remove the texture from all other windows
3810        for window in self.windows.values_mut().flatten() {
3811            _ = window.drop_image(image.clone());
3812        }
3813
3814        // remove the texture from the current window
3815        if let Some(window) = current_window {
3816            _ = window.drop_image(image);
3817        }
3818    }
3819
3820    /// Sets the renderer for the inspector.
3821    #[cfg(any(feature = "inspector", debug_assertions))]
3822    pub fn set_inspector_renderer(&mut self, f: crate::InspectorRenderer) {
3823        self.inspector_renderer = Some(f);
3824    }
3825
3826    /// Registers a renderer specific to an inspector state.
3827    #[cfg(any(feature = "inspector", debug_assertions))]
3828    pub fn register_inspector_element<T: 'static, R: crate::IntoElement, F>(
3829        &mut self,
3830        factory: impl 'static + Fn(&mut Window, &mut App) -> F,
3831    ) where
3832        F: 'static + FnMut(crate::InspectorElementId, &T, &mut Window, &mut App) -> R,
3833    {
3834        self.inspector_element_registry.register(factory);
3835    }
3836
3837    /// Sets the default [`Colors`] global, which `cx.default_colors()` returns.
3838    pub fn init_colors(&mut self) {
3839        self.set_global(GlobalColors(Arc::new(Colors::default())));
3840    }
3841
3842    #[inline(never)]
3843    fn update_window_erased(
3844        &mut self,
3845        window_id: WindowId,
3846        update: &mut dyn FnMut(Option<(AnyView, &mut Window, &mut App)>),
3847    ) {
3848        self.update(|cx| {
3849            let Some(mut window) = cx.windows.get_mut(window_id).and_then(Option::take) else {
3850                update(None);
3851                return;
3852            };
3853
3854            let root_view = window.root.clone().unwrap();
3855
3856            cx.window_update_stack.push(window.handle.id);
3857            update(Some((root_view, &mut window, cx)));
3858            fn trail(window_id: WindowId, window: Box<Window>, cx: &mut App) -> Option<()> {
3859                cx.window_update_stack.pop();
3860
3861                if window.removed {
3862                    cx.end_platform_drag(window_id);
3863                    cx.window_handles.remove(&window_id);
3864                    cx.windows.remove(window_id);
3865                    if let Some(tracked) = cx.tracked_entities.remove(&window_id) {
3866                        for entity_id in tracked {
3867                            if let Some(windows) =
3868                                cx.window_invalidators_by_entity.get_mut(&entity_id)
3869                            {
3870                                windows.remove(&window_id);
3871                            }
3872                            if cx.current_window_by_entity.get(&entity_id) == Some(&window_id) {
3873                                cx.current_window_by_entity.remove(&entity_id);
3874                            }
3875                        }
3876                    }
3877
3878                    cx.window_closed_observers.clone().retain(&(), |callback| {
3879                        callback(cx, window_id);
3880                        true
3881                    });
3882
3883                    let quit_on_empty = match cx.quit_mode {
3884                        QuitMode::Explicit => false,
3885                        QuitMode::LastWindowClosed => true,
3886                        QuitMode::Default => cfg!(not(target_os = "macos")),
3887                    };
3888
3889                    if quit_on_empty && cx.windows.is_empty() {
3890                        cx.quit();
3891                    }
3892                } else {
3893                    cx.windows.get_mut(window_id)?.replace(window);
3894                }
3895                Some(())
3896            }
3897            if trail(window_id, window, cx).is_none() {
3898                update(None);
3899            }
3900        });
3901    }
3902
3903    #[inline(never)]
3904    fn update_entity_erased(
3905        &mut self,
3906        handle: &AnyEntity,
3907        entity_type: &str,
3908        update: &mut dyn FnMut(&mut dyn Any, &mut App),
3909    ) {
3910        self.update(|cx| {
3911            let mut lease = cx.entities.lease_erased(handle, entity_type);
3912            update(lease.entity.as_deref_mut().unwrap(), cx);
3913            cx.entities.end_lease_erased(handle.entity_id, lease);
3914        });
3915    }
3916
3917    #[inline(never)]
3918    #[track_caller]
3919    fn prepare_spawn(&self) -> AsyncApp {
3920        if self.quitting {
3921            debug_panic!("Can't spawn on main thread after on_app_quit")
3922        };
3923        self.to_async()
3924    }
3925}
3926
3927impl AppContext for App {
3928    /// Builds an entity that is owned by the application.
3929    ///
3930    /// The given function will be invoked with a [`Context`] and must return an object representing the entity. An
3931    /// [`Entity`] handle will be returned, which can be used to access the entity in a context.
3932    fn new<T: 'static>(&mut self, build_entity: impl FnOnce(&mut Context<T>) -> T) -> Entity<T> {
3933        self.update(|cx| {
3934            let slot = cx.entities.reserve();
3935            let handle = slot.clone();
3936            let entity = build_entity(&mut Context::new_context(cx, slot.downgrade()));
3937
3938            cx.push_effect(Effect::EntityCreated {
3939                entity: handle.into_any(),
3940                tid: TypeId::of::<T>(),
3941                window: cx.window_update_stack.last().cloned(),
3942            });
3943
3944            cx.entities.insert(slot, entity)
3945        })
3946    }
3947
3948    fn reserve_entity<T: 'static>(&mut self) -> Reservation<T> {
3949        Reservation(self.entities.reserve())
3950    }
3951
3952    fn insert_entity<T: 'static>(
3953        &mut self,
3954        reservation: Reservation<T>,
3955        build_entity: impl FnOnce(&mut Context<T>) -> T,
3956    ) -> Entity<T> {
3957        self.update(|cx| {
3958            let slot = reservation.0;
3959            let entity = build_entity(&mut Context::new_context(cx, slot.downgrade()));
3960            cx.entities.insert(slot, entity)
3961        })
3962    }
3963
3964    /// Updates the entity referenced by the given handle. The function is passed a mutable reference to the
3965    /// entity along with a `Context` for the entity.
3966    #[inline(always)]
3967    fn update_entity<T: 'static, R>(
3968        &mut self,
3969        handle: &Entity<T>,
3970        update: impl FnOnce(&mut T, &mut Context<T>) -> R,
3971    ) -> R {
3972        let mut update = Some(update);
3973        let mut result = None;
3974        self.update_entity_erased(handle, type_name::<T>(), &mut |entity, cx| {
3975            let value = update.take().unwrap()(
3976                entity.downcast_mut::<T>().unwrap(),
3977                &mut Context::new_context(cx, handle.downgrade()),
3978            );
3979            result = Some(value);
3980        });
3981        result.unwrap()
3982    }
3983
3984    fn as_mut<'a, T>(&'a mut self, handle: &Entity<T>) -> GpuiBorrow<'a, T>
3985    where
3986        T: 'static,
3987    {
3988        GpuiBorrow::new(handle.clone(), self)
3989    }
3990
3991    #[inline(always)]
3992    fn read_entity<T, R>(&self, handle: &Entity<T>, read: impl FnOnce(&T, &App) -> R) -> R
3993    where
3994        T: 'static,
3995    {
3996        let entity = self.entities.read(handle);
3997        read(entity, self)
3998    }
3999
4000    fn notify(&mut self, entity_id: EntityId) {
4001        let window_invalidators = mem::take(
4002            self.window_invalidators_by_entity
4003                .entry(entity_id)
4004                .or_default(),
4005        );
4006
4007        // `window_invalidators_by_entity` is monotonic, so an entry alone
4008        // doesn't mean the window is currently rendering the entity. Filter
4009        // through `tracked_entities` to keep invalidation tight to windows
4010        // that actually display this entity right now.
4011        let live_invalidators: SmallVec<[WindowInvalidator; 2]> = window_invalidators
4012            .iter()
4013            .filter(|(window_id, _)| {
4014                self.tracked_entities
4015                    .get(window_id)
4016                    .is_some_and(|set| set.contains(&entity_id))
4017            })
4018            .map(|(_, invalidator)| invalidator.clone())
4019            .collect();
4020
4021        if live_invalidators.is_empty() {
4022            if self.pending_notifications.insert(entity_id) {
4023                self.pending_effects
4024                    .push_back(Effect::Notify { emitter: entity_id });
4025            }
4026        } else {
4027            for invalidator in &live_invalidators {
4028                invalidator.invalidate_view(entity_id, self);
4029            }
4030        }
4031
4032        self.window_invalidators_by_entity
4033            .insert(entity_id, window_invalidators);
4034    }
4035
4036    fn emit<EntityType, EventType>(&mut self, entity: &Entity<EntityType>, event: EventType)
4037    where
4038        EntityType: EventEmitter<EventType>,
4039        EventType: 'static,
4040    {
4041        let event = self
4042            .event_arena
4043            .alloc(|| event)
4044            .map(|it| it as &mut dyn Any);
4045        self.pending_effects.push_back(Effect::Emit {
4046            emitter: entity.entity_id(),
4047            event_type: TypeId::of::<EventType>(),
4048            event,
4049        });
4050    }
4051
4052    fn update_window<T, F>(&mut self, handle: AnyWindowHandle, update: F) -> Result<T>
4053    where
4054        F: FnOnce(AnyView, &mut Window, &mut App) -> T,
4055    {
4056        self.update_window_id(handle.id, update)
4057    }
4058
4059    fn with_window<R>(
4060        &mut self,
4061        entity_id: EntityId,
4062        f: impl FnOnce(&mut Window, &mut App) -> R,
4063    ) -> Option<R> {
4064        App::with_window(self, entity_id, f)
4065    }
4066
4067    fn read_window<T, R>(
4068        &self,
4069        window: &WindowHandle<T>,
4070        read: impl FnOnce(Entity<T>, &App) -> R,
4071    ) -> Result<R>
4072    where
4073        T: 'static,
4074    {
4075        let window = self
4076            .windows
4077            .get(window.id)
4078            .context("window not found")?
4079            .as_deref()
4080            .expect("attempted to read a window that is already on the stack");
4081
4082        let root_view = window.root.clone().unwrap();
4083        let view = root_view
4084            .downcast::<T>()
4085            .map_err(|_| anyhow!("root view's type has changed"))?;
4086
4087        Ok(read(view, self))
4088    }
4089
4090    fn background_spawn<R>(&self, future: impl Future<Output = R> + Send + 'static) -> Task<R>
4091    where
4092        R: Send + 'static,
4093    {
4094        self.background_executor.spawn(future)
4095    }
4096
4097    fn read_global<G, R>(&self, callback: impl FnOnce(&G, &App) -> R) -> R
4098    where
4099        G: Global,
4100    {
4101        let mut g = self.global::<G>();
4102        callback(g, self)
4103    }
4104
4105    fn insert_global_entity<T: 'static>(&mut self, entity: Entity<T>) {
4106        let any = entity.into_any();
4107        if !self.global_entities.contains(&any) {
4108            self.global_entities.push(any);
4109        }
4110    }
4111
4112    fn remove_global_entity<T: 'static>(&mut self, entity: &Entity<T>) {
4113        self.global_entities
4114            .retain(|any| any.entity_id() != entity.entity_id());
4115    }
4116
4117    fn global_entities<T: 'static>(&self) -> impl Iterator<Item = Entity<T>> {
4118        let mut iter = self.global_entities.iter();
4119        iter.filter_map(|any| any.clone().downcast::<T>().ok())
4120    }
4121}
4122
4123/// These effects are processed at the end of each application update cycle.
4124pub(crate) enum Effect {
4125    Notify {
4126        emitter: EntityId,
4127    },
4128    Emit {
4129        emitter: EntityId,
4130        event_type: TypeId,
4131        event: ArenaBox<dyn Any>,
4132    },
4133    RefreshWindows,
4134    NotifyGlobalObservers {
4135        global_type: TypeId,
4136    },
4137    Defer {
4138        callback: Box<dyn FnOnce(&mut App) + 'static>,
4139    },
4140    EntityCreated {
4141        entity: AnyEntity,
4142        tid: TypeId,
4143        window: Option<WindowId>,
4144    },
4145}
4146
4147impl std::fmt::Debug for Effect {
4148    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4149        match self {
4150            Effect::Notify { emitter } => write!(f, "Notify({})", emitter),
4151            Effect::Emit { emitter, .. } => write!(f, "Emit({:?})", emitter),
4152            Effect::RefreshWindows => write!(f, "RefreshWindows"),
4153            Effect::NotifyGlobalObservers { global_type } => {
4154                write!(f, "NotifyGlobalObservers({:?})", global_type)
4155            }
4156            Effect::Defer { .. } => write!(f, "Defer(..)"),
4157            Effect::EntityCreated { entity, .. } => write!(f, "EntityCreated({:?})", entity),
4158        }
4159    }
4160}
4161
4162/// Wraps a global variable value during `update_global` while the value has been moved to the stack.
4163pub(crate) struct GlobalLease<G: Global> {
4164    global: Box<dyn Any>,
4165    global_type: PhantomData<G>,
4166}
4167
4168impl<G: Global> GlobalLease<G> {
4169    fn new(global: Box<dyn Any>) -> Self {
4170        GlobalLease {
4171            global,
4172            global_type: PhantomData,
4173        }
4174    }
4175}
4176
4177impl<G: Global> Deref for GlobalLease<G> {
4178    type Target = G;
4179
4180    fn deref(&self) -> &Self::Target {
4181        self.global.downcast_ref().unwrap()
4182    }
4183}
4184
4185impl<G: Global> DerefMut for GlobalLease<G> {
4186    fn deref_mut(&mut self) -> &mut Self::Target {
4187        self.global.downcast_mut().unwrap()
4188    }
4189}
4190
4191/// The state of a drag in progress, started by dragging an element in a window.
4192///
4193/// Set with [`App::start_drag`]. Read it with [`App::active_drag`]. It is cleared by
4194/// [`App::stop_drag`] when the drop happens.
4195#[derive(derive_setters::Setters)]
4196#[setters(generate = false)]
4197pub struct AnyDrag {
4198    /// The view that draws the dragged item under the cursor.
4199    pub view: AnyView,
4200
4201    /// The value that the drop target receives.
4202    pub value: Arc<dyn Any>,
4203
4204    /// The offset from the cursor to the drag view, so the view stays under the same point it was grabbed.
4205    #[setters(generate, rename = "offset")]
4206    pub cursor_offset: Point<Pixels>,
4207
4208    /// The cursor shown during the drag, or `None` for the default.
4209    #[setters(generate)]
4210    pub cursor_style: Option<CursorStyle>,
4211
4212    /// Resolves the payload to offer the platform if the drag leaves the window.
4213    /// Invoked at most once per drag gesture, at promotion time.
4214    pub external_payload_source: Option<ExternalDragPayloadSource>,
4215}
4216
4217impl AnyDrag {
4218    /// Creates a drag that carries `value` and draws `view` under the cursor.
4219    pub fn new<T: 'static + Sized>(value: T, view: impl Into<AnyView>) -> Self {
4220        Self {
4221            view: view.into(),
4222            value: Arc::new(value),
4223            cursor_offset: Point::default(),
4224            cursor_style: None,
4225            external_payload_source: None,
4226        }
4227    }
4228
4229    /// Sets [`AnyDrag::external_payload_source`]: the closure builds the payload if the drag leaves the window.
4230    pub fn external_payload(
4231        mut self,
4232        predicate: impl FnOnce(&mut Window, &mut App) -> Option<ExternalDragPayload> + 'static,
4233    ) -> Self {
4234        self.external_payload_source = Some(Box::new(predicate));
4235        self
4236    }
4237
4238    /// Returns whether the dragged value has type `T`.
4239    pub fn is_type<T: 'static>(&self) -> bool {
4240        self.value.as_ref().type_id() == TypeId::of::<T>()
4241    }
4242}
4243
4244/// A closure that builds the payload for a drag that leaves the window.
4245///
4246/// It runs when the drag becomes a native drag session, not when the drag starts. Set it
4247/// with [`AnyDrag::external_payload`].
4248pub type ExternalDragPayloadSource =
4249    Box<dyn FnOnce(&mut Window, &mut App) -> Option<ExternalDragPayload> + 'static>;
4250
4251/// The state of a tooltip that is currently shown.
4252///
4253/// You need this type only when you implement tooltip behavior on a custom element.
4254/// Otherwise use [`Interactivity::tooltip`](crate::Interactivity::tooltip).
4255#[derive(Clone)]
4256pub struct AnyTooltip {
4257    /// The view that draws the tooltip.
4258    pub view: AnyView,
4259
4260    /// The absolute position of the mouse when the tooltip was shown.
4261    pub mouse_position: Point<Pixels>,
4262
4263    /// Given the bounds of the tooltip, checks whether the tooltip should still be visible and
4264    /// updates its state accordingly. This is needed atop the hovered element's mouse move handler
4265    /// to handle the case where the element is not painted (e.g. via use of `visible_on_hover`).
4266    pub check_visible_and_update: Rc<dyn Fn(Bounds<Pixels>, &mut Window, &mut App) -> bool>,
4267}
4268
4269/// Whether a keystroke should prefer character input or key bindings.
4270#[derive(Clone, Copy, Debug, Eq, PartialEq)]
4271pub enum InputPreference {
4272    /// Prefer typing text over triggering key bindings.
4273    CharacterInput,
4274    /// Dispatch key bindings normally, if any match.
4275    KeyBindings,
4276}
4277
4278/// A keystroke that reached the app, with the action it resolved to, if any.
4279///
4280/// Passed to the callbacks from [`App::observe_keystrokes`] and [`App::intercept_keystrokes`].
4281#[derive(Debug)]
4282pub struct KeystrokeEvent {
4283    /// The keystroke that was pressed.
4284    pub keystroke: Keystroke,
4285
4286    /// Whether this keystroke should prefer character input or key bindings.
4287    /// This is [`InputPreference::CharacterInput`] when the platform prefers text for the key
4288    /// (e.g. AltGr on Windows) and the focused input accepts text. Interceptors still receive
4289    /// these keystrokes and can consume them.
4290    ///
4291    /// If the keystroke is part of a multi-stroke binding, it still waits as pending input
4292    /// even when this is [`InputPreference::CharacterInput`].
4293    pub input_preference: InputPreference,
4294
4295    /// The action the keystroke resolved to, or `None` if no binding matched. Always
4296    /// `None` in an `intercept_keystrokes` callback.
4297    pub action: Option<Box<dyn Action>>,
4298
4299    /// The key contexts that were active for the keystroke, from the outermost to the focused element.
4300    pub context_stack: Vec<KeyContext>,
4301}
4302
4303/// A mutable borrow of an entity's state, taken out of GPUI while the borrow is alive.
4304pub struct GpuiBorrow<'a, T> {
4305    inner: Option<Lease<T>>,
4306    app: &'a mut App,
4307}
4308
4309impl<'a, T: 'static> GpuiBorrow<'a, T> {
4310    fn new(inner: Entity<T>, app: &'a mut App) -> Self {
4311        app.start_update();
4312        let lease = app.entities.lease(&inner);
4313        Self {
4314            inner: Some(lease),
4315            app,
4316        }
4317    }
4318}
4319
4320impl<'a, T: 'static> std::borrow::Borrow<T> for GpuiBorrow<'a, T> {
4321    fn borrow(&self) -> &T {
4322        self.inner.as_ref().unwrap().borrow()
4323    }
4324}
4325
4326impl<'a, T: 'static> std::borrow::BorrowMut<T> for GpuiBorrow<'a, T> {
4327    fn borrow_mut(&mut self) -> &mut T {
4328        self.inner.as_mut().unwrap().borrow_mut()
4329    }
4330}
4331
4332impl<'a, T: 'static> std::ops::Deref for GpuiBorrow<'a, T> {
4333    type Target = T;
4334
4335    fn deref(&self) -> &Self::Target {
4336        self.inner.as_ref().unwrap()
4337    }
4338}
4339
4340impl<'a, T: 'static> std::ops::DerefMut for GpuiBorrow<'a, T> {
4341    fn deref_mut(&mut self) -> &mut T {
4342        self.inner.as_mut().unwrap()
4343    }
4344}
4345
4346impl<'a, T> Drop for GpuiBorrow<'a, T> {
4347    fn drop(&mut self) {
4348        let lease = self.inner.take().unwrap();
4349        self.app.notify(lease.id);
4350        self.app.entities.end_lease(lease);
4351        self.app.finish_update();
4352    }
4353}
4354
4355#[cfg(test)]
4356mod test {
4357    use std::{
4358        cell::{Cell, RefCell},
4359        ffi::OsString,
4360        path::PathBuf,
4361        rc::Rc,
4362    };
4363
4364    #[cfg(unix)]
4365    use std::os::unix::ffi::OsStringExt;
4366
4367    use crate::{AppContext, Context, Empty, IntoElement, Render, TestAppContext, Window};
4368
4369    struct RenderCounter(Rc<Cell<usize>>);
4370
4371    impl Render for RenderCounter {
4372        fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
4373            self.0.set(self.0.get() + 1);
4374            Empty
4375        }
4376    }
4377
4378    #[gpui::test]
4379    fn async_app_refresh_flushes_refresh_effect(cx: &mut TestAppContext) {
4380        let render_count = Rc::new(Cell::new(0));
4381
4382        let _window = cx.add_window({
4383            let render_count = render_count.clone();
4384            move |_, _| RenderCounter(render_count)
4385        });
4386
4387        cx.run_until_parked();
4388        let render_count_before_refresh = render_count.get();
4389
4390        cx.to_async().refresh();
4391
4392        assert_eq!(render_count.get(), render_count_before_refresh + 1);
4393    }
4394
4395    #[test]
4396    fn embedded_update_flushes_effects() {
4397        let cx = TestAppContext::single();
4398        let handle = super::ApplicationHandle { app: cx.app };
4399        let completed = Rc::new(Cell::new(false));
4400
4401        handle.update(|cx| {
4402            cx.defer({
4403                let completed = completed.clone();
4404                move |_| completed.set(true)
4405            });
4406        });
4407
4408        assert!(completed.get());
4409    }
4410
4411    #[gpui::test]
4412    fn nested_update_defers_new_effects_until_current_effect_returns(cx: &mut TestAppContext) {
4413        let order = Rc::new(RefCell::new(Vec::new()));
4414        cx.update({
4415            let order = order.clone();
4416            move |cx| {
4417                cx.defer(move |cx| {
4418                    order.borrow_mut().push("outer-start");
4419                    cx.update({
4420                        let order = order.clone();
4421                        |cx| {
4422                            cx.defer(move |_| order.borrow_mut().push("nested"));
4423                        }
4424                    });
4425                    order.borrow_mut().push("outer-end");
4426                });
4427            }
4428        });
4429
4430        assert_eq!(*order.borrow(), ["outer-start", "outer-end", "nested"]);
4431    }
4432
4433    #[gpui::test]
4434    fn adding_a_tab_group_after_removal_preserves_other_groups(cx: &mut TestAppContext) {
4435        use super::{SystemWindowTab, SystemWindowTabController};
4436
4437        let windows: Vec<_> = (0..4).map(|_| cx.add_window(|_, _| Empty)).collect();
4438        cx.update(|cx| {
4439            for (ix, window) in windows.iter().take(3).enumerate() {
4440                SystemWindowTabController::add_tab(
4441                    cx,
4442                    window.window_id(),
4443                    vec![SystemWindowTab::new(
4444                        format!("Window {ix}").into(),
4445                        (*window).into(),
4446                    )],
4447                );
4448            }
4449            SystemWindowTabController::remove_tab(cx, windows[0].window_id());
4450            SystemWindowTabController::add_tab(
4451                cx,
4452                windows[3].window_id(),
4453                vec![SystemWindowTab::new("New window".into(), windows[3].into())],
4454            );
4455
4456            let controller = cx.global::<SystemWindowTabController>();
4457            assert_eq!(controller.tab_groups.len(), 3);
4458            for window in &windows[1..] {
4459                assert_eq!(controller.tabs(window.window_id()).unwrap().len(), 1);
4460            }
4461        });
4462    }
4463
4464    #[gpui::test]
4465    fn drag_type_matches_the_payload(cx: &mut TestAppContext) {
4466        cx.update(|cx| {
4467            let view = cx.new(|_| Empty);
4468            let drag = super::AnyDrag::new(String::from("row"), view);
4469            assert!(drag.is_type::<String>());
4470            assert!(!drag.is_type::<usize>());
4471            assert!(!drag.is_type::<std::sync::Arc<dyn std::any::Any>>());
4472        });
4473    }
4474
4475    #[test]
4476    fn test_gpui_borrow() {
4477        let cx = TestAppContext::single();
4478        let observation_count = Rc::new(RefCell::new(0));
4479
4480        let state = cx.update(|cx| {
4481            let state = cx.new(|_| false);
4482            cx.observe(&state, {
4483                let observation_count = observation_count.clone();
4484                move |_, _| {
4485                    let mut count = observation_count.borrow_mut();
4486                    *count += 1;
4487                }
4488            })
4489            .detach();
4490
4491            state
4492        });
4493
4494        cx.update(|cx| {
4495            // Calling this like this so that we don't clobber the borrow_mut above
4496            *std::borrow::BorrowMut::borrow_mut(&mut state.as_mut(cx)) = true;
4497        });
4498
4499        cx.update(|cx| {
4500            state.write(cx, false);
4501        });
4502
4503        assert_eq!(*observation_count.borrow(), 2);
4504    }
4505
4506    #[gpui::test]
4507    async fn test_restart_preserves_path_and_arguments(cx: &mut TestAppContext) {
4508        #[cfg(unix)]
4509        let user_data_dir = OsString::from_vec(b"/tmp/zed data/\xff".to_vec());
4510        #[cfg(not(unix))]
4511        let user_data_dir = OsString::from("C:\\zed data");
4512        let arguments = vec![OsString::from("--user-data-dir"), user_data_dir];
4513        let restart_path = PathBuf::from("updated-zed");
4514        let _application =
4515            super::Application(cx.app.clone()).with_restart_arguments(arguments.clone());
4516        let restart = cx.expect_restart();
4517
4518        cx.update(|cx| {
4519            cx.set_restart_path(restart_path.clone());
4520            cx.restart();
4521        });
4522
4523        let (path, restart_arguments) = restart.await.expect("restart was not requested");
4524        assert_eq!(path, Some(restart_path));
4525        assert_eq!(restart_arguments, arguments);
4526    }
4527}