2904 lines · 96.6 KB · Rust
RawDownload
mod app_menu;mod keyboard;mod keystroke; #[cfg(all(target_os = "linux", feature = "wayland"))]#[expect(missing_docs)]pub mod layer_shell; /// Types for configuring parent-anchored popup windows such as menus, dropdowns and tooltips.pub mod popup; #[cfg(any(test, feature = "bench"))]mod bench_dispatcher; #[cfg(any(test, feature = "test-support"))]mod test; #[cfg(all(target_os = "macos", any(test, feature = "test-support")))]mod visual_test; #[cfg(all(    feature = "screen-capture",    any(target_os = "windows", target_os = "linux", target_os = "freebsd",)))]pub mod scap_screen_capture; #[cfg(all(    any(target_os = "windows", target_os = "linux"),    feature = "screen-capture"))]pub(crate) type PlatformScreenCaptureFrame = scap::frame::Frame;#[cfg(not(feature = "screen-capture"))]pub(crate) type PlatformScreenCaptureFrame = ();#[cfg(all(target_os = "macos", feature = "screen-capture"))]pub(crate) type PlatformScreenCaptureFrame = core_video::image_buffer::CVImageBuffer; use crate::{    Action, AnyWindowHandle, App, AsyncWindowContext, BackgroundExecutor, Bounds,    DEFAULT_WINDOW_SIZE, DevicePixels, DispatchEventResult, Edges, ExternalDragPayload, Font,    FontId, FontMetrics, FontRun, ForegroundExecutor, GlyphId, GpuSpecs, Hsla, ImageSource, Keymap,    LineLayout, Pixels, PlatformGestures, PlatformInput, Point, Priority, RenderGlyphParams,    RenderImage, RenderImageParams, RenderSvgParams, Scene, ShapedGlyph, ShapedRun, SharedString,    Size, SvgRenderer, SystemWindowTab, Task, Window, WindowControlArea, hash, point, px, size,};#[cfg(any(target_os = "linux", target_os = "freebsd"))]use anyhow::bail;use anyhow::{Context as _, Result};use async_task::Runnable;use futures::channel::oneshot;#[cfg(any(test, feature = "test-support"))]use image::RgbaImage;use image::codecs::gif::GifDecoder;use image::{AnimationDecoder as _, DynamicImage, Frame};use raw_window_handle::{HasDisplayHandle, HasWindowHandle};use scheduler::Instant;pub use scheduler::RunnableMeta;use schemars::JsonSchema;use seahash::SeaHasher;use serde::{Deserialize, Serialize};use smallvec::SmallVec;use std::borrow::Cow;use std::hash::{Hash, Hasher};use std::io::Cursor;use std::ops;use std::time::Duration;use std::{    fmt::{self, Debug},    ops::Range,    path::{Path, PathBuf},    rc::Rc,    sync::Arc,};use strum::EnumIter;use uuid::Uuid; pub use app_menu::*;pub use keyboard::*;pub use keystroke::*; #[cfg(any(test, feature = "test-support"))]pub(crate) use test::*; #[cfg(any(test, feature = "test-support"))]pub use test::{TestDispatcher, TestScreenCaptureSource, TestScreenCaptureStream}; #[cfg(any(test, feature = "bench"))]pub use bench_dispatcher::BenchDispatcher; #[cfg(all(target_os = "macos", any(test, feature = "test-support")))]pub use visual_test::VisualTestPlatform; // TODO(jk): return an enum instead of a string/// Return which compositor we're guessing we'll use./// Does not attempt to connect to the given compositor.#[cfg(any(target_os = "linux", target_os = "freebsd"))]#[inline]pub fn guess_compositor() -> &'static str {    if std::env::var_os("ZED_HEADLESS").is_some() {        return "Headless";    }     #[cfg(feature = "wayland")]    let wayland_display = std::env::var_os("WAYLAND_DISPLAY");    #[cfg(not(feature = "wayland"))]    let wayland_display: Option<std::ffi::OsString> = None;     #[cfg(feature = "x11")]    let x11_display = std::env::var_os("DISPLAY");    #[cfg(not(feature = "x11"))]    let x11_display: Option<std::ffi::OsString> = None;     let use_wayland = wayland_display.is_some_and(|display| !display.is_empty());    let use_x11 = x11_display.is_some_and(|display| !display.is_empty());     if use_wayland {        "Wayland"    } else if use_x11 {        "X11"    } else {        "Headless"    }} #[expect(missing_docs)]pub trait Platform: 'static {    fn background_executor(&self) -> BackgroundExecutor;    fn foreground_executor(&self) -> ForegroundExecutor;    fn text_system(&self) -> Arc<dyn PlatformTextSystem>;     fn run(&self, on_finish_launching: Box<dyn 'static + FnOnce()>);    fn quit(&self);    fn restart(&self, binary_path: Option<PathBuf>);    fn activate(&self, ignoring_other_apps: bool);    fn hide(&self);    fn hide_other_apps(&self);    fn unhide_other_apps(&self);     fn displays(&self) -> Vec<Rc<dyn PlatformDisplay>>;    fn primary_display(&self) -> Option<Rc<dyn PlatformDisplay>>;    fn active_window(&self) -> Option<AnyWindowHandle>;    fn window_stack(&self) -> Option<Vec<AnyWindowHandle>> {        None    }     fn is_screen_capture_supported(&self) -> bool {        false    }     fn screen_capture_sources(        &self,    ) -> oneshot::Receiver<anyhow::Result<Vec<Rc<dyn ScreenCaptureSource>>>> {        let (sources_tx, sources_rx) = oneshot::channel();        sources_tx            .send(Err(anyhow::anyhow!(                "gpui was compiled without the screen-capture feature"            )))            .ok();        sources_rx    }     fn open_window(        &self,        handle: AnyWindowHandle,        options: WindowParams,    ) -> anyhow::Result<Box<dyn PlatformWindow>>;     /// Returns the appearance of the application's windows.    fn window_appearance(&self) -> WindowAppearance;     /// Overrides the appearance (light/dark) applied to the app's windows, independent    /// of the OS-wide setting. Pass `None` to clear the override and follow the system    /// again. The override is reflected by [`Platform::window_appearance`].    ///    /// Currently only implemented on macOS, where it sets `NSApplication.appearance` so    /// the native window chrome (the window border and titlebar) of every window matches    /// a dark app theme even when the system is in light mode (or vice versa). A no-op on    /// other platforms.    fn set_window_appearance(&self, _appearance: Option<WindowAppearance>) {}     /// Returns the window button layout configuration when supported.    fn button_layout(&self) -> Option<WindowButtonLayout> {        None    }     fn open_url(&self, url: &str);    fn on_open_urls(&self, callback: Box<dyn FnMut(Vec<String>)>);    fn register_url_scheme(&self, url: &str) -> Task<Result<()>>;     fn prompt_for_paths(        &self,        options: PathPromptOptions,    ) -> oneshot::Receiver<Result<Option<Vec<PathBuf>>>>;    fn prompt_for_new_path(        &self,        directory: &Path,        suggested_name: Option<&str>,    ) -> oneshot::Receiver<Result<Option<PathBuf>>>;    fn can_select_mixed_files_and_dirs(&self) -> bool;    fn reveal_path(&self, path: &Path);    fn open_with_system(&self, path: &Path);     fn on_quit(&self, callback: Box<dyn FnMut()>);    fn on_reopen(&self, callback: Box<dyn FnMut()>);    fn on_system_wake(&self, callback: Box<dyn FnMut()>);     // Mobile platform methods. On mobile the OS owns the application    // lifecycle: apps are backgrounded, foregrounded, and killed at the    // system's discretion, and must react rather than decide.     /// Registers a callback invoked whenever the application's lifecycle    /// phase changes. See [`AppLifecyclePhase`] for the phase vocabulary and    /// its mapping onto iOS and Android.    ///    /// Desktop platforms never invoke this.    fn on_app_lifecycle(&self, _callback: Box<dyn FnMut(AppLifecyclePhase)>) {}     /// Registers a callback invoked when the OS signals memory pressure    /// (iOS `didReceiveMemoryWarning`, Android `onTrimMemory`).    ///    /// Desktop platforms never invoke this.    fn on_memory_warning(&self, _callback: Box<dyn FnMut()>) {}     /// The platform's gesture recognition services, if it provides any    /// beyond gpui's portable recognizers. See    /// [`PlatformGestures`](crate::PlatformGestures).    fn gestures(&self) -> Option<Rc<dyn PlatformGestures>> {        None    }     fn set_menus(&self, menus: Vec<Menu>, keymap: &Keymap);    fn get_menus(&self) -> Option<Vec<OwnedMenu>> {        None    }     fn set_dock_menu(&self, menu: Vec<MenuItem>, keymap: &Keymap);    fn perform_dock_menu_action(&self, _action: usize) {}    fn add_recent_document(&self, _path: &Path) {}    fn update_jump_list(        &self,        _menus: Vec<MenuItem>,        _entries: Vec<SmallVec<[PathBuf; 2]>>,    ) -> Task<Vec<SmallVec<[PathBuf; 2]>>> {        Task::ready(Vec::new())    }    fn on_app_menu_action(&self, callback: Box<dyn FnMut(&dyn Action)>);    fn on_will_open_app_menu(&self, callback: Box<dyn FnMut()>);    fn on_validate_app_menu_command(&self, callback: Box<dyn FnMut(&dyn Action) -> bool>);     fn thermal_state(&self) -> ThermalState;    fn on_thermal_state_change(&self, callback: Box<dyn FnMut()>);     /// Sets the application's process-wide identity and user-visible name.    ///    /// The identifier is used for platform identity mechanisms such as the    /// Windows AppUserModelID. The name is used wherever the operating system    /// presents the application to the user. Call this once, early in startup,    /// before opening windows or posting notifications.    fn set_app_identity(&self, identifier: &str, name: &str) {        _ = (identifier, name);    }     /// Posts a notification to the operating system's notification center.    ///    /// Posting a notification whose [`SystemNotification::tag`] matches an    /// earlier one replaces that notification where the platform supports it.    /// No-op on platforms without notification support, or when delivery is    /// unavailable (e.g. authorization was denied).    fn show_system_notification(&self, notification: SystemNotification) {        _ = notification;    }     /// Removes the delivered or pending notification with this tag.    ///    /// Best-effort: some platforms cannot retract a notification once shown,    /// in which case it ages out of the notification center on its own.    fn dismiss_system_notification(&self, tag: &str) {        _ = tag;    }     /// Registers the callback invoked when the user activates a system    /// notification, either by clicking its body or one of its action    /// buttons.    ///    /// Implementations must invoke the callback on the main thread.    fn on_system_notification_response(        &self,        callback: Box<dyn FnMut(SystemNotificationResponse)>,    ) {        _ = callback;    }     fn compositor_name(&self) -> &'static str {        ""    }    fn app_path(&self) -> Result<PathBuf>;    fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf>;     fn set_cursor_style(&self, style: CursorStyle);     /// Hides the mouse cursor until the user moves the mouse over one of    /// this application's windows.    fn hide_cursor_until_mouse_moves(&self);     /// Returns whether the mouse cursor is currently visible.    fn is_cursor_visible(&self) -> bool;     fn should_auto_hide_scrollbars(&self) -> bool;     fn read_from_clipboard(&self) -> Option<ClipboardItem>;    fn write_to_clipboard(&self, item: ClipboardItem);     #[cfg(any(target_os = "linux", target_os = "freebsd"))]    fn read_from_primary(&self) -> Option<ClipboardItem>;    #[cfg(any(target_os = "linux", target_os = "freebsd"))]    fn write_to_primary(&self, item: ClipboardItem);     #[cfg(target_os = "macos")]    fn read_from_find_pasteboard(&self) -> Option<ClipboardItem>;    #[cfg(target_os = "macos")]    fn write_to_find_pasteboard(&self, item: ClipboardItem);     fn write_credentials(&self, url: &str, username: &str, password: &[u8]) -> Task<Result<()>>;    fn read_credentials(&self, url: &str) -> Task<Result<Option<(String, Vec<u8>)>>>;    fn delete_credentials(&self, url: &str) -> Task<Result<()>>;     fn keyboard_layout(&self) -> Box<dyn PlatformKeyboardLayout>;    fn keyboard_mapper(&self) -> Rc<dyn PlatformKeyboardMapper>;    fn on_keyboard_layout_change(&self, callback: Box<dyn FnMut()>);} /// A handle to a platform's display, e.g. a monitor or laptop screen.pub trait PlatformDisplay: Debug {    /// Get the ID for this display    fn id(&self) -> DisplayId;     /// Returns a stable identifier for this display that can be persisted and used    /// across system restarts.    fn uuid(&self) -> Result<Uuid>;     /// Get the bounds for this display    fn bounds(&self) -> Bounds<Pixels>;     /// Get the visible bounds for this display, excluding taskbar/dock areas.    /// This is the usable area where windows can be placed without being obscured.    /// Defaults to the full display bounds if not overridden.    fn visible_bounds(&self) -> Bounds<Pixels> {        self.bounds()    }     /// Get the default bounds for this display to place a window    fn default_bounds(&self) -> Bounds<Pixels> {        let bounds = self.bounds();        let center = bounds.center();        let clipped_window_size = DEFAULT_WINDOW_SIZE.min(&bounds.size);         let offset = clipped_window_size / 2.0;        let origin = point(center.x - offset.width, center.y - offset.height);        Bounds::new(origin, clipped_window_size)    }} /// A notification posted to the operating system's notification center,/// rather than rendered as in-app UI.#[derive(Clone, Debug, PartialEq, Eq)]pub struct SystemNotification {    /// Stable identity for the notification. Posting a new notification with    /// the same tag replaces the previous one where the platform supports it,    /// and responses carry the tag back to the application.    pub tag: SharedString,    /// The notification's headline.    pub title: SharedString,    /// Additional text displayed below the title.    pub body: SharedString,    /// Buttons offered on the notification. Platforms that cannot display    /// action buttons show the notification without them.    pub actions: Vec<SystemNotificationAction>,} /// A button offered on a [`SystemNotification`].#[derive(Clone, Debug, PartialEq, Eq, Hash)]pub struct SystemNotificationAction {    /// Identifies the action in [`SystemNotificationResponse::action_id`]    /// when the user presses this button.    pub id: SharedString,    /// The button's user-visible label.    pub label: SharedString,} /// The user's activation of a [`SystemNotification`].#[derive(Clone, Debug, PartialEq, Eq)]pub struct SystemNotificationResponse {    /// The [`SystemNotification::tag`] of the activated notification.    pub tag: SharedString,    /// The pressed action button's [`SystemNotificationAction::id`], or    /// `None` when the user activated the notification body itself.    pub action_id: Option<SharedString>,} /// Thermal state of the system#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum ThermalState {    /// System has no thermal constraints    Nominal,    /// System is slightly constrained, reduce discretionary work    Fair,    /// System is moderately constrained, reduce CPU/GPU intensive work    Serious,    /// System is critically constrained, minimize all resource usage    Critical,} /// Metadata for a given [ScreenCaptureSource]#[derive(Clone)]pub struct SourceMetadata {    /// Opaque identifier of this screen.    pub id: u64,    /// Human-readable label for this source.    pub label: Option<SharedString>,    /// Whether this source is the main display.    pub is_main: Option<bool>,    /// Video resolution of this source.    pub resolution: Size<DevicePixels>,} /// A source of on-screen video content that can be captured.pub trait ScreenCaptureSource {    /// Returns metadata for this source.    fn metadata(&self) -> Result<SourceMetadata>;     /// Start capture video from this source, invoking the given callback    /// with each frame.    fn stream(        &self,        foreground_executor: &ForegroundExecutor,        frame_callback: Box<dyn Fn(ScreenCaptureFrame) + Send>,    ) -> oneshot::Receiver<Result<Box<dyn ScreenCaptureStream>>>;} /// A video stream captured from a screen.pub trait ScreenCaptureStream {    /// Returns metadata for this source.    fn metadata(&self) -> Result<SourceMetadata>;} /// A frame of video captured from a screen.pub struct ScreenCaptureFrame(pub PlatformScreenCaptureFrame); /// An opaque identifier for a hardware display#[derive(PartialEq, Eq, Hash, Copy, Clone)]pub struct DisplayId(pub(crate) u64); impl DisplayId {    /// Create a new `DisplayId` from a raw platform display identifier.    pub fn new(id: u64) -> Self {        Self(id)    }} impl From<u64> for DisplayId {    fn from(id: u64) -> Self {        Self(id)    }} impl From<DisplayId> for u64 {    fn from(id: DisplayId) -> Self {        id.0    }} impl Debug for DisplayId {    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {        write!(f, "DisplayId({})", self.0)    }} /// Which part of the window to resize#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum ResizeEdge {    /// The top edge    Top,    /// The top right corner    TopRight,    /// The right edge    Right,    /// The bottom right corner    BottomRight,    /// The bottom edge    Bottom,    /// The bottom left corner    BottomLeft,    /// The left edge    Left,    /// The top left corner    TopLeft,} /// A type to describe the appearance of a window#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default)]pub enum WindowDecorations {

Lines 1–500 of 2904.