2018 lines · 63.1 KB · Rust
RawDownload
mod app_menu;mod keyboard;mod keystroke; #[cfg(any(target_os = "linux", target_os = "freebsd"))]mod linux; #[cfg(target_os = "macos")]mod mac; #[cfg(any(    all(        any(target_os = "linux", target_os = "freebsd"),        any(feature = "x11", feature = "wayland")    ),    all(target_os = "macos", feature = "macos-blade")))]mod blade; #[cfg(any(test, feature = "test-support"))]mod test; #[cfg(target_os = "windows")]mod windows; #[cfg(all(    feature = "screen-capture",    any(        target_os = "windows",        all(            any(target_os = "linux", target_os = "freebsd"),            any(feature = "wayland", feature = "x11"),        )    )))]pub(crate) mod scap_screen_capture; use crate::{    Action, AnyWindowHandle, App, AsyncWindowContext, BackgroundExecutor, Bounds,    DEFAULT_WINDOW_SIZE, DevicePixels, DispatchEventResult, Font, FontId, FontMetrics, FontRun,    ForegroundExecutor, GlyphId, GpuSpecs, ImageSource, Keymap, LineLayout, Pixels, PlatformInput,    Point, Priority, RealtimePriority, RenderGlyphParams, RenderImage, RenderImageParams,    RenderSvgParams, Scene, ShapedGlyph, ShapedRun, SharedString, Size, SvgRenderer,    SystemWindowTab, Task, TaskLabel, TaskTiming, ThreadTaskTimings, Window, WindowControlArea,    hash, point, px, size,};use anyhow::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 _, Frame};use raw_window_handle::{HasDisplayHandle, HasWindowHandle};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, Instant};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(target_os = "linux", target_os = "freebsd"))]pub(crate) use linux::*;#[cfg(target_os = "macos")]pub(crate) use mac::*;#[cfg(any(test, feature = "test-support"))]pub(crate) use test::*;#[cfg(target_os = "windows")]pub(crate) use windows::*; #[cfg(all(target_os = "linux", feature = "wayland"))]pub use linux::layer_shell; #[cfg(any(test, feature = "test-support"))]pub use test::{TestDispatcher, TestScreenCaptureSource, TestScreenCaptureStream}; /// Returns a background executor for the current platform.pub fn background_executor() -> BackgroundExecutor {    current_platform(true).background_executor()} #[cfg(target_os = "macos")]pub(crate) fn current_platform(headless: bool) -> Rc<dyn Platform> {    Rc::new(MacPlatform::new(headless))} #[cfg(any(target_os = "linux", target_os = "freebsd"))]pub(crate) fn current_platform(headless: bool) -> Rc<dyn Platform> {    #[cfg(feature = "x11")]    use anyhow::Context as _;     if headless {        return Rc::new(HeadlessClient::new());    }     match guess_compositor() {        #[cfg(feature = "wayland")]        "Wayland" => Rc::new(WaylandClient::new()),         #[cfg(feature = "x11")]        "X11" => Rc::new(            X11Client::new()                .context("Failed to initialize X11 client.")                .unwrap(),        ),         "Headless" => Rc::new(HeadlessClient::new()),        _ => unreachable!(),    }} #[cfg(target_os = "windows")]pub(crate) fn current_platform(_headless: bool) -> Rc<dyn Platform> {    Rc::new(        WindowsPlatform::new()            .inspect_err(|err| show_error("Failed to launch", err.to_string()))            .unwrap(),    )} /// 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"    }} pub(crate) 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    }     #[cfg(feature = "screen-capture")]    fn is_screen_capture_supported(&self) -> bool;    #[cfg(not(feature = "screen-capture"))]    fn is_screen_capture_supported(&self) -> bool {        false    }    #[cfg(feature = "screen-capture")]    fn screen_capture_sources(&self)    -> oneshot::Receiver<Result<Vec<Rc<dyn ScreenCaptureSource>>>>;    #[cfg(not(feature = "screen-capture"))]    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;     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 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]>>,    ) -> Vec<SmallVec<[PathBuf; 2]>> {        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 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);    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: Send + Sync + 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)    }} /// 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) u32); impl From<DisplayId> for u32 {    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 {    #[default]    /// Server side decorations    Server,    /// Client side decorations    Client,} /// A type to describe how this window is currently configured#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default)]pub enum Decorations {    /// The window is configured to use server side decorations    #[default]    Server,    /// The window is configured to use client side decorations    Client {        /// The edge tiling state        tiling: Tiling,    },} /// What window controls this platform supports#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]pub struct WindowControls {    /// Whether this platform supports fullscreen    pub fullscreen: bool,    /// Whether this platform supports maximize    pub maximize: bool,    /// Whether this platform supports minimize    pub minimize: bool,    /// Whether this platform supports a window menu    pub window_menu: bool,} impl Default for WindowControls {    fn default() -> Self {        // Assume that we can do anything, unless told otherwise        Self {            fullscreen: true,            maximize: true,            minimize: true,            window_menu: true,        }    }} /// A type to describe which sides of the window are currently tiled in some way#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default)]pub struct Tiling {    /// Whether the top edge is tiled    pub top: bool,    /// Whether the left edge is tiled    pub left: bool,    /// Whether the right edge is tiled    pub right: bool,    /// Whether the bottom edge is tiled    pub bottom: bool,} impl Tiling {    /// Initializes a [`Tiling`] type with all sides tiled    pub fn tiled() -> Self {        Self {            top: true,            left: true,            right: true,            bottom: true,        }    }     /// Whether any edge is tiled    pub fn is_tiled(&self) -> bool {        self.top || self.left || self.right || self.bottom    }} #[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]pub(crate) struct RequestFrameOptions {    pub(crate) require_presentation: bool,    /// Force refresh of all rendering states when true    pub(crate) force_render: bool,} pub(crate) trait PlatformWindow: HasWindowHandle + HasDisplayHandle {    fn bounds(&self) -> Bounds<Pixels>;    fn is_maximized(&self) -> bool;    fn window_bounds(&self) -> WindowBounds;    fn content_size(&self) -> Size<Pixels>;    fn resize(&mut self, size: Size<Pixels>);    fn scale_factor(&self) -> f32;    fn appearance(&self) -> WindowAppearance;    fn display(&self) -> Option<Rc<dyn PlatformDisplay>>;    fn mouse_position(&self) -> Point<Pixels>;    fn modifiers(&self) -> Modifiers;    fn capslock(&self) -> Capslock;    fn set_input_handler(&mut self, input_handler: PlatformInputHandler);    fn take_input_handler(&mut self) -> Option<PlatformInputHandler>;    fn prompt(        &self,        level: PromptLevel,        msg: &str,        detail: Option<&str>,        answers: &[PromptButton],    ) -> Option<oneshot::Receiver<usize>>;    fn activate(&self);    fn is_active(&self) -> bool;

Lines 1–500 of 2018.