diff --git a/Cargo.toml b/Cargo.toml index ae51d0da42..0155698bf9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -276,6 +276,7 @@ go_to_line = { path = "crates/go_to_line" } google_ai = { path = "crates/google_ai" } gpui = { path = "crates/gpui", default-features = false, features = [ "http_client", + "screen-capture", ] } gpui_macros = { path = "crates/gpui_macros" } gpui_tokio = { path = "crates/gpui_tokio" } diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index 418b7729f4..1ab591e9d7 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -50,7 +50,6 @@ wayland = [ "filedescriptor", "xkbcommon", "open", - "scap", ] x11 = [ "blade-graphics", @@ -67,6 +66,8 @@ x11 = [ "x11-clipboard", "filedescriptor", "open", +] +screen-capture = [ "scap", ] windows-manifest = [] diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 277f2d9ab8..79ec5e5da6 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -25,6 +25,7 @@ mod test; mod windows; #[cfg(all( + feature = "screen-capture", any(target_os = "linux", target_os = "freebsd"), any(feature = "wayland", feature = "x11"), ))] @@ -176,10 +177,28 @@ pub(crate) trait Platform: 'static { 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>>>; + #[cfg(not(feature = "screen-capture"))] + fn screen_capture_sources( + &self, + ) -> oneshot::Receiver>>> { + 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, diff --git a/crates/gpui/src/platform/linux.rs b/crates/gpui/src/platform/linux.rs index af8b8c2370..5221f71f99 100644 --- a/crates/gpui/src/platform/linux.rs +++ b/crates/gpui/src/platform/linux.rs @@ -23,7 +23,7 @@ pub(crate) use wayland::*; #[cfg(feature = "x11")] pub(crate) use x11::*; -#[cfg(any(feature = "wayland", feature = "x11"))] +#[cfg(all(feature = "screen-capture", any(feature = "wayland", feature = "x11")))] pub(crate) type PlatformScreenCaptureFrame = scap::frame::Frame; -#[cfg(not(any(feature = "wayland", feature = "x11")))] +#[cfg(not(all(feature = "screen-capture", any(feature = "wayland", feature = "x11"))))] pub(crate) type PlatformScreenCaptureFrame = (); diff --git a/crates/gpui/src/platform/linux/headless/client.rs b/crates/gpui/src/platform/linux/headless/client.rs index d541c7f152..663a740389 100644 --- a/crates/gpui/src/platform/linux/headless/client.rs +++ b/crates/gpui/src/platform/linux/headless/client.rs @@ -1,16 +1,14 @@ use std::cell::RefCell; use std::rc::Rc; -use anyhow::anyhow; use calloop::{EventLoop, LoopHandle}; -use futures::channel::oneshot; use util::ResultExt; use crate::platform::linux::LinuxClient; use crate::platform::{LinuxCommon, PlatformWindow}; use crate::{ AnyWindowHandle, CursorStyle, DisplayId, LinuxKeyboardLayout, PlatformDisplay, - PlatformKeyboardLayout, ScreenCaptureSource, WindowParams, + PlatformKeyboardLayout, WindowParams, }; pub struct HeadlessClientState { @@ -67,15 +65,18 @@ impl LinuxClient for HeadlessClient { None } + #[cfg(feature = "screen-capture")] fn is_screen_capture_supported(&self) -> bool { false } + #[cfg(feature = "screen-capture")] fn screen_capture_sources( &self, - ) -> oneshot::Receiver>>> { - let (mut tx, rx) = oneshot::channel(); - tx.send(Err(anyhow!( + ) -> futures::channel::oneshot::Receiver>>> + { + let (mut tx, rx) = futures::channel::oneshot::channel(); + tx.send(Err(anyhow::anyhow!( "Headless mode does not support screen capture." ))) .ok(); diff --git a/crates/gpui/src/platform/linux/platform.rs b/crates/gpui/src/platform/linux/platform.rs index 180ff065c2..01a587e72a 100644 --- a/crates/gpui/src/platform/linux/platform.rs +++ b/crates/gpui/src/platform/linux/platform.rs @@ -26,7 +26,7 @@ use crate::{ Action, AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId, ForegroundExecutor, Keymap, LinuxDispatcher, Menu, MenuItem, OwnedMenu, PathPromptOptions, Pixels, Platform, PlatformDisplay, PlatformKeyboardLayout, PlatformTextSystem, PlatformWindow, - Point, Result, ScreenCaptureSource, Task, WindowAppearance, WindowParams, px, + Point, Result, Task, WindowAppearance, WindowParams, px, }; #[cfg(any(feature = "wayland", feature = "x11"))] @@ -51,10 +51,12 @@ pub trait LinuxClient { #[allow(unused)] fn display(&self, id: DisplayId) -> Option>; fn primary_display(&self) -> Option>; + #[cfg(feature = "screen-capture")] fn is_screen_capture_supported(&self) -> bool; + #[cfg(feature = "screen-capture")] fn screen_capture_sources( &self, - ) -> oneshot::Receiver>>>; + ) -> oneshot::Receiver>>>; fn open_window( &self, @@ -235,13 +237,15 @@ impl Platform for P { self.displays() } + #[cfg(feature = "screen-capture")] fn is_screen_capture_supported(&self) -> bool { self.is_screen_capture_supported() } + #[cfg(feature = "screen-capture")] fn screen_capture_sources( &self, - ) -> oneshot::Receiver>>> { + ) -> oneshot::Receiver>>> { self.screen_capture_sources() } diff --git a/crates/gpui/src/platform/linux/wayland/client.rs b/crates/gpui/src/platform/linux/wayland/client.rs index 2cf6d35f30..57d1dcec04 100644 --- a/crates/gpui/src/platform/linux/wayland/client.rs +++ b/crates/gpui/src/platform/linux/wayland/client.rs @@ -7,7 +7,6 @@ use std::{ time::{Duration, Instant}, }; -use anyhow::anyhow; use calloop::{ EventLoop, LoopHandle, timer::{TimeoutAction, Timer}, @@ -15,7 +14,6 @@ use calloop::{ use calloop_wayland_source::WaylandSource; use collections::HashMap; use filedescriptor::Pipe; -use futures::channel::oneshot; use http_client::Url; use smallvec::SmallVec; use util::ResultExt; @@ -77,8 +75,8 @@ use crate::{ FileDropEvent, ForegroundExecutor, KeyDownEvent, KeyUpEvent, Keystroke, LinuxCommon, LinuxKeyboardLayout, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseExitEvent, MouseMoveEvent, MouseUpEvent, NavigationDirection, Pixels, PlatformDisplay, - PlatformInput, PlatformKeyboardLayout, Point, SCROLL_LINES, ScaledPixels, ScreenCaptureSource, - ScrollDelta, ScrollWheelEvent, Size, TouchPhase, WindowParams, point, px, size, + PlatformInput, PlatformKeyboardLayout, Point, SCROLL_LINES, ScaledPixels, ScrollDelta, + ScrollWheelEvent, Size, TouchPhase, WindowParams, point, px, size, }; use crate::{ SharedString, @@ -666,20 +664,25 @@ impl LinuxClient for WaylandClient { None } + #[cfg(feature = "screen-capture")] fn is_screen_capture_supported(&self) -> bool { false } + #[cfg(feature = "screen-capture")] fn screen_capture_sources( &self, - ) -> oneshot::Receiver>>> { + ) -> futures::channel::oneshot::Receiver>>> + { // TODO: Get screen capture working on wayland. Be sure to try window resizing as that may // be tricky. // // start_scap_default_target_source() - let (sources_tx, sources_rx) = oneshot::channel(); + let (sources_tx, sources_rx) = futures::channel::oneshot::channel(); sources_tx - .send(Err(anyhow!("Wayland screen capture not yet implemented."))) + .send(Err(anyhow::anyhow!( + "Wayland screen capture not yet implemented." + ))) .ok(); sources_rx } diff --git a/crates/gpui/src/platform/linux/x11/client.rs b/crates/gpui/src/platform/linux/x11/client.rs index f0ad8b8cf4..430ce9260b 100644 --- a/crates/gpui/src/platform/linux/x11/client.rs +++ b/crates/gpui/src/platform/linux/x11/client.rs @@ -15,7 +15,6 @@ use calloop::{ generic::{FdWrapper, Generic}, }; use collections::HashMap; -use futures::channel::oneshot; use http_client::Url; use log::Level; use smallvec::SmallVec; @@ -59,13 +58,12 @@ use crate::platform::{ reveal_path_internal, xdg_desktop_portal::{Event as XDPEvent, XDPEventSource}, }, - scap_screen_capture::scap_screen_sources, }; use crate::{ AnyWindowHandle, Bounds, ClipboardItem, CursorStyle, DisplayId, FileDropEvent, Keystroke, LinuxKeyboardLayout, Modifiers, ModifiersChangedEvent, MouseButton, Pixels, Platform, PlatformDisplay, PlatformInput, PlatformKeyboardLayout, Point, RequestFrameOptions, - ScaledPixels, ScreenCaptureSource, ScrollDelta, Size, TouchPhase, WindowParams, X11Window, + ScaledPixels, ScrollDelta, Size, TouchPhase, WindowParams, X11Window, modifiers_from_xinput_info, point, px, }; @@ -1479,14 +1477,19 @@ impl LinuxClient for X11Client { )) } + #[cfg(feature = "screen-capture")] fn is_screen_capture_supported(&self) -> bool { true } + #[cfg(feature = "screen-capture")] fn screen_capture_sources( &self, - ) -> oneshot::Receiver>>> { - scap_screen_sources(&self.0.borrow().common.foreground_executor) + ) -> futures::channel::oneshot::Receiver>>> + { + crate::platform::scap_screen_capture::scap_screen_sources( + &self.0.borrow().common.foreground_executor, + ) } fn open_window( diff --git a/crates/gpui/src/platform/mac.rs b/crates/gpui/src/platform/mac.rs index cce65e4293..76d636b457 100644 --- a/crates/gpui/src/platform/mac.rs +++ b/crates/gpui/src/platform/mac.rs @@ -5,6 +5,8 @@ mod display; mod display_link; mod events; mod keyboard; + +#[cfg(feature = "screen-capture")] mod screen_capture; #[cfg(not(feature = "macos-blade"))] diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index 35bc99553d..d5ecd1c066 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -2,14 +2,14 @@ use super::{ BoolExt, MacKeyboardLayout, attributed_string::{NSAttributedString, NSMutableAttributedString}, events::key_to_native, - is_macos_version_at_least, renderer, screen_capture, + renderer, }; use crate::{ Action, AnyWindowHandle, BackgroundExecutor, ClipboardEntry, ClipboardItem, ClipboardString, CursorStyle, ForegroundExecutor, Image, ImageFormat, KeyContext, Keymap, MacDispatcher, MacDisplay, MacWindow, Menu, MenuItem, PathPromptOptions, Platform, PlatformDisplay, - PlatformKeyboardLayout, PlatformTextSystem, PlatformWindow, Result, ScreenCaptureSource, - SemanticVersion, Task, WindowAppearance, WindowParams, hash, + PlatformKeyboardLayout, PlatformTextSystem, PlatformWindow, Result, SemanticVersion, Task, + WindowAppearance, WindowParams, hash, }; use anyhow::{Context as _, anyhow}; use block::ConcreteBlock; @@ -22,8 +22,8 @@ use cocoa::{ }, base::{BOOL, NO, YES, id, nil, selector}, foundation::{ - NSArray, NSAutoreleasePool, NSBundle, NSData, NSInteger, NSOperatingSystemVersion, - NSProcessInfo, NSRange, NSString, NSUInteger, NSURL, + NSArray, NSAutoreleasePool, NSBundle, NSData, NSInteger, NSProcessInfo, NSRange, NSString, + NSUInteger, NSURL, }, }; use core_foundation::{ @@ -572,15 +572,17 @@ impl Platform for MacPlatform { .collect() } + #[cfg(feature = "screen-capture")] fn is_screen_capture_supported(&self) -> bool { - let min_version = NSOperatingSystemVersion::new(12, 3, 0); - is_macos_version_at_least(min_version) + let min_version = cocoa::foundation::NSOperatingSystemVersion::new(12, 3, 0); + super::is_macos_version_at_least(min_version) } + #[cfg(feature = "screen-capture")] fn screen_capture_sources( &self, - ) -> oneshot::Receiver>>> { - screen_capture::get_sources() + ) -> oneshot::Receiver>>> { + super::screen_capture::get_sources() } fn active_window(&self) -> Option { diff --git a/crates/gpui/src/platform/test/platform.rs b/crates/gpui/src/platform/test/platform.rs index eb3b6e9461..bef05399e5 100644 --- a/crates/gpui/src/platform/test/platform.rs +++ b/crates/gpui/src/platform/test/platform.rs @@ -263,10 +263,12 @@ impl Platform for TestPlatform { Some(self.active_display.clone()) } + #[cfg(feature = "screen-capture")] fn is_screen_capture_supported(&self) -> bool { true } + #[cfg(feature = "screen-capture")] fn screen_capture_sources( &self, ) -> oneshot::Receiver>>> { diff --git a/crates/gpui/src/platform/windows/platform.rs b/crates/gpui/src/platform/windows/platform.rs index 2dc3c11c09..a8212307ad 100644 --- a/crates/gpui/src/platform/windows/platform.rs +++ b/crates/gpui/src/platform/windows/platform.rs @@ -432,10 +432,12 @@ impl Platform for WindowsPlatform { WindowsDisplay::primary_monitor().map(|display| Rc::new(display) as Rc) } + #[cfg(feature = "screen-capture")] fn is_screen_capture_supported(&self) -> bool { false } + #[cfg(feature = "screen-capture")] fn screen_capture_sources( &self, ) -> oneshot::Receiver>>> {