From 035a80c7f6a572270d4b9a3b3f49c4803c567a5a Mon Sep 17 00:00:00 2001 From: Rudrabhoj Bhati Date: Wed, 29 Apr 2026 10:10:55 +0700 Subject: [PATCH 1/3] Permit FreeBSD targets at Linux-only cfg sites wayland-client, cctk, fontconfig, x11rb, native-dialog, notify-rust, the WindowingSystem enum and platform/linux all build and run on FreeBSD with the same code we already use for Linux. Replace `target_os = "linux"` with `any(target_os = "linux", target_os = "freebsd")` across app/ and crates/ so FreeBSD hits the Linux branches instead of the cross-platform no-op fallbacks. InputFlags::IUTF8 in local_tty/unix.rs stays Linux/macOS only because nix does not expose that termios flag on FreeBSD. Linux, macOS, and Windows builds are unaffected: every cfg already evaluated true on Linux and continues to. --- app/Cargo.toml | 4 +-- app/build.rs | 2 +- app/src/app_services/mod.rs | 6 ++-- app/src/auth/auth_view_modal.rs | 2 +- app/src/auth/login_slide.rs | 2 +- app/src/auth/paste_auth_token_modal.rs | 2 +- app/src/autoupdate/mod.rs | 10 +++--- app/src/code_review/code_review_view.rs | 2 +- app/src/crash_recovery.rs | 4 +-- app/src/crash_reporting/mod.rs | 6 ++-- app/src/crash_reporting/sentry_minidump.rs | 8 ++--- app/src/debug_dump.rs | 8 ++--- app/src/lib.rs | 12 +++---- app/src/quit_warning/mod.rs | 2 +- app/src/settings/cloud_preferences.rs | 2 +- .../cloud_preferences_syncer_tests.rs | 10 +++--- app/src/settings/gpu.rs | 2 +- app/src/settings/init.rs | 4 +-- app/src/settings/mod.rs | 4 +-- app/src/settings/select.rs | 2 +- app/src/settings_view/appearance_page.rs | 6 ++-- app/src/settings_view/features_page.rs | 24 +++++++------- app/src/settings_view/settings_page.rs | 2 +- app/src/system/memory_footprint.rs | 2 +- app/src/terminal/audible_bell/mod.rs | 2 +- app/src/terminal/local_tty/event_loop.rs | 2 +- app/src/terminal/local_tty/unix.rs | 4 +-- app/src/terminal/view.rs | 2 +- app/src/test_util/settings.rs | 2 +- app/src/uri/mod.rs | 12 +++---- app/src/util/file/external_editor/mod.rs | 8 ++--- app/src/util/traffic_lights.rs | 18 +++++------ app/src/workspace/action.rs | 4 +-- app/src/workspace/view.rs | 16 +++++----- app/src/workspace/view/crash_recovery.rs | 4 +-- crates/ai/src/index/file_outline/native.rs | 2 +- .../chunker/semantic.rs | 2 +- crates/channel_versions/src/overrides.rs | 2 +- .../channel_versions/src/overrides_tests.rs | 6 ++-- crates/computer_use/Cargo.toml | 2 +- crates/computer_use/build.rs | 2 +- crates/integration/src/builder.rs | 2 +- crates/integration/src/test.rs | 2 +- crates/integration/src/test/agent_mode.rs | 2 +- crates/integration/src/test/bootstrapping.rs | 2 +- crates/integration/src/test/ctrl_d.rs | 2 +- crates/integration/src/test/workspace.rs | 2 +- .../integration/tests/integration/ui_tests.rs | 2 +- crates/lsp/src/servers/rust.rs | 8 ++--- crates/settings/src/lib.rs | 2 +- crates/warp_cli/build.rs | 2 +- crates/warp_cli/src/lib.rs | 2 +- crates/warp_core/src/operating_system_info.rs | 2 +- crates/warp_core/src/paths.rs | 4 +-- crates/warp_core/src/paths_tests.rs | 14 ++++---- crates/warp_logging/src/native.rs | 2 +- crates/warpui/Cargo.toml | 6 ++-- crates/warpui/src/platform/mod.rs | 4 +-- crates/warpui/src/rendering/wgpu/mod.rs | 2 +- crates/warpui/src/windowing/mod.rs | 2 +- crates/warpui/src/windowing/winit/app.rs | 22 ++++++------- crates/warpui/src/windowing/winit/delegate.rs | 10 +++--- .../src/windowing/winit/event_loop/mod.rs | 18 +++++------ crates/warpui/src/windowing/winit/fonts.rs | 8 ++--- .../windowing/winit/linux/clipboard_tests.rs | 2 +- crates/warpui/src/windowing/winit/mod.rs | 6 ++-- .../src/windowing/winit/notifications/mod.rs | 2 +- crates/warpui/src/windowing/winit/window.rs | 32 +++++++++---------- crates/warpui_core/Cargo.toml | 2 +- crates/warpui_core/src/clipboard_utils.rs | 12 +++---- .../warpui_core/src/clipboard_utils_tests.rs | 14 ++++---- crates/warpui_core/src/core/app.rs | 2 +- crates/warpui_core/src/platform/app.rs | 6 ++-- crates/warpui_core/src/platform/menu.rs | 2 +- crates/warpui_core/src/platform/mod.rs | 2 +- .../src/ui_components/segmented_control.rs | 2 +- crates/warpui_core/src/windowing/mod.rs | 2 +- crates/warpui_extras/Cargo.toml | 2 +- .../warpui_extras/src/secure_storage/mod.rs | 4 +-- 79 files changed, 216 insertions(+), 216 deletions(-) diff --git a/app/Cargo.toml b/app/Cargo.toml index 937f0360..65f8eab6 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -348,11 +348,11 @@ nix = { workspace = true, features = [ "mman", ] } -[target.'cfg(any(target_os = "linux", target_os = "windows"))'.dependencies] +[target.'cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))'.dependencies] crash-handler = { version = "0.6.3", optional = true } minidumper = { version = "0.8.3", optional = true } -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies] freedesktop-desktop-entry = "0.5.0" x11rb.workspace = true zbus.workspace = true diff --git a/app/build.rs b/app/build.rs index 3ee49904..c8204bb8 100644 --- a/app/build.rs +++ b/app/build.rs @@ -18,7 +18,7 @@ use warp_util::path::app_target_dir; fn main() -> Result<()> { cfg_aliases! { - linux_or_windows: { any(target_os = "linux", windows) }, + linux_or_windows: { any(any(target_os = "linux", target_os = "freebsd"), windows) }, enable_crash_recovery: { linux_or_windows }, } diff --git a/app/src/app_services/mod.rs b/app/src/app_services/mod.rs index cb67e174..4b885d34 100644 --- a/app/src/app_services/mod.rs +++ b/app/src/app_services/mod.rs @@ -5,7 +5,7 @@ //! Finder such that the user can open a new Warp tab or window //! in a given directory. -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub mod linux; #[cfg(target_os = "macos")] mod mac; @@ -17,7 +17,7 @@ use warpui::AppContext; pub fn init(_ctx: &mut AppContext) { log::info!("Initializing app services"); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] linux::init(_ctx); #[cfg(target_os = "macos")] mac::init(); @@ -28,6 +28,6 @@ pub fn init(_ctx: &mut AppContext) { pub fn teardown(_ctx: &mut AppContext) { log::info!("Tearing down app services..."); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] linux::teardown(_ctx); } diff --git a/app/src/auth/auth_view_modal.rs b/app/src/auth/auth_view_modal.rs index 3a2ced99..0f473999 100644 --- a/app/src/auth/auth_view_modal.rs +++ b/app/src/auth/auth_view_modal.rs @@ -64,7 +64,7 @@ pub fn init(app: &mut AppContext) { // to solve it in a more general way later). In the meantime, we // add a basic ctrl+v binding for the auth view, since there is no // terminal to interact with yet. - #[cfg(any(target_os = "linux", target_os = "windows"))] + #[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] app.register_fixed_bindings([FixedBinding::new( "cmdorctrl-v", AuthViewAction::PasteAuthUrl, diff --git a/app/src/auth/login_slide.rs b/app/src/auth/login_slide.rs index 8528c6bd..f7e1cfc6 100644 --- a/app/src/auth/login_slide.rs +++ b/app/src/auth/login_slide.rs @@ -78,7 +78,7 @@ pub fn init(app: &mut AppContext) { ), ]); - #[cfg(any(target_os = "linux", target_os = "windows"))] + #[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] app.register_fixed_bindings([FixedBinding::new( "cmdorctrl-v", LoginSlideAction::PasteAuthUrl, diff --git a/app/src/auth/paste_auth_token_modal.rs b/app/src/auth/paste_auth_token_modal.rs index 6f5f69f1..b874efbc 100644 --- a/app/src/auth/paste_auth_token_modal.rs +++ b/app/src/auth/paste_auth_token_modal.rs @@ -63,7 +63,7 @@ pub fn init(app: &mut AppContext) { ), ]); - #[cfg(any(target_os = "linux", target_os = "windows"))] + #[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] app.register_fixed_bindings([FixedBinding::new( "cmdorctrl-v", PasteAuthTokenModalAction::PasteIntoEditor, diff --git a/app/src/autoupdate/mod.rs b/app/src/autoupdate/mod.rs index 875d62b8..52913946 100644 --- a/app/src/autoupdate/mod.rs +++ b/app/src/autoupdate/mod.rs @@ -1,6 +1,6 @@ mod changelog; mod channel_versions; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub mod linux; #[cfg(target_os = "macos")] mod mac; @@ -789,7 +789,7 @@ async fn download_update( cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { mac::download_update_and_cleanup(&version_info, &update_id, last_successful_update_id.as_deref(), server_api.http_client()).await - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { linux::download_update_and_cleanup(&version_info, &update_id, server_api.http_client()).await } else if #[cfg(windows)] { windows::download_update_and_cleanup(&version_info, &update_id, server_api.http_client()).await @@ -819,7 +819,7 @@ pub fn apply_update( // macOS applies the update during the download step. Windows does it during // `spawn_child_if_necessary`. In either case, simply continue relaunching the app. Ok(ReadyForRelaunch::Yes) - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { let AutoupdateStage::UpdateReady { update_id, .. } = &AutoupdateState::handle(_ctx).as_ref(_ctx).stage else { anyhow::bail!("Trying to apply an update without AutoupdateState being UpdateReady!"); }; @@ -996,7 +996,7 @@ pub fn spawn_child_if_necessary(app: &mut AppContext) { cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { let relaunch_status = mac::relaunch(); - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { let relaunch_status = linux::relaunch(); } else if #[cfg(windows)] { let relaunch_status = windows::relaunch(); @@ -1047,7 +1047,7 @@ pub fn remove_old_executable() -> Result<()> { cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { mac::remove_old_executable() - } else if #[cfg(any(target_os = "linux", windows))] { + } else if #[cfg(any(any(target_os = "linux", target_os = "freebsd"), windows))] { // Nothing to do on Linux or Windows; we don't leave anything behind to clean up after // a relaunch. Ok(()) diff --git a/app/src/code_review/code_review_view.rs b/app/src/code_review/code_review_view.rs index 11f834d4..e2619cc4 100644 --- a/app/src/code_review/code_review_view.rs +++ b/app/src/code_review/code_review_view.rs @@ -7765,7 +7765,7 @@ impl BackingView for CodeReviewView { AppContext::show_native_platform_modal(ctx, dialog); } else if cfg!(all( not(target_family = "wasm"), - any(target_os = "linux", target_os = "windows") + any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows") )) { // Find the workspace to show the Warp-native modal if let Some(workspace) = ctx diff --git a/app/src/crash_recovery.rs b/app/src/crash_recovery.rs index 524be1c1..8e0ffd43 100644 --- a/app/src/crash_recovery.rs +++ b/app/src/crash_recovery.rs @@ -295,7 +295,7 @@ fn choose_crash_recovery_mechanism( return None; } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { let force_x11 = settings::ForceX11::read_from_preferences(user_preferences); // Prioritize X11 crash recovery first. If the user has actively @@ -441,7 +441,7 @@ fn handle_parent_crash( warp_logging::on_parent_process_crash(); match recovery_mechanism { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] RecoveryMechanism::X11 => { let force_x11 = settings::ForceX11::read_from_preferences(user_preferences); if force_x11 != Some(true) { diff --git a/app/src/crash_reporting/mod.rs b/app/src/crash_reporting/mod.rs index 48fc8a27..d350f0bf 100644 --- a/app/src/crash_reporting/mod.rs +++ b/app/src/crash_reporting/mod.rs @@ -3,7 +3,7 @@ mod mac; #[cfg(linux_or_windows)] mod sentry_minidump; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] mod linux; use std::borrow::Cow; @@ -262,7 +262,7 @@ fn get_environment() -> Cow<'static, str> { cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { let operating_system = "mac"; - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { let operating_system = "linux"; } else if #[cfg(target_os = "windows")] { @@ -547,7 +547,7 @@ impl VirtualEnvironment { /// Detects the current virtual environment, if any. fn detect() -> Option { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { linux::get_virtualized_environment() } else { None diff --git a/app/src/crash_reporting/sentry_minidump.rs b/app/src/crash_reporting/sentry_minidump.rs index 1a424558..f5c0effb 100644 --- a/app/src/crash_reporting/sentry_minidump.rs +++ b/app/src/crash_reporting/sentry_minidump.rs @@ -306,7 +306,7 @@ impl MinidumpGuard { .context("Failed to attach crash signal handler")?; // Ensure that the crash server process can ptrace Warp. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] crash_handler.set_ptracer(Some(child.id())); let guard = MinidumpGuard { @@ -341,9 +341,9 @@ impl MinidumpGuard { /// Simulate a crash. pub fn crash(&self) { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] self.crash_handler.simulate_signal(libc::SIGSEGV as _); - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] self.crash_handler.simulate_exception(None); } } @@ -424,7 +424,7 @@ enum MinidumpCommand { /// already be in the minidump, but it's useful to surface prominently in Sentry. fn format_crash_details(crash_context: &CrashContext) -> Option { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { Some(format!("Killed by signal {} / {}", crash_context.siginfo.ssi_signo, crash_context.siginfo.ssi_code)) } else if #[cfg(target_os = "windows")] { Some(format!("Exception {}", crash_context.exception_code)) diff --git a/app/src/debug_dump.rs b/app/src/debug_dump.rs index 1308161b..6c1579dc 100644 --- a/app/src/debug_dump.rs +++ b/app/src/debug_dump.rs @@ -17,7 +17,7 @@ pub(crate) fn run() -> anyhow::Result<()> { println!("uname(1) output: {}", uname.trim_end()); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] println!( "Package type: {:?}", crate::autoupdate::linux::UpdateMethod::detect() @@ -36,7 +36,7 @@ pub(crate) fn run() -> anyhow::Result<()> { )); // Log some additional windowing system information on Linux. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { use winit::raw_window_handle::HasDisplayHandle as _; @@ -54,7 +54,7 @@ pub(crate) fn run() -> anyhow::Result<()> { } } - #[cfg(any(target_os = "linux", windows))] + #[cfg(any(any(target_os = "linux", target_os = "freebsd"), windows))] { use std::ops::Deref as _; @@ -90,7 +90,7 @@ pub(crate) fn run() -> anyhow::Result<()> { )); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { let lspci_info = collect_output_or_suggest_install("lspci"); println!("##################################################"); diff --git a/app/src/lib.rs b/app/src/lib.rs index 04dada41..9b3ee974 100644 --- a/app/src/lib.rs +++ b/app/src/lib.rs @@ -734,12 +734,12 @@ fn run_internal(mut launch_mode: LaunchMode) -> Result<()> { // Collect errors that occur in run_internal() before the Sentry client is initialized, // so they can be replayed to Sentry once it's ready. #[cfg_attr( - not(all(feature = "release_bundle", any(windows, target_os = "linux"))), + not(all(feature = "release_bundle", any(windows, any(target_os = "linux", target_os = "freebsd")))), expect(unused_mut) )] let mut pre_sentry_errors: Vec = Vec::new(); - #[cfg(all(feature = "release_bundle", target_os = "linux"))] + #[cfg(all(feature = "release_bundle", any(target_os = "linux", target_os = "freebsd")))] if let LaunchMode::App { .. } = launch_mode { match app_services::linux::pass_startup_args_to_existing_instance( launch_mode.args().as_ref(), @@ -805,7 +805,7 @@ fn run_internal(mut launch_mode: LaunchMode) -> Result<()> { // When the SettingsFile feature flag is enabled, public settings live in // the TOML-backed store. When disabled, they live in the platform-native // store (same backend as private). Use the correct one for pre-app reads. - #[cfg_attr(not(any(enable_crash_recovery, target_os = "linux")), expect(unused))] + #[cfg_attr(not(any(enable_crash_recovery, any(target_os = "linux", target_os = "freebsd"))), expect(unused))] let prefs_for_public_settings: &dyn warpui_extras::user_preferences::UserPreferences = if FeatureFlag::SettingsFile.is_enabled() { public_preferences.as_ref() @@ -854,7 +854,7 @@ fn run_internal(mut launch_mode: LaunchMode) -> Result<()> { app_builder.set_dock_menu_builder(|_| app_menus::dock_menu()); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { use crate::settings::ForceX11; use warpui::platform::linux::{self, AppBuilderExt}; @@ -979,7 +979,7 @@ fn initialize_app( cfg_if::cfg_if! { if #[cfg(feature = "integration_tests")] { warpui_extras::secure_storage::register_noop(&data_domain, ctx); - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { warpui_extras::secure_storage::register_with_fallback(&data_domain, warp_core::paths::state_dir(), ctx) } else if #[cfg(target_os = "windows")] { warpui_extras::secure_storage::register_with_dir(&data_domain, warp_core::paths::state_dir(), ctx) @@ -1915,7 +1915,7 @@ fn app_callbacks(is_integration_test: bool) -> warpui::platform::AppCallbacks { let general_settings = GeneralSettings::as_ref(ctx); // On Linux or Windows, if we're about to close the final window, we should quit the app instead. // On Mac, we do this conditionally based on a user setting. - let quit_on_last_window_closed = cfg!(any(target_os = "linux", windows)) + let quit_on_last_window_closed = cfg!(any(any(target_os = "linux", target_os = "freebsd"), windows)) || *general_settings.quit_on_last_window_closed; if ctx.window_ids().count() == 1 && quit_on_last_window_closed { log::info!("No windows left, terminating app"); diff --git a/app/src/quit_warning/mod.rs b/app/src/quit_warning/mod.rs index 30ffec69..d9fc9976 100644 --- a/app/src/quit_warning/mod.rs +++ b/app/src/quit_warning/mod.rs @@ -468,7 +468,7 @@ impl<'a> QuitWarningDialog<'a> { shown = true; } else if cfg!(all( not(target_family = "wasm"), - any(target_os = "linux", windows) + any(any(target_os = "linux", target_os = "freebsd"), windows) )) { // Find a window to show the Warp-native modal in. If there is no active window, use // one of the windows with a running process. diff --git a/app/src/settings/cloud_preferences.rs b/app/src/settings/cloud_preferences.rs index c1ae1c01..3a7b5e2a 100644 --- a/app/src/settings/cloud_preferences.rs +++ b/app/src/settings/cloud_preferences.rs @@ -68,7 +68,7 @@ impl Platform { return Self::Mac; } - if cfg!(all(not(target_family = "wasm"), target_os = "linux")) { + if cfg!(all(not(target_family = "wasm"), any(target_os = "linux", target_os = "freebsd"))) { return Self::Linux; } diff --git a/app/src/settings/cloud_preferences_syncer_tests.rs b/app/src/settings/cloud_preferences_syncer_tests.rs index 437930b3..5e96b858 100644 --- a/app/src/settings/cloud_preferences_syncer_tests.rs +++ b/app/src/settings/cloud_preferences_syncer_tests.rs @@ -332,7 +332,7 @@ fn test_sync_local_pref_to_cloud_after_initial_sync() { let mut server_api = mock_object_client_with_base_expectations(); let is_mac = cfg!(all(not(target_family = "wasm"), target_os = "macos")); - let is_linux = cfg!(all(not(target_family = "wasm"), target_os = "linux")); + let is_linux = cfg!(all(not(target_family = "wasm"), any(target_os = "linux", target_os = "freebsd"))); let mut all_client_ids = expect_sync_preferences_setting(&mut server_api); all_client_ids.append(&mut expect_sync_server_stored_privacy_settings( @@ -429,7 +429,7 @@ fn test_sync_local_pref_to_cloud_after_initial_sync() { .set_value(true, ctx); if cfg!(all(not(target_family = "wasm"), target_os = "macos")) { let _ = test_settings.mac_only_cloud_setting.set_value(true, ctx); - } else if cfg!(all(not(target_family = "wasm"), target_os = "linux")) { + } else if cfg!(all(not(target_family = "wasm"), any(target_os = "linux", target_os = "freebsd"))) { let _ = test_settings.linux_only_cloud_setting.set_value(true, ctx); } let _ = test_settings.non_cloud_setting.set_value(true, ctx); @@ -455,7 +455,7 @@ fn run_initial_sync_test(is_onboarded: bool) { let mut server_api = mock_object_client_with_base_expectations(); let is_mac = cfg!(all(not(target_family = "wasm"), target_os = "macos")); - let is_linux = cfg!(all(not(target_family = "wasm"), target_os = "linux")); + let is_linux = cfg!(all(not(target_family = "wasm"), any(target_os = "linux", target_os = "freebsd"))); let mut all_client_ids = expect_sync_preferences_setting(&mut server_api); @@ -748,7 +748,7 @@ fn test_sync_cloud_pref_to_local_on_initial_load_or_collab_update() { .await; let is_mac = cfg!(all(not(target_family = "wasm"), target_os = "macos")); - let is_linux = cfg!(all(not(target_family = "wasm"), target_os = "linux")); + let is_linux = cfg!(all(not(target_family = "wasm"), any(target_os = "linux", target_os = "freebsd"))); app.read(|ctx| { let settings = TestSettings::as_ref(ctx); assert!( @@ -856,7 +856,7 @@ fn test_cloud_preferences_setting_initial_load_skipped_when_setting_is_off() { }); let is_mac = cfg!(all(not(target_family = "wasm"), target_os = "macos")); - let is_linux = cfg!(all(not(target_family = "wasm"), target_os = "linux")); + let is_linux = cfg!(all(not(target_family = "wasm"), any(target_os = "linux", target_os = "freebsd"))); app.read(|ctx| { let settings = TestSettings::as_ref(ctx); assert!( diff --git a/app/src/settings/gpu.rs b/app/src/settings/gpu.rs index 8c66705a..ae6af043 100644 --- a/app/src/settings/gpu.rs +++ b/app/src/settings/gpu.rs @@ -6,7 +6,7 @@ define_settings_group!(GPUSettings, settings: [ type: bool, // Opt for the low power (integrated) GPU on Windows / Linux since discrete GPUs tend to be // more unstable. - default: cfg!(any(target_os = "linux", windows)), + default: cfg!(any(any(target_os = "linux", target_os = "freebsd"), windows)), supported_platforms: SupportedPlatforms::ALL, sync_to_cloud: SyncToCloud::Never, private: false, diff --git a/app/src/settings/init.rs b/app/src/settings/init.rs index f14ec26a..3572e8de 100644 --- a/app/src/settings/init.rs +++ b/app/src/settings/init.rs @@ -99,7 +99,7 @@ pub fn register_all_settings(ctx: &mut AppContext) { SameLinePromptBlockSettings::register(ctx); SemanticSelection::register(ctx); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] super::LinuxAppConfiguration::register(ctx); #[cfg(feature = "local_fs")] @@ -261,7 +261,7 @@ fn init_platform_native_preferences() -> user_preferences::Model { cfg_if::cfg_if! { if #[cfg(test)] { Box::::default() - } else if #[cfg(any(target_os = "linux", feature = "integration_tests"))] { + } else if #[cfg(any(any(target_os = "linux", target_os = "freebsd"), feature = "integration_tests"))] { match user_preferences::file_backed::FileBackedUserPreferences::new(super::user_preferences_file_path()) { Ok(prefs) => Box::new(prefs) as user_preferences::Model, Err(err) => { diff --git a/app/src/settings/mod.rs b/app/src/settings/mod.rs index 7c99c799..56fb9d73 100644 --- a/app/src/settings/mod.rs +++ b/app/src/settings/mod.rs @@ -18,7 +18,7 @@ mod init; pub mod initializer; mod input; mod input_mode; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] mod linux; pub mod macros; pub mod manager; @@ -52,7 +52,7 @@ pub use gpu::*; pub use init::*; pub use input::*; pub use input_mode::*; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub use linux::*; pub use native_preference::*; pub use onboarding::*; diff --git a/app/src/settings/select.rs b/app/src/settings/select.rs index 2342295c..6c23609b 100644 --- a/app/src/settings/select.rs +++ b/app/src/settings/select.rs @@ -91,7 +91,7 @@ impl SelectionSettings { /// lack this separate clipboard, and so we map middle-click to the normal clipboard on those /// platforms. pub fn read_for_middle_click_paste(&self, ctx: &mut AppContext) -> Option { - if cfg!(target_os = "linux") { + if cfg!(any(target_os = "linux", target_os = "freebsd")) { return self.maybe_read_from_linux_selection_clipboard(ctx); } (self diff --git a/app/src/settings_view/appearance_page.rs b/app/src/settings_view/appearance_page.rs index 4f6297b7..2d376e6e 100644 --- a/app/src/settings_view/appearance_page.rs +++ b/app/src/settings_view/appearance_page.rs @@ -1492,7 +1492,7 @@ impl AppearanceSettingsPageView { // If we're on a non-Linux platform, render the dropdown item in the // actual font. We currently don't do this on Linux because // pre-loading all of the fonts is too expensive. - if cfg!(not(target_os = "linux")) { + if cfg!(not(any(target_os = "linux", target_os = "freebsd"))) { if let Some(family_id) = ctx.font_cache().family_id_for_name(&font_name) { initial_dropdown_item = initial_dropdown_item.with_font_override(family_id); } @@ -1901,7 +1901,7 @@ impl AppearanceSettingsPageView { // If we're on a non-Linux platform, render the dropdown item in the // actual font. We currently don't do this on Linux because // pre-loading all of the fonts is too expensive. - if cfg!(not(target_os = "linux")) { + if cfg!(not(any(target_os = "linux", target_os = "freebsd"))) { if let Some(family_id) = family { dropdown = dropdown.with_font_override(*family_id) } @@ -1962,7 +1962,7 @@ impl AppearanceSettingsPageView { // If we're on a non-Linux platform, render the dropdown item in the // actual font. We currently don't do this on Linux because // pre-loading all of the fonts is too expensive. - if cfg!(not(target_os = "linux")) { + if cfg!(not(any(target_os = "linux", target_os = "freebsd"))) { if let Some(family_id) = family { dropdown = dropdown.with_font_override(*family_id) } diff --git a/app/src/settings_view/features_page.rs b/app/src/settings_view/features_page.rs index ffeab1ea..fec11df1 100644 --- a/app/src/settings_view/features_page.rs +++ b/app/src/settings_view/features_page.rs @@ -9,7 +9,7 @@ use warp_core::context_flag::ContextFlag; use warpui::platform::GraphicsBackend; use warpui::rendering::GPUPowerPreference; use warpui::{elements::DispatchEventResult, platform::Cursor}; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] use { crate::settings::ForceX11, crate::settings::LinuxAppConfiguration, warpui::platform::linux::windowing_system_is_customizable, @@ -519,7 +519,7 @@ pub fn init_actions_from_parent_view( ); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { if windowing_system_is_customizable(app) { toggle_binding_pairs.push( @@ -531,7 +531,7 @@ pub fn init_actions_from_parent_view( context, flags::ALLOW_NATIVE_WAYLAND, ) - .is_supported_on_current_platform(cfg!(target_os = "linux")), + .is_supported_on_current_platform(cfg!(any(target_os = "linux", target_os = "freebsd"))), ); } } @@ -631,7 +631,7 @@ pub enum FeaturesPageAction { ToggleAutosuggestions, ToggleConfirmCloseSession, ToggleShowChangelogAfterUpdate, - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] ToggleForceX11, ToggleAutosuggestionKeybindingHint, ToggleShowAutosuggestionIgnoreButton, @@ -1097,7 +1097,7 @@ impl FeaturesPageAction { value: to_string(selection_setting), } } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] Self::ToggleForceX11 => { let setting = *LinuxAppConfiguration::as_ref(ctx).force_x11.value(); TelemetryEvent::FeaturesPageAction { @@ -1237,7 +1237,7 @@ pub struct FeaturesPageView { window_id: WindowId, - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] force_x11_changed: bool, gpu_power_preference_changed: bool, graphics_backend_preference_changed: bool, @@ -1834,7 +1834,7 @@ impl TypedActionView for FeaturesPageView { .toggle_and_save_value(ctx)); }); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] ToggleForceX11 => { LinuxAppConfiguration::handle(ctx).update(ctx, |linux_app_configuration, ctx| { report_if_error!(linux_app_configuration.force_x11.toggle_and_save_value(ctx)); @@ -2415,7 +2415,7 @@ impl FeaturesPageView { mouse_scroll_input_editor, valid_mouse_scroll_multiplier: true, - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] force_x11_changed: false, gpu_power_preference_changed: false, graphics_backend_preference_changed: false, @@ -2740,7 +2740,7 @@ impl FeaturesPageView { system_widgets.push(Box::new(GraphicsBackendWidget::default())); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { if windowing_system_is_customizable(ctx) { system_widgets.push(Box::new(WindowSystemWidget::default())); @@ -4041,7 +4041,7 @@ impl SettingsPageMeta for FeaturesPageView { // notify on the [`DisplayCount`] model. However, no mechanism exists on Linux to trigger // that callback. As a workaround, we check for updates here where quake mode is // configured. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] DisplayCount::handle(ctx).update(ctx, |display_count, ctx| { display_count.0 = ctx.windows().display_count(); ctx.notify(); @@ -7107,14 +7107,14 @@ impl SettingsWidget for GPUWidget { } } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] #[derive(Default)] struct WindowSystemWidget { additional_info_link: MouseStateHandle, switch_state: SwitchStateHandle, } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] impl SettingsWidget for WindowSystemWidget { type View = FeaturesPageView; diff --git a/app/src/settings_view/settings_page.rs b/app/src/settings_view/settings_page.rs index 058dfd2c..19f94447 100644 --- a/app/src/settings_view/settings_page.rs +++ b/app/src/settings_view/settings_page.rs @@ -1539,7 +1539,7 @@ impl PageType { } } - #[cfg_attr(not(target_os = "linux"), allow(dead_code))] + #[cfg_attr(not(any(target_os = "linux", target_os = "freebsd")), allow(dead_code))] pub fn scroll_by(&self, delta: Pixels) { match self { PageType::Monolith { diff --git a/app/src/system/memory_footprint.rs b/app/src/system/memory_footprint.rs index d9bb5e6d..873c5343 100644 --- a/app/src/system/memory_footprint.rs +++ b/app/src/system/memory_footprint.rs @@ -97,7 +97,7 @@ mod platform { // Linux // --------------------------------------------------------------------------- -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] mod platform { /// Reads `/proc/self/status` and sums `VmRSS` + `VmSwap` to approximate /// the full memory footprint (resident + swapped). diff --git a/app/src/terminal/audible_bell/mod.rs b/app/src/terminal/audible_bell/mod.rs index e8413752..04a95078 100644 --- a/app/src/terminal/audible_bell/mod.rs +++ b/app/src/terminal/audible_bell/mod.rs @@ -3,7 +3,7 @@ use anyhow::Result; use warpui::{Entity, SingletonEntity}; -#[cfg_attr(target_os = "linux", path = "linux.rs")] +#[cfg_attr(any(target_os = "linux", target_os = "freebsd"), path = "linux.rs")] #[cfg_attr(target_os = "macos", path = "macos.rs")] #[cfg_attr(target_os = "windows", path = "windows.rs")] // TODO(WASM): Replace this with a functional implementation for the web. diff --git a/app/src/terminal/local_tty/event_loop.rs b/app/src/terminal/local_tty/event_loop.rs index 506f8fac..bdf72777 100644 --- a/app/src/terminal/local_tty/event_loop.rs +++ b/app/src/terminal/local_tty/event_loop.rs @@ -441,7 +441,7 @@ where // just loop back round for the inevitable `Exited` event. // This sucks, but checking the process is either racy or // blocking. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] if err.kind() == ErrorKind::Other { continue; } diff --git a/app/src/terminal/local_tty/unix.rs b/app/src/terminal/local_tty/unix.rs index 9b1c8eb0..6849fd76 100644 --- a/app/src/terminal/local_tty/unix.rs +++ b/app/src/terminal/local_tty/unix.rs @@ -401,7 +401,7 @@ fn spawn_command_in_pty( } // Detect isolation platform outside pre_exec, since detect() is not async-signal-safe. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] let is_isolated = warp_isolation_platform::detect().is_some(); unsafe { @@ -468,7 +468,7 @@ fn spawn_command_in_pty( } } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] if is_isolated { // If running in a sandbox on Linux, adjust the OOM score // to make the child process more likely to be killed than the parent process diff --git a/app/src/terminal/view.rs b/app/src/terminal/view.rs index 559c407c..15632f11 100644 --- a/app/src/terminal/view.rs +++ b/app/src/terminal/view.rs @@ -23143,7 +23143,7 @@ impl TerminalView { // On Linux, immediately mark the request permission status as accepted since there's no concept of // requesting desktop notification permissions. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { if let NotificationsDiscoveryBanner::Open { request_outcome, .. diff --git a/app/src/test_util/settings.rs b/app/src/test_util/settings.rs index 813aec0c..fd6f1c10 100644 --- a/app/src/test_util/settings.rs +++ b/app/src/test_util/settings.rs @@ -72,7 +72,7 @@ pub fn initialize_settings_for_tests_with_mode( KeysSettings::register(app); LigatureSettings::register(app); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { use crate::settings::LinuxAppConfiguration; LinuxAppConfiguration::register(app); diff --git a/app/src/uri/mod.rs b/app/src/uri/mod.rs index 700cb8db..d2269f44 100644 --- a/app/src/uri/mod.rs +++ b/app/src/uri/mod.rs @@ -454,7 +454,7 @@ impl UriHost { } /// When handling this URI action, determine which window(s) should be focused. - #[cfg_attr(not(target_os = "linux"), allow(dead_code))] + #[cfg_attr(not(any(target_os = "linux", target_os = "freebsd")), allow(dead_code))] fn window_behavior_hint(&self) -> WindowBehaviorHint { use WindowBehaviorHint as W; match self { @@ -498,7 +498,7 @@ impl Default for WindowBehaviorHint { impl WindowBehaviorHint { /// Perform the desired window focus behavior for the URI being handled. This may change the /// "primary window" if a new one has to be created. Return the new primary WindowId. - #[cfg_attr(not(target_os = "linux"), allow(dead_code))] + #[cfg_attr(not(any(target_os = "linux", target_os = "freebsd")), allow(dead_code))] fn resolve( self, primary_window_id: Option, @@ -546,7 +546,7 @@ enum WindowActivationFallbackBehavior { impl WindowActivationFallbackBehavior { /// Perform the desired window fallback behavior for the URI being handled. This may change the /// "primary window" if a new one has to be created. Return the new primary WindowId. - #[cfg_attr(not(target_os = "linux"), allow(dead_code))] + #[cfg_attr(not(any(target_os = "linux", target_os = "freebsd")), allow(dead_code))] fn resolve(self, primary_window_id: WindowId, ctx: &mut AppContext) -> Option { match self { WindowActivationFallbackBehavior::Notify { title, description } => { @@ -704,7 +704,7 @@ impl Action { } fn handle(&self, primary_window_id: Option, url: &Url, ctx: &mut AppContext) { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] let primary_window_id = self.window_behavior_hint().resolve(primary_window_id, ctx); match self { Self::NewTab | Self::NewWindow => { @@ -910,7 +910,7 @@ impl Action { } /// When handling this URI action, determine which window(s) should be focused. - #[cfg_attr(not(target_os = "linux"), allow(dead_code))] + #[cfg_attr(not(any(target_os = "linux", target_os = "freebsd")), allow(dead_code))] fn window_behavior_hint(&self) -> WindowBehaviorHint { use WindowBehaviorHint as W; match self { @@ -961,7 +961,7 @@ pub fn handle_incoming_uri(url: &Url, ctx: &mut AppContext) { match validate_custom_uri(url) { Ok(host) => { - #[cfg(any(target_os = "linux", windows))] + #[cfg(any(any(target_os = "linux", target_os = "freebsd"), windows))] let primary_window_id = host.window_behavior_hint().resolve(primary_window_id, ctx); host.handle(primary_window_id, url, ctx); } diff --git a/app/src/util/file/external_editor/mod.rs b/app/src/util/file/external_editor/mod.rs index 7fde89ee..dc1d8001 100644 --- a/app/src/util/file/external_editor/mod.rs +++ b/app/src/util/file/external_editor/mod.rs @@ -1,4 +1,4 @@ -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] mod linux; #[cfg(target_os = "macos")] mod mac; @@ -40,10 +40,10 @@ pub const SUPPORTED_EDITORS: &[Editor] = &[ Editor::Sublime3, #[cfg(target_os = "macos")] Editor::Sublime4, - #[cfg(any(target_os = "macos", target_os = "linux"))] + #[cfg(any(target_os = "macos", any(target_os = "linux", target_os = "freebsd")))] // Zed is available on macos and linux Editor::Zed, - #[cfg(any(target_os = "macos", target_os = "linux"))] + #[cfg(any(target_os = "macos", any(target_os = "linux", target_os = "freebsd")))] // Zed Preview is available on macos and linux Editor::ZedPreview, Editor::GoLand, @@ -311,7 +311,7 @@ pub fn open_file_path_with_editor( cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { mac::open_file_path_with_line_and_col(line_column_number, editor, &full_path, ctx); - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { linux::open_file_path_with_line_and_col(line_column_number, editor, &full_path, ctx); } else if #[cfg(windows)]{ windows::open_file_path_with_line_and_col(line_column_number, editor, &full_path, ctx); diff --git a/app/src/util/traffic_lights.rs b/app/src/util/traffic_lights.rs index 5de80e86..9c4001c7 100644 --- a/app/src/util/traffic_lights.rs +++ b/app/src/util/traffic_lights.rs @@ -7,7 +7,7 @@ #[cfg(windows)] pub mod windows; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] mod linux_only { pub(super) use crate::workspace::TOTAL_TAB_BAR_HEIGHT; pub(super) use pathfinder_color::ColorU; @@ -19,7 +19,7 @@ mod linux_only { }; } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] use linux_only::*; #[cfg(target_os = "windows")] @@ -54,7 +54,7 @@ use warpui::elements::MouseStateHandle; use warpui::platform::FullscreenState; use warpui::{AppContext, Element, WindowId}; -#[cfg(any(target_os = "windows", target_os = "linux"))] +#[cfg(any(target_os = "windows", any(target_os = "linux", target_os = "freebsd")))] const BUTTON_ICON_SIZE: f32 = 22.; pub fn traffic_light_data(ctx: &AppContext, window_id: WindowId) -> Option { @@ -73,7 +73,7 @@ pub fn traffic_light_data(ctx: &AppContext, window_id: WindowId) -> Option Box { - if !cfg!(target_os = "linux") { + if !cfg!(any(target_os = "linux", target_os = "freebsd")) { return Empty::new().finish(); } @@ -226,7 +226,7 @@ impl TrafficLightData { .finish() } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] fn render_linux_maximize_button_icon( fg_color: ColorU, fullscreen_state: FullscreenState, @@ -282,7 +282,7 @@ impl TrafficLightData { maximize_button_icon } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] fn render_button( mouse_state: MouseStateHandle, child: Box, @@ -442,7 +442,7 @@ impl TrafficLightData { }) } - #[cfg(all(not(target_os = "linux"), not(target_os = "windows")))] + #[cfg(all(not(any(target_os = "linux", target_os = "freebsd")), not(target_os = "windows")))] pub fn render( &self, _fullscreen_state: FullscreenState, diff --git a/app/src/workspace/action.rs b/app/src/workspace/action.rs index 3bfd52ed..e75f5c54 100644 --- a/app/src/workspace/action.rs +++ b/app/src/workspace/action.rs @@ -393,7 +393,7 @@ pub enum WorkspaceAction { AttemptLoginGatedAIUpgrade, /// Dismisses the Wayland crash recovery banner and opens a link to our docs page with more /// information. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] DismissWaylandCrashRecoveryBannerAndOpenLink, /// Open a new pane with its input in AI mode /// with query "Fix this" with error name and details from AI summary. @@ -959,7 +959,7 @@ impl WorkspaceAction { #[cfg(feature = "local_fs")] FileDeleted { .. } => false, // File deletion doesn't change workspace state OpenEnvironmentManagementPane => false, - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] DismissWaylandCrashRecoveryBannerAndOpenLink => false, #[cfg(target_family = "wasm")] OpenLinkOnDesktop(_) => false, diff --git a/app/src/workspace/view.rs b/app/src/workspace/view.rs index 6af9ef53..bbd3126e 100644 --- a/app/src/workspace/view.rs +++ b/app/src/workspace/view.rs @@ -678,7 +678,7 @@ pub enum WorkspaceBanner { AnonymousUserAuth, /// to display when recovering from a crash that may have been due to use /// of Wayland - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] WaylandCrashRecovery, /// to display when settings.toml has errors (parse failure or invalid values) InvalidSettings, @@ -695,7 +695,7 @@ impl WorkspaceBanner { Self::VersionDeprecated => false, Self::AnonymousUserAuth => false, Self::Reauth => true, - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] Self::WaylandCrashRecovery => true, Self::InvalidSettings => true, } @@ -10267,7 +10267,7 @@ impl Workspace { return false; } else if cfg!(all( not(target_family = "wasm"), - any(target_os = "linux", windows) + any(any(target_os = "linux", target_os = "freebsd"), windows) )) { self.show_native_modal(dialog, ctx); return false; @@ -18641,7 +18641,7 @@ impl Workspace { WorkspaceBanner::Reauth => { self.reauth_banner_dismissed = true; } - #[cfg(all(enable_crash_recovery, target_os = "linux"))] + #[cfg(all(enable_crash_recovery, any(target_os = "linux", target_os = "freebsd")))] WorkspaceBanner::WaylandCrashRecovery => { crash_recovery::dismiss_workspace_banner(ctx); } @@ -19249,7 +19249,7 @@ impl Workspace { .insert(flags::AUTOSUGGESTION_KEYBINDING_HINT_FLAG); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { let force_x11 = *crate::settings::LinuxAppConfiguration::as_ref(app) .force_x11 @@ -20820,7 +20820,7 @@ impl TypedActionView for Workspace { ) }); } - #[cfg(all(enable_crash_recovery, target_os = "linux"))] + #[cfg(all(enable_crash_recovery, any(target_os = "linux", target_os = "freebsd")))] DismissWaylandCrashRecoveryBannerAndOpenLink => { self.dismiss_workspace_banner(ctx, &WorkspaceBanner::WaylandCrashRecovery); ctx.open_url("https://docs.warp.dev/terminal/more-features/linux#native-wayland"); @@ -22904,10 +22904,10 @@ impl View for Workspace { stack.finish() }; - #[cfg_attr(not(any(windows, target_os = "linux")), allow(unused_mut))] + #[cfg_attr(not(any(windows, any(target_os = "linux", target_os = "freebsd"))), allow(unused_mut))] let mut event_handler = EventHandler::new(stack); - #[cfg(any(windows, target_os = "linux"))] + #[cfg(any(windows, any(target_os = "linux", target_os = "freebsd")))] { event_handler = event_handler.on_scroll_wheel(move |ctx, _app, delta, modifiers_state| { diff --git a/app/src/workspace/view/crash_recovery.rs b/app/src/workspace/view/crash_recovery.rs index a59fe7e8..5d669756 100644 --- a/app/src/workspace/view/crash_recovery.rs +++ b/app/src/workspace/view/crash_recovery.rs @@ -11,7 +11,7 @@ pub fn banner_metadata(ctx: &AppContext) -> Option { let recovery_mechanism = crash_recovery.should_notify_user_about_crash()?; match recovery_mechanism { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] RecoveryMechanism::X11 => Some(WorkspaceBannerFields { banner_type: super::WorkspaceBanner::WaylandCrashRecovery, severity: super::BannerSeverity::Warning, @@ -42,7 +42,7 @@ pub fn banner_metadata(ctx: &AppContext) -> Option { } } -#[cfg_attr(all(enable_crash_recovery, not(target_os = "linux")), allow(unused))] +#[cfg_attr(all(enable_crash_recovery, not(any(target_os = "linux", target_os = "freebsd"))), allow(unused))] pub fn dismiss_workspace_banner(ctx: &mut ViewContext) { CrashRecovery::handle(ctx).update(ctx, |crash_recovery, ctx| { crash_recovery.handle_user_acknowledged_crash(ctx); diff --git a/crates/ai/src/index/file_outline/native.rs b/crates/ai/src/index/file_outline/native.rs index 18f1ef6f..2af42b9f 100644 --- a/crates/ai/src/index/file_outline/native.rs +++ b/crates/ai/src/index/file_outline/native.rs @@ -267,7 +267,7 @@ fn parse_file_outline(path: &Path) -> anyhow::Result { // of the allocator). // // See: https://github.com/tree-sitter/tree-sitter/issues/3129 - #[cfg(all(target_os = "linux", target_env = "gnu", not(feature = "jemalloc")))] + #[cfg(all(any(target_os = "linux", target_os = "freebsd"), target_env = "gnu", not(feature = "jemalloc")))] unsafe { nix::libc::malloc_trim(0); } diff --git a/crates/ai/src/index/full_source_code_embedding/chunker/semantic.rs b/crates/ai/src/index/full_source_code_embedding/chunker/semantic.rs index 6958d660..7376a9c8 100644 --- a/crates/ai/src/index/full_source_code_embedding/chunker/semantic.rs +++ b/crates/ai/src/index/full_source_code_embedding/chunker/semantic.rs @@ -48,7 +48,7 @@ pub(super) fn chunk_code<'a>( // of the allocator). // // See: https://github.com/tree-sitter/tree-sitter/issues/3129 - #[cfg(all(target_os = "linux", target_env = "gnu", not(feature = "jemalloc")))] + #[cfg(all(any(target_os = "linux", target_os = "freebsd"), target_env = "gnu", not(feature = "jemalloc")))] unsafe { nix::libc::malloc_trim(0); } diff --git a/crates/channel_versions/src/overrides.rs b/crates/channel_versions/src/overrides.rs index b74f35b2..922b9fab 100644 --- a/crates/channel_versions/src/overrides.rs +++ b/crates/channel_versions/src/overrides.rs @@ -49,7 +49,7 @@ impl TargetOS { Some(TargetOS::Web) } else if cfg!(target_os = "macos") { Some(TargetOS::MacOS) - } else if cfg!(target_os = "linux") { + } else if cfg!(any(target_os = "linux", target_os = "freebsd")) { Some(TargetOS::Linux) } else if cfg!(target_os = "windows") { Some(TargetOS::Windows) diff --git a/crates/channel_versions/src/overrides_tests.rs b/crates/channel_versions/src/overrides_tests.rs index 6d83627d..370fd58e 100644 --- a/crates/channel_versions/src/overrides_tests.rs +++ b/crates/channel_versions/src/overrides_tests.rs @@ -8,7 +8,7 @@ use super::*; fn test_only_first_override_is_applied() { #[cfg(target_os = "macos")] let predicate = OverridePredicate::TargetOS(TargetOS::MacOS); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] let predicate = OverridePredicate::TargetOS(TargetOS::Linux); #[cfg(target_os = "windows")] let predicate = OverridePredicate::TargetOS(TargetOS::Windows); @@ -130,7 +130,7 @@ fn test_unknown_target_is_ignored() { fn test_cli_version_override_is_applied() { #[cfg(target_os = "macos")] let predicate = OverridePredicate::TargetOS(TargetOS::MacOS); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] let predicate = OverridePredicate::TargetOS(TargetOS::Linux); #[cfg(target_os = "windows")] let predicate = OverridePredicate::TargetOS(TargetOS::Windows); @@ -174,7 +174,7 @@ fn test_cli_version_override_is_applied() { fn test_cli_version_preserved_when_override_omits_it() { #[cfg(target_os = "macos")] let predicate = OverridePredicate::TargetOS(TargetOS::MacOS); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] let predicate = OverridePredicate::TargetOS(TargetOS::Linux); #[cfg(target_os = "windows")] let predicate = OverridePredicate::TargetOS(TargetOS::Windows); diff --git a/crates/computer_use/Cargo.toml b/crates/computer_use/Cargo.toml index 9dcea4c4..326cd6d9 100644 --- a/crates/computer_use/Cargo.toml +++ b/crates/computer_use/Cargo.toml @@ -36,7 +36,7 @@ objc2-core-graphics.workspace = true tempfile.workspace = true warpui.workspace = true -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies] ashpd.workspace = true futures.workspace = true image.workspace = true diff --git a/crates/computer_use/build.rs b/crates/computer_use/build.rs index bf2634d0..7cb9923a 100644 --- a/crates/computer_use/build.rs +++ b/crates/computer_use/build.rs @@ -3,7 +3,7 @@ use cfg_aliases::cfg_aliases; fn main() { cfg_aliases! { macos: { target_os = "macos" }, - linux: { target_os = "linux" }, + linux: { any(target_os = "linux", target_os = "freebsd") }, noop: { not(any(macos, linux, windows)) }, } } diff --git a/crates/integration/src/builder.rs b/crates/integration/src/builder.rs index 15df8060..e673a167 100644 --- a/crates/integration/src/builder.rs +++ b/crates/integration/src/builder.rs @@ -185,7 +185,7 @@ impl Builder { // printed out during shell initialization telling the user how to // use `sudo`. This can interfere with tests that make assertions // about the block list, so suppress the message. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] std::fs::File::create(dir.join(".sudo_as_admin_successful")) .expect("should not fail to create file in home directory"); diff --git a/crates/integration/src/test.rs b/crates/integration/src/test.rs index 024d8f74..c2d8999a 100644 --- a/crates/integration/src/test.rs +++ b/crates/integration/src/test.rs @@ -2174,7 +2174,7 @@ pub fn test_ctrl_tab_session_switching() -> Builder { // this test fails on linux at the step where the command pallete is expected to show. // The feature does work on linux though - there's some underlying issue with our integration // test here. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { return builder; } diff --git a/crates/integration/src/test/agent_mode.rs b/crates/integration/src/test/agent_mode.rs index eba9b09c..82deabbe 100644 --- a/crates/integration/src/test/agent_mode.rs +++ b/crates/integration/src/test/agent_mode.rs @@ -26,7 +26,7 @@ use warp_multi_agent_api as api; use warpui::{async_assert, integration::TestStep, text::SelectionType, Event, SingletonEntity}; cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { lazy_static! { /// Position directly to the left of the first user query. static ref START_OF_FIRST_BLOCK_POSITION: Vector2F = vec2f(17.0, 239.0); diff --git a/crates/integration/src/test/bootstrapping.rs b/crates/integration/src/test/bootstrapping.rs index df5d2c11..67080f29 100644 --- a/crates/integration/src/test/bootstrapping.rs +++ b/crates/integration/src/test/bootstrapping.rs @@ -91,7 +91,7 @@ pub fn test_paste_and_type_characters_before_bootstrap() -> Builder { // On Ubuntu (and possibly other Linux distros), a message is // printed out during shell initialization telling the user how to // use `sudo`. This interferes with our expected pty contents, so suppress the message. - if cfg!(target_os = "linux") { + if cfg!(any(target_os = "linux", target_os = "freebsd")) { std::fs::File::create(dir.join(".sudo_as_admin_successful")) .expect("should not fail to create file in home directory"); } diff --git a/crates/integration/src/test/ctrl_d.rs b/crates/integration/src/test/ctrl_d.rs index 7226175b..e41bcc66 100644 --- a/crates/integration/src/test/ctrl_d.rs +++ b/crates/integration/src/test/ctrl_d.rs @@ -101,7 +101,7 @@ pub fn test_ctrl_d_during_bootstrapping_exits_shell_upon_completion() -> Builder // is to exit upon completion. // However, this differs on Linux where the common behaviour is to // ignore ctrl-d (and the corresponding EOF) while bootstrapping. - let final_assertion = if cfg!(target_os = "linux") { + let final_assertion = if cfg!(any(target_os = "linux", target_os = "freebsd")) { assert_terminal_bootstrapped(0, 0) } else { // TODO: figure out what the right behaviour is on windows. diff --git a/crates/integration/src/test/workspace.rs b/crates/integration/src/test/workspace.rs index 375eae8e..5d09d8e0 100644 --- a/crates/integration/src/test/workspace.rs +++ b/crates/integration/src/test/workspace.rs @@ -148,7 +148,7 @@ pub fn test_focus_panes_on_hover() -> Builder { pub fn test_close_tab_with_long_running_process() -> Builder { new_builder() - .set_should_run_test(|| cfg!(target_os = "linux")) + .set_should_run_test(|| cfg!(any(target_os = "linux", target_os = "freebsd"))) .with_step(wait_until_bootstrapped_single_pane_for_tab(0)) .with_step( new_step_with_default_assertions("Open a new tab") diff --git a/crates/integration/tests/integration/ui_tests.rs b/crates/integration/tests/integration/ui_tests.rs index c9d74feb..98d10d59 100644 --- a/crates/integration/tests/integration/ui_tests.rs +++ b/crates/integration/tests/integration/ui_tests.rs @@ -296,7 +296,7 @@ integration_tests! { test_restored_ai_block_renders_mermaid_and_local_images, // Middle-click-paste is only implemented for Linux right now. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] test_middle_click_paste, test_agent_mode_pane_minimum_size, diff --git a/crates/lsp/src/servers/rust.rs b/crates/lsp/src/servers/rust.rs index d4dc3e8d..8583c797 100644 --- a/crates/lsp/src/servers/rust.rs +++ b/crates/lsp/src/servers/rust.rs @@ -26,11 +26,11 @@ fn asset_name() -> &'static str { { "rust-analyzer-x86_64-apple-darwin.gz" } - #[cfg(all(target_os = "linux", target_arch = "x86_64"))] + #[cfg(all(any(target_os = "linux", target_os = "freebsd"), target_arch = "x86_64"))] { "rust-analyzer-x86_64-unknown-linux-gnu.gz" } - #[cfg(all(target_os = "linux", target_arch = "aarch64"))] + #[cfg(all(any(target_os = "linux", target_os = "freebsd"), target_arch = "aarch64"))] { "rust-analyzer-aarch64-unknown-linux-gnu.gz" } @@ -45,8 +45,8 @@ fn asset_name() -> &'static str { #[cfg(not(any( all(target_os = "macos", target_arch = "aarch64"), all(target_os = "macos", target_arch = "x86_64"), - all(target_os = "linux", target_arch = "x86_64"), - all(target_os = "linux", target_arch = "aarch64"), + all(any(target_os = "linux", target_os = "freebsd"), target_arch = "x86_64"), + all(any(target_os = "linux", target_os = "freebsd"), target_arch = "aarch64"), all(target_os = "windows", target_arch = "x86_64"), all(target_os = "windows", target_arch = "aarch64"), )))] diff --git a/crates/settings/src/lib.rs b/crates/settings/src/lib.rs index 746125ac..8def1054 100644 --- a/crates/settings/src/lib.rs +++ b/crates/settings/src/lib.rs @@ -204,7 +204,7 @@ impl SupportedPlatforms { cfg!(all(not(target_family = "wasm"), target_os = "macos")) } SupportedPlatforms::LINUX => { - cfg!(all(not(target_family = "wasm"), target_os = "linux")) + cfg!(all(not(target_family = "wasm"), any(target_os = "linux", target_os = "freebsd"))) } SupportedPlatforms::WINDOWS => { cfg!(all(not(target_family = "wasm"), target_os = "windows")) diff --git a/crates/warp_cli/build.rs b/crates/warp_cli/build.rs index 8182a6be..664c8f3e 100644 --- a/crates/warp_cli/build.rs +++ b/crates/warp_cli/build.rs @@ -3,7 +3,7 @@ use cfg_aliases::cfg_aliases; fn main() { // This sets the same cfg aliases as the `warp` crate, used to gate crash-recovery flags. cfg_aliases! { - linux_or_windows: { any(target_os = "linux", windows) }, + linux_or_windows: { any(any(target_os = "linux", target_os = "freebsd"), windows) }, enable_crash_recovery: { linux_or_windows }, } } diff --git a/crates/warp_cli/src/lib.rs b/crates/warp_cli/src/lib.rs index 3ec4cce0..cf001e1a 100644 --- a/crates/warp_cli/src/lib.rs +++ b/crates/warp_cli/src/lib.rs @@ -599,7 +599,7 @@ pub struct TerminalServerArgs { #[derive(Debug, Copy, Clone, clap::ValueEnum)] pub enum RecoveryMechanism { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] #[value(name = "force-x11")] X11, #[value(name = "force-dedicated-gpu")] diff --git a/crates/warp_core/src/operating_system_info.rs b/crates/warp_core/src/operating_system_info.rs index 150106c2..53ec6731 100644 --- a/crates/warp_core/src/operating_system_info.rs +++ b/crates/warp_core/src/operating_system_info.rs @@ -131,7 +131,7 @@ pub enum OperatingSystemCategory { impl OperatingSystemCategory { #[cfg_attr(target_family = "wasm", allow(dead_code))] fn new() -> Option { - if cfg!(target_os = "linux") { + if cfg!(any(target_os = "linux", target_os = "freebsd")) { Some(OperatingSystemCategory::Linux) } else if cfg!(target_os = "macos") { Some(OperatingSystemCategory::Mac) diff --git a/crates/warp_core/src/paths.rs b/crates/warp_core/src/paths.rs index c2f928b2..8b2f88f1 100644 --- a/crates/warp_core/src/paths.rs +++ b/crates/warp_core/src/paths.rs @@ -237,7 +237,7 @@ fn project_dirs_for_app_id( data_profile: Option<&str>, ) -> Option { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { // Adjust the base application name so that we end up with // directories like "warp-terminal" and "warp-terminal-dev", to // match our Linux package name. @@ -319,7 +319,7 @@ pub fn bundled_resources_dir() -> Option { .join("Contents") .join("Resources") }) - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { std::env::current_exe() .ok() .and_then(|executable| std::fs::canonicalize(executable).ok()) diff --git a/crates/warp_core/src/paths_tests.rs b/crates/warp_core/src/paths_tests.rs index 91b445b6..c62a3916 100644 --- a/crates/warp_core/src/paths_tests.rs +++ b/crates/warp_core/src/paths_tests.rs @@ -9,7 +9,7 @@ fn test_data_dir_path() { cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { assert_eq!(data_dir(), home_dir.join(".warp-oss")); - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { assert_eq!(data_dir(), home_dir.join(".local/share/warp-oss")); } else if #[cfg(windows)] { assert_eq!(data_dir(), home_dir.join("AppData\\Roaming\\warp\\WarpOss\\data")); @@ -26,7 +26,7 @@ fn test_config_local_dir_path() { cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { assert_eq!(config_local_dir(), home_dir.join(".warp-oss")); - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { assert_eq!(config_local_dir(), home_dir.join(".config/warp-oss")); } else if #[cfg(windows)] { assert_eq!(config_local_dir(), home_dir.join("AppData\\Local\\warp\\WarpOss\\config")); @@ -69,7 +69,7 @@ fn test_cache_dir_path() { cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { assert_eq!(cache_dir(), home_dir.join("Library/Application Support/dev.warp.WarpOss")); - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { assert_eq!(cache_dir(), home_dir.join(".cache/warp-oss")); } else if #[cfg(windows)] { assert_eq!(cache_dir(), home_dir.join("AppData\\Local\\warp\\WarpOss\\cache")); @@ -86,7 +86,7 @@ fn test_state_dir_path() { // ChannelState, by default, is configured for Channel::Oss. if #[cfg(target_os = "macos")] { assert_eq!(state_dir(), home_dir.join("Library/Application Support/dev.warp.WarpOss")); - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { assert_eq!(state_dir(), home_dir.join(".local/state/warp-oss")); } else if #[cfg(windows)] { assert_eq!(state_dir(), home_dir.join("AppData\\Local\\warp\\WarpOss\\data")); @@ -103,7 +103,7 @@ fn test_project_path_for_warp_app_id() { cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { assert_eq!(project_dirs.project_path(), "dev.warp.Warp"); - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { assert_eq!(project_dirs.project_path(), "warp-terminal"); } else if #[cfg(windows)] { assert_eq!(project_dirs.project_path(), "warp\\Warp"); @@ -120,7 +120,7 @@ fn test_project_path_for_warp_dev_app_id() { cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { assert_eq!(project_dirs.project_path(), "dev.warp.WarpDev"); - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { assert_eq!(project_dirs.project_path(), "warp-terminal-dev"); } else if #[cfg(windows)] { assert_eq!(project_dirs.project_path(), "warp\\WarpDev"); @@ -137,7 +137,7 @@ fn test_project_path_for_oss_app_id() { cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { assert_eq!(project_dirs.project_path(), "dev.warp.WarpOss"); - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { assert_eq!(project_dirs.project_path(), "warp-oss"); } else if #[cfg(windows)] { assert_eq!(project_dirs.project_path(), "warp\\WarpOss"); diff --git a/crates/warp_logging/src/native.rs b/crates/warp_logging/src/native.rs index 43150d23..816c8de1 100644 --- a/crates/warp_logging/src/native.rs +++ b/crates/warp_logging/src/native.rs @@ -480,7 +480,7 @@ fn init_log_directory() -> Result { anyhow::anyhow!("could not locate home directory in order to create a log file") })? .join("Library/Logs/")) - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { Ok(warp_core::paths::state_dir()) } else if #[cfg(windows)] { Ok(warp_core::paths::state_dir().join(warp_core::paths::WARP_LOGS_DIR)) diff --git a/crates/warpui/Cargo.toml b/crates/warpui/Cargo.toml index 6830eb07..776f368f 100644 --- a/crates/warpui/Cargo.toml +++ b/crates/warpui/Cargo.toml @@ -113,7 +113,7 @@ web-sys.workspace = true workspace = true features = ["fragile-send-sync-non-atomic-wasm", "webgl"] -[target.'cfg(any(target_os = "linux", target_os = "windows"))'.dependencies] +[target.'cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))'.dependencies] arboard = { workspace = true, features = [ "wayland-data-control", "image-data", @@ -121,7 +121,7 @@ arboard = { workspace = true, features = [ native-dialog = "0.7.0" open = "5.0.0" -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies] blocking.workspace = true dirs.workspace = true fontconfig = { version = "0.8.0", features = ["dlopen"] } @@ -139,7 +139,7 @@ x11rb.workspace = true x11-dl = "2.21.0" zbus.workspace = true -[target.'cfg(target_os = "linux")'.dev-dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dev-dependencies] virtual-fs.workspace = true [target.'cfg(target_os = "windows")'.dependencies] diff --git a/crates/warpui/src/platform/mod.rs b/crates/warpui/src/platform/mod.rs index 8b866390..1e698de8 100644 --- a/crates/warpui/src/platform/mod.rs +++ b/crates/warpui/src/platform/mod.rs @@ -1,5 +1,5 @@ pub mod app; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub mod linux; #[cfg(target_os = "macos")] pub mod mac; @@ -14,7 +14,7 @@ pub mod current { cfg_if::cfg_if! { if #[cfg(target_family = "wasm")] { pub use super::wasm::*; - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { pub use super::linux::*; } else if #[cfg(target_os = "macos")] { pub use super::mac::*; diff --git a/crates/warpui/src/rendering/wgpu/mod.rs b/crates/warpui/src/rendering/wgpu/mod.rs index e4ed5db7..41cab965 100644 --- a/crates/warpui/src/rendering/wgpu/mod.rs +++ b/crates/warpui/src/rendering/wgpu/mod.rs @@ -78,7 +78,7 @@ pub fn init_wgpu_instance(display_handle: Box) { } instance_lock_guard.get_or_insert_with(|| { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { use crate::windowing::{winit::app::WINDOWING_SYSTEM, WindowingSystem}; // If the user hasn't enabled (and is making use of) native Wayland diff --git a/crates/warpui/src/windowing/mod.rs b/crates/warpui/src/windowing/mod.rs index abbab401..3e351f62 100644 --- a/crates/warpui/src/windowing/mod.rs +++ b/crates/warpui/src/windowing/mod.rs @@ -2,5 +2,5 @@ pub mod winit; pub use warpui_core::windowing::*; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub use winit::WindowingSystem; diff --git a/crates/warpui/src/windowing/winit/app.rs b/crates/warpui/src/windowing/winit/app.rs index 6b1cd839..2bfef447 100644 --- a/crates/warpui/src/windowing/winit/app.rs +++ b/crates/warpui/src/windowing/winit/app.rs @@ -15,10 +15,10 @@ use crate::notification::RequestPermissionsOutcome; use crate::platform::NotificationInfo; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] use std::sync::OnceLock; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub static WINDOWING_SYSTEM: OnceLock = OnceLock::new(); pub type RequestPermissionsCallback = @@ -65,9 +65,9 @@ pub enum CustomEvent { Clipboard(ClipboardEvent), SetCursorShape(platform::Cursor), ActiveCursorPositionUpdated, - #[cfg_attr(not(target_os = "linux"), allow(dead_code))] + #[cfg_attr(not(any(target_os = "linux", target_os = "freebsd")), allow(dead_code))] AboutToSleep, - #[cfg_attr(not(target_os = "linux"), allow(dead_code))] + #[cfg_attr(not(any(target_os = "linux", target_os = "freebsd")), allow(dead_code))] ResumedFromSleep, /// The application is connected to the internet. #[cfg_attr(any(target_os = "macos"), allow(dead_code))] @@ -115,7 +115,7 @@ pub enum ClipboardEvent { Paste(ClipboardContent), } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] #[derive(Debug, PartialEq)] pub enum WindowingSystem { X11, @@ -127,7 +127,7 @@ pub struct App { assets: Box, is_integration_test: bool, window_class: Option, - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] force_x11: bool, } @@ -142,7 +142,7 @@ impl App { assets, is_integration_test: test_driver.is_some(), window_class: None, - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] force_x11: false, } } @@ -154,7 +154,7 @@ impl App { self.window_class = Some(window_class); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] pub(crate) fn force_x11(&mut self, force_x11: bool) { self.force_x11 = force_x11; } @@ -168,13 +168,13 @@ impl App { assets, is_integration_test, window_class, - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] force_x11, } = self; let mut event_loop_builder = winit::event_loop::EventLoop::with_user_event(); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] if force_x11 { winit::platform::x11::EventLoopBuilderExtX11::with_x11(&mut event_loop_builder); } @@ -188,7 +188,7 @@ impl App { // Perform some platform-specific initialization. cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { super::linux::maybe_register_xlib_error_hook(&event_loop); super::linux::ensure_cursor_theme(); } else if #[cfg(target_family = "wasm")] { diff --git a/crates/warpui/src/windowing/winit/delegate.rs b/crates/warpui/src/windowing/winit/delegate.rs index 6acb5821..cd6d22b0 100644 --- a/crates/warpui/src/windowing/winit/delegate.rs +++ b/crates/warpui/src/windowing/winit/delegate.rs @@ -71,7 +71,7 @@ pub fn open_url_in_system(url: &str) { let _ = window.open_with_url_and_target(url, "_blank"); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { // Opening in WSL is complicated for a few reasons // 1. By default, wsl does not have an awareness of browsers installed in windows. @@ -125,7 +125,7 @@ pub fn open_url_in_system(url: &str) { } } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] fn use_wsl_browser() -> bool { static USE_WSL_BROWSER: OnceLock = OnceLock::new(); USE_WSL_BROWSER @@ -214,7 +214,7 @@ impl AppDelegate { cfg_if::cfg_if! { if #[cfg(target_family = "wasm")] { self.clipboard = Box::new(super::wasm::WebClipboard::new()); - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { match super::linux::LinuxClipboard::new() { Ok(clipboard) => self.clipboard = Box::new(clipboard), Err(err) => { @@ -251,7 +251,7 @@ impl platform::Delegate for AppDelegate { #[cfg(not(target_family = "wasm"))] fn system_theme(&self) -> platform::SystemTheme { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] match super::linux::get_system_theme() { Ok(system_theme) => { return system_theme; @@ -295,7 +295,7 @@ impl platform::Delegate for AppDelegate { fn open_file_path(&self, path: &Path) { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { let _ = command::blocking::Command::new("xdg-open") .arg(path) .spawn(); diff --git a/crates/warpui/src/windowing/winit/event_loop/mod.rs b/crates/warpui/src/windowing/winit/event_loop/mod.rs index d36bfbde..3d9d64da 100644 --- a/crates/warpui/src/windowing/winit/event_loop/mod.rs +++ b/crates/warpui/src/windowing/winit/event_loop/mod.rs @@ -6,7 +6,7 @@ mod drag_drop_tests; use std::collections::HashMap; use std::mem::ManuallyDrop; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] use crate::notification::RequestPermissionsOutcome; use futures_util::future::LocalBoxFuture; @@ -544,7 +544,7 @@ impl EventLoop { match evt { Event::NewEvents(StartCause::Init) => { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { let windowing_system = if winit::platform::x11::ActiveEventLoopExtX11::is_x11(window_target) { @@ -563,7 +563,7 @@ impl EventLoop { } // Start listening for various platform events. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { super::linux::watch_suspend_resume_changes( self.proxy.clone(), @@ -755,13 +755,13 @@ impl EventLoop { } } Event::UserEvent(CustomEvent::AboutToSleep) => { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] self.prepare_for_sleep_on_linux(window_target); self.callbacks.cpu_will_sleep(); } Event::UserEvent(CustomEvent::ResumedFromSleep) => { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] self.resume_from_sleep_on_linux(); self.callbacks.cpu_awakened(); @@ -987,7 +987,7 @@ impl EventLoop { let window = downcast_window(window.as_ref()); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] if crate::windowing::winit::linux::take_encountered_bad_match_from_dri3_fence_from_fd() { log::warn!("Encountered a DRI3FenceFromFd error, forcing use of the NVIDIA GPU and recreating resources..."); self.downrank_non_nvidia_vulkan_adapters = true; @@ -1409,7 +1409,7 @@ impl EventLoop { ) .await; - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { // On Linux, there is no concept of requesting notification permissions. This // logic is hard-coded to always return an outcome of "Accepted". @@ -1804,7 +1804,7 @@ impl EventLoop { /// /// To work around this, we drop all rendering resources pre-suspend, and /// re-create them post-resume. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] fn prepare_for_sleep_on_linux(&mut self, window_target: &ActiveEventLoop) { self.ui_app.update(|ctx| { for window_id in ctx.window_ids() { @@ -1822,7 +1822,7 @@ impl EventLoop { /// /// See the [`Self::prepare_for_sleep_on_linux`] documentation for more /// details. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] fn resume_from_sleep_on_linux(&mut self) { self.ui_app.update(|ctx| { for window_id in ctx.window_ids() { diff --git a/crates/warpui/src/windowing/winit/fonts.rs b/crates/warpui/src/windowing/winit/fonts.rs index bd8e1cc0..286c0893 100644 --- a/crates/warpui/src/windowing/winit/fonts.rs +++ b/crates/warpui/src/windowing/winit/fonts.rs @@ -4,7 +4,7 @@ mod str_index_map; mod swash_rasterizer; mod text_layout; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] mod linux; #[cfg(target_os = "windows")] @@ -60,7 +60,7 @@ struct FontFamily { fonts: Vec, } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] mod loader { use super::*; use crate::windowing::winit::fonts::linux::{Error, FontconfigLoader}; @@ -115,7 +115,7 @@ mod loader { } } -#[cfg(not(any(target_os = "linux", target_os = "windows")))] +#[cfg(not(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows")))] mod loader { use super::*; #[cfg(not(target_family = "wasm"))] @@ -159,7 +159,7 @@ fn load_font_family_from_bytes(name: &str, font_bytes: Vec>) -> Result>, /// This is a client for talking to the Xorg server directly instead of through winit. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] x11_manager: Option, display_handle: OwnedDisplayHandle, } @@ -106,7 +106,7 @@ impl WindowManager { windows: Default::default(), event_loop_proxy, os_window_manager_name: Default::default(), - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] x11_manager: match x11::X11Manager::new() { Ok(x11_manager) => Some(x11_manager), Err(err) => { @@ -125,7 +125,7 @@ impl WindowManager { /// space. All our app's windows must be on the same screen, and hence will have the same scale /// factor. For more in-depth explanation: /// https://github.com/warpdotdev/warp-internal/pull/8431#discussion_r1460629912 - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] fn get_x11_backing_scale_factor(&self) -> f32 { use crate::platform::WindowContext; @@ -283,7 +283,7 @@ impl platform::WindowManager for WindowManager { fn active_display_bounds(&self) -> RectF { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { self.x11_manager .as_ref() .and_then(|x11_manager| match x11_manager.get_active_monitor() { @@ -305,7 +305,7 @@ impl platform::WindowManager for WindowManager { fn active_display_id(&self) -> DisplayId { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { self.x11_manager .as_ref() .and_then(|x11_manager| match x11_manager.get_active_monitor() { @@ -330,7 +330,7 @@ impl platform::WindowManager for WindowManager { // never invalidates the cache. We need to drop down to X11 directly to ensure we read a // fresh value. cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { self.x11_manager .as_ref() .and_then(|x11_manager| x11_manager.list_monitor_bounds().ok()) @@ -347,7 +347,7 @@ impl platform::WindowManager for WindowManager { fn bounds_for_display_idx(&self, display_idx: DisplayIdx) -> Option { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { let idx = match display_idx { DisplayIdx::Primary => 0, DisplayIdx::External(idx) => idx + 1, @@ -392,7 +392,7 @@ impl platform::WindowManager for WindowManager { self.os_window_manager_name .get_or_init(|| { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { get_os_window_manager_name_internal(self.x11_manager.as_ref()) } else { None @@ -403,12 +403,12 @@ impl platform::WindowManager for WindowManager { } } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub fn get_os_window_manager_name() -> Option { get_os_window_manager_name_internal(x11::X11Manager::new().ok().as_ref()) } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] fn get_os_window_manager_name_internal(x11_manager: Option<&x11::X11Manager>) -> Option { super::linux::look_for_wayland_compositor() .or_else(|| x11_manager.and_then(|manager| manager.os_window_manager_name().ok())) @@ -416,7 +416,7 @@ fn get_os_window_manager_name_internal(x11_manager: Option<&x11::X11Manager>) -> fn is_tiling_window_manager(name: &str) -> bool { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { super::linux::is_tiling_window_manager(name) } else { let _ = name; @@ -614,7 +614,7 @@ struct Inner { window: Arc, #[cfg(windows)] is_cloaked: bool, - #[cfg_attr(not(target_os = "linux"), allow(dead_code))] + #[cfg_attr(not(any(target_os = "linux", target_os = "freebsd")), allow(dead_code))] gpu_power_preference: GPUPowerPreference, backend_preference: Option, rendering_resources: Option, @@ -838,7 +838,7 @@ impl Window { } /// Drops the window's renderer and all associated resources. - #[cfg_attr(not(target_os = "linux"), allow(dead_code))] + #[cfg_attr(not(any(target_os = "linux", target_os = "freebsd")), allow(dead_code))] pub fn drop_renderer(&self, display_handle: Box) { let mut inner = self.inner.borrow_mut(); let Some(inner) = inner.as_mut() else { @@ -855,7 +855,7 @@ impl Window { } /// Recreates the window's renderer and all associated resources. - #[cfg_attr(not(target_os = "linux"), allow(dead_code))] + #[cfg_attr(not(any(target_os = "linux", target_os = "freebsd")), allow(dead_code))] pub fn recreate_renderer(&self, downrank_non_nvidia_vulkan_adapters: bool) { let mut inner = self.inner.borrow_mut(); let Some(inner) = inner.as_mut() else { @@ -1338,7 +1338,7 @@ fn create_window( FullscreenState::Normal => {} } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] if let Some(window_class) = _window_class.as_deref() { use winit::platform::x11::{WindowAttributesExtX11, WindowType}; diff --git a/crates/warpui_core/Cargo.toml b/crates/warpui_core/Cargo.toml index 80401b41..3a1149ea 100644 --- a/crates/warpui_core/Cargo.toml +++ b/crates/warpui_core/Cargo.toml @@ -94,7 +94,7 @@ ctrlc.workspace = true font-kit.workspace = true tokio = { workspace = true, features = ["rt-multi-thread"] } -[target.'cfg(any(target_os = "linux", target_os = "windows"))'.dependencies] +[target.'cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))'.dependencies] arboard = { workspace = true, features = ["image-data"] } [target.'cfg(target_family = "wasm")'.dependencies] diff --git a/crates/warpui_core/src/clipboard_utils.rs b/crates/warpui_core/src/clipboard_utils.rs index 5c4c56e0..20c051b0 100644 --- a/crates/warpui_core/src/clipboard_utils.rs +++ b/crates/warpui_core/src/clipboard_utils.rs @@ -1,7 +1,7 @@ #[allow(unused_imports)] use crate::clipboard::{Clipboard, ClipboardContent}; -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] use {arboard, image::ImageEncoder}; use itertools::Itertools; @@ -19,7 +19,7 @@ pub const CLIPBOARD_IMAGE_MIME_TYPES: &[&str] = &[ ]; /// Minimum bytes needed for image format detection. -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] const MIN_IMAGE_HEADER_SIZE: usize = 8; /// Check if a string has an image file extension. @@ -270,7 +270,7 @@ pub fn strip_html_to_plain_text(html: &str) -> String { } /// Process clipboard image data, preserving original format or converting to PNG. -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] pub fn process_clipboard_image( arboard_image: &arboard::ImageData, filename: Option, @@ -295,7 +295,7 @@ pub fn process_clipboard_image( } /// Read image data from clipboard, checking for images before expensive filename extraction. -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] pub fn read_images_from_clipboard( clipboard: &mut arboard::Clipboard, html_content: &Option, @@ -326,7 +326,7 @@ pub fn read_images_from_clipboard( } /// Try to preserve original image format using infer crate for detection. -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] pub fn try_preserve_original_format( bytes: &[u8], filename: Option, @@ -353,7 +353,7 @@ pub fn try_preserve_original_format( } /// Converts RGBA bitmap data to PNG format, returns None on invalid dimensions/encoding. -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] pub fn convert_raw_bitmap_to_png( width: usize, height: usize, diff --git a/crates/warpui_core/src/clipboard_utils_tests.rs b/crates/warpui_core/src/clipboard_utils_tests.rs index a0504b40..b83c3882 100644 --- a/crates/warpui_core/src/clipboard_utils_tests.rs +++ b/crates/warpui_core/src/clipboard_utils_tests.rs @@ -5,7 +5,7 @@ use crate::clipboard::{ClipboardContent, ImageData}; // HELPER FUNCTIONS (shared across tests) // ============================================================================ -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] fn create_rgba_data(w: usize, h: usize) -> Vec { // Simple test pattern: red gradient (0..h) @@ -15,19 +15,19 @@ fn create_rgba_data(w: usize, h: usize) -> Vec { .collect() } -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] fn create_simple_png() -> Vec { // PNG header for 1x1 red pixel vec![0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A] // PNG signature } -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] fn create_simple_jpeg() -> Vec { // JPEG header vec![0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46] } -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] fn create_simple_gif() -> Vec { // GIF header let mut data = Vec::new(); @@ -36,7 +36,7 @@ fn create_simple_gif() -> Vec { data } -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] fn create_simple_webp() -> Vec { // WebP header let mut data = Vec::new(); @@ -47,7 +47,7 @@ fn create_simple_webp() -> Vec { data } -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] fn assert_valid_png(result: Option) { let image_data = result.expect("Should process image successfully"); assert_eq!(image_data.mime_type, "image/png"); @@ -187,7 +187,7 @@ fn test_extract_filename_from_clipboard_content() { // IMAGE PROCESSING TESTS (Linux/Windows platforms only) // ============================================================================ -#[cfg(any(target_os = "linux", target_os = "windows"))] +#[cfg(any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows"))] mod image_processing_tests { use super::*; diff --git a/crates/warpui_core/src/core/app.rs b/crates/warpui_core/src/core/app.rs index 70d99978..7c9f8ebf 100644 --- a/crates/warpui_core/src/core/app.rs +++ b/crates/warpui_core/src/core/app.rs @@ -2441,7 +2441,7 @@ impl AppContext { // window fullscreen state changes, so instead we're using a // resize event as a signal that the fullscreen state _may_ have // changed. - #[cfg(any(target_os = "linux", windows))] + #[cfg(any(any(target_os = "linux", target_os = "freebsd"), windows))] crate::windowing::WindowManager::handle(ctx).update(ctx, |manager, ctx| { manager.update_is_active_window_fullscreen(ctx); }); diff --git a/crates/warpui_core/src/platform/app.rs b/crates/warpui_core/src/platform/app.rs index 2e414212..0289be01 100644 --- a/crates/warpui_core/src/platform/app.rs +++ b/crates/warpui_core/src/platform/app.rs @@ -105,7 +105,7 @@ impl AppCallbackDispatcher { // click on/interact with a notification. // TODO(CORE-2322): implement desktop notifications on Windows #[cfg_attr( - any(target_os = "linux", target_os = "windows", target_family = "wasm"), + any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows", target_family = "wasm"), allow(dead_code) )] pub fn notification_clicked(&mut self, response: notification::NotificationResponse) { @@ -294,7 +294,7 @@ impl AppCallbackDispatcher { // application menus, so these never get called. // TODO(CORE-2691): implement native Windows OS app menus #[cfg_attr( - any(target_os = "linux", target_os = "windows", target_family = "wasm"), + any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows", target_family = "wasm"), allow(dead_code) )] impl AppCallbackDispatcher { @@ -316,7 +316,7 @@ impl AppCallbackDispatcher { // native platform modals on these platforms, so these never get called. // TODO(CORE-2323): implement native Windows OS modal #[cfg_attr( - any(target_os = "linux", target_os = "windows", target_family = "wasm"), + any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows", target_family = "wasm"), allow(dead_code) )] impl AppCallbackDispatcher { diff --git a/crates/warpui_core/src/platform/menu.rs b/crates/warpui_core/src/platform/menu.rs index 2a2e1352..65b395b9 100644 --- a/crates/warpui_core/src/platform/menu.rs +++ b/crates/warpui_core/src/platform/menu.rs @@ -84,7 +84,7 @@ pub struct MenuItemPropertyChanges { impl MenuItemPropertyChanges { /// Returns a struct that unconditionally sets all properties, to be used /// when initializing a menu item for the first time. - #[cfg_attr(target_os = "linux", allow(dead_code))] + #[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))] pub fn for_new_item(props: MenuItemProperties, submenu: Submenu) -> Self { Self { name: Some(props.name), diff --git a/crates/warpui_core/src/platform/mod.rs b/crates/warpui_core/src/platform/mod.rs index 20d33b2b..40ace9c9 100644 --- a/crates/warpui_core/src/platform/mod.rs +++ b/crates/warpui_core/src/platform/mod.rs @@ -669,7 +669,7 @@ impl OperatingSystem { cfg_if::cfg_if! { if #[cfg(target_family = "wasm")] { wasm::current_platform() - } else if #[cfg(target_os = "linux")] { + } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { OperatingSystem::Linux } else if #[cfg(target_os = "macos")] { OperatingSystem::Mac diff --git a/crates/warpui_core/src/ui_components/segmented_control.rs b/crates/warpui_core/src/ui_components/segmented_control.rs index 08509ea4..1840d86f 100644 --- a/crates/warpui_core/src/ui_components/segmented_control.rs +++ b/crates/warpui_core/src/ui_components/segmented_control.rs @@ -236,7 +236,7 @@ impl View for SegmentedControl { ); if let Some(label_config) = option_config.label.take() { - let font_size = if cfg!(any(windows, target_os = "linux")) { + let font_size = if cfg!(any(windows, any(target_os = "linux", target_os = "freebsd"))) { // Reduce the font size by one to avoid text being cut off on Windows and Linux. self.styles.font_size.unwrap_or(12.0) - 1.0 } else { diff --git a/crates/warpui_core/src/windowing/mod.rs b/crates/warpui_core/src/windowing/mod.rs index 5cfe0eee..555253ba 100644 --- a/crates/warpui_core/src/windowing/mod.rs +++ b/crates/warpui_core/src/windowing/mod.rs @@ -100,7 +100,7 @@ impl<'a> WindowCallbackDispatcher<'a> { // support application menus, so these never get called. // TODO(CORE-2691): implement native Windows OS app menus #[cfg_attr( - any(target_os = "linux", target_os = "windows", target_family = "wasm"), + any(any(target_os = "linux", target_os = "freebsd"), target_os = "windows", target_family = "wasm"), allow(dead_code) )] impl WindowCallbackDispatcher<'_> { diff --git a/crates/warpui_extras/Cargo.toml b/crates/warpui_extras/Cargo.toml index 2663701f..474dbfa0 100644 --- a/crates/warpui_extras/Cargo.toml +++ b/crates/warpui_extras/Cargo.toml @@ -35,7 +35,7 @@ cocoa = { workspace = true, optional = true } objc = { workspace = true, optional = true } security-framework = { version = "2.0.0", optional = true } -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies] ouroboros = { version = "0.18", optional = true } rand = "0.8.5" ring = "0.17.13" diff --git a/crates/warpui_extras/src/secure_storage/mod.rs b/crates/warpui_extras/src/secure_storage/mod.rs index 928d68e9..69e24127 100644 --- a/crates/warpui_extras/src/secure_storage/mod.rs +++ b/crates/warpui_extras/src/secure_storage/mod.rs @@ -6,7 +6,7 @@ #[cfg(not(target_family = "wasm"))] #[cfg_attr(target_os = "macos", path = "mac.rs")] -#[cfg_attr(target_os = "linux", path = "linux.rs")] +#[cfg_attr(any(target_os = "linux", target_os = "freebsd"), path = "linux.rs")] #[cfg_attr(target_os = "windows", path = "windows.rs")] mod imp; mod noop; @@ -60,7 +60,7 @@ pub fn register_noop(service_name: &str, ctx: &mut warpui::AppContext) { ctx.add_singleton_model(|_| -> Model { Box::new(noop::SecureStorage::new(service_name)) }); } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub fn register_with_fallback( service_name: &str, fallback_dir: std::path::PathBuf, From 3aceb2c7a6d6141024c0381ab5f4d6844fb86a92 Mon Sep 17 00:00:00 2001 From: Rudrabhoj Bhati Date: Wed, 29 Apr 2026 10:52:28 +0700 Subject: [PATCH 2/3] Address review feedback for FreeBSD cfg widening Three of the previous commit's widened cfg sites pulled FreeBSD into code paths that ship Linux-only artifacts or rely on Linux-only filesystems. Pull FreeBSD back out of those, with a real implementation where a portable one exists. `app/src/autoupdate/mod.rs`: revert the cfg widening. The Linux autoupdate path downloads AppImage and package-manager release assets that aren't published for FreeBSD; FreeBSD now falls through to the existing 'not implemented' arm. FreeBSD users update via pkg or source. `crates/lsp/src/servers/rust.rs`: keep FreeBSD detection working (`should_suggest_for_repo`, `is_installed_on_path`, `is_installed_in_data_dir` are OS-agnostic), but make `install` and `fetch_latest_server_metadata` early-return Err on FreeBSD with a message pointing the user at `rustup component add rust-analyzer` or `pkg install rust-analyzer`. The reason auto-download cannot work: warp installs rust-analyzer through `install_from_github`, which pulls from the `rust-lang/rust-analyzer` GitHub release page. That page publishes mac/linux/windows tarballs only; there is no FreeBSD asset to download. The rustup distribution channel (`static.rust-lang.org/dist/`) does build a FreeBSD rust-analyzer as part of the toolchain, and the FreeBSD ports tree ships one as `devel/rust-analyzer`, so either install lands the binary on PATH where warp finds it. `app/src/system/memory_footprint.rs`: split FreeBSD into its own `mod platform` that calls `getrusage(RUSAGE_SELF)` and reports `ru_maxrss`, instead of pretending `/proc/self/status` exists. linprocfs is optional on FreeBSD and almost never mounted; the previous widened cfg would have made the function silently return 0. --- app/src/autoupdate/mod.rs | 10 +++--- app/src/system/memory_footprint.rs | 33 +++++++++++++++++- crates/lsp/src/servers/rust.rs | 56 +++++++++++++++++++++--------- 3 files changed, 77 insertions(+), 22 deletions(-) diff --git a/app/src/autoupdate/mod.rs b/app/src/autoupdate/mod.rs index 52913946..875d62b8 100644 --- a/app/src/autoupdate/mod.rs +++ b/app/src/autoupdate/mod.rs @@ -1,6 +1,6 @@ mod changelog; mod channel_versions; -#[cfg(any(target_os = "linux", target_os = "freebsd"))] +#[cfg(target_os = "linux")] pub mod linux; #[cfg(target_os = "macos")] mod mac; @@ -789,7 +789,7 @@ async fn download_update( cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { mac::download_update_and_cleanup(&version_info, &update_id, last_successful_update_id.as_deref(), server_api.http_client()).await - } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { + } else if #[cfg(target_os = "linux")] { linux::download_update_and_cleanup(&version_info, &update_id, server_api.http_client()).await } else if #[cfg(windows)] { windows::download_update_and_cleanup(&version_info, &update_id, server_api.http_client()).await @@ -819,7 +819,7 @@ pub fn apply_update( // macOS applies the update during the download step. Windows does it during // `spawn_child_if_necessary`. In either case, simply continue relaunching the app. Ok(ReadyForRelaunch::Yes) - } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { + } else if #[cfg(target_os = "linux")] { let AutoupdateStage::UpdateReady { update_id, .. } = &AutoupdateState::handle(_ctx).as_ref(_ctx).stage else { anyhow::bail!("Trying to apply an update without AutoupdateState being UpdateReady!"); }; @@ -996,7 +996,7 @@ pub fn spawn_child_if_necessary(app: &mut AppContext) { cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { let relaunch_status = mac::relaunch(); - } else if #[cfg(any(target_os = "linux", target_os = "freebsd"))] { + } else if #[cfg(target_os = "linux")] { let relaunch_status = linux::relaunch(); } else if #[cfg(windows)] { let relaunch_status = windows::relaunch(); @@ -1047,7 +1047,7 @@ pub fn remove_old_executable() -> Result<()> { cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { mac::remove_old_executable() - } else if #[cfg(any(any(target_os = "linux", target_os = "freebsd"), windows))] { + } else if #[cfg(any(target_os = "linux", windows))] { // Nothing to do on Linux or Windows; we don't leave anything behind to clean up after // a relaunch. Ok(()) diff --git a/app/src/system/memory_footprint.rs b/app/src/system/memory_footprint.rs index 873c5343..e881b692 100644 --- a/app/src/system/memory_footprint.rs +++ b/app/src/system/memory_footprint.rs @@ -97,7 +97,7 @@ mod platform { // Linux // --------------------------------------------------------------------------- -#[cfg(any(target_os = "linux", target_os = "freebsd"))] +#[cfg(target_os = "linux")] mod platform { /// Reads `/proc/self/status` and sums `VmRSS` + `VmSwap` to approximate /// the full memory footprint (resident + swapped). @@ -151,6 +151,37 @@ mod platform { } } +// --------------------------------------------------------------------------- +// FreeBSD +// --------------------------------------------------------------------------- + +#[cfg(target_os = "freebsd")] +mod platform { + /// FreeBSD has no `/proc/self/status` by default (linprocfs is optional and + /// rarely mounted), so we use `getrusage(RUSAGE_SELF)`. `ru_maxrss` is + /// reported in kilobytes and represents the maximum resident set size, not + /// the current value, but it's the closest portable signal we have without + /// pulling in `kvm`/`sysctl(KERN_PROC_PID)` plumbing for one telemetry + /// number. + pub fn memory_footprint_bytes() -> u64 { + let mut usage: libc::rusage = unsafe { std::mem::zeroed() }; + if unsafe { libc::getrusage(libc::RUSAGE_SELF, &mut usage) } != 0 { + return 0; + } + (usage.ru_maxrss as u64).saturating_mul(1024) + } + + pub fn memory_breakdown() -> serde_json::Value { + let mut usage: libc::rusage = unsafe { std::mem::zeroed() }; + if unsafe { libc::getrusage(libc::RUSAGE_SELF, &mut usage) } != 0 { + return serde_json::json!({}); + } + serde_json::json!({ + "ru_maxrss": (usage.ru_maxrss as u64).saturating_mul(1024), + }) + } +} + // --------------------------------------------------------------------------- // Windows // --------------------------------------------------------------------------- diff --git a/crates/lsp/src/servers/rust.rs b/crates/lsp/src/servers/rust.rs index 8583c797..4126a8b8 100644 --- a/crates/lsp/src/servers/rust.rs +++ b/crates/lsp/src/servers/rust.rs @@ -26,11 +26,11 @@ fn asset_name() -> &'static str { { "rust-analyzer-x86_64-apple-darwin.gz" } - #[cfg(all(any(target_os = "linux", target_os = "freebsd"), target_arch = "x86_64"))] + #[cfg(all(target_os = "linux", target_arch = "x86_64"))] { "rust-analyzer-x86_64-unknown-linux-gnu.gz" } - #[cfg(all(any(target_os = "linux", target_os = "freebsd"), target_arch = "aarch64"))] + #[cfg(all(target_os = "linux", target_arch = "aarch64"))] { "rust-analyzer-aarch64-unknown-linux-gnu.gz" } @@ -45,8 +45,8 @@ fn asset_name() -> &'static str { #[cfg(not(any( all(target_os = "macos", target_arch = "aarch64"), all(target_os = "macos", target_arch = "x86_64"), - all(any(target_os = "linux", target_os = "freebsd"), target_arch = "x86_64"), - all(any(target_os = "linux", target_os = "freebsd"), target_arch = "aarch64"), + all(target_os = "linux", target_arch = "x86_64"), + all(target_os = "linux", target_arch = "aarch64"), all(target_os = "windows", target_arch = "x86_64"), all(target_os = "windows", target_arch = "aarch64"), )))] @@ -136,21 +136,45 @@ impl LanguageServerCandidate for RustAnalyzerCandidate { metadata: LanguageServerMetadata, _executor: &CommandBuilder, ) -> anyhow::Result<()> { - let asset_kind = AssetKind::from_filename(asset_name()).ok_or_else(|| { - anyhow::anyhow!("Unsupported archive format for asset: {}", asset_name()) - })?; - install_from_github(&self.client, &metadata, SERVER_NAME, asset_kind, None).await?; - Ok(()) + #[cfg(target_os = "freebsd")] + { + let _ = (&metadata, &self.client); + anyhow::bail!( + "rust-analyzer is not auto-installable on FreeBSD: upstream \ + GitHub releases publish no FreeBSD asset. Install it via \ + `rustup component add rust-analyzer` or `pkg install \ + rust-analyzer` and warp will pick it up off PATH." + ); + } + #[cfg(not(target_os = "freebsd"))] + { + let asset_kind = AssetKind::from_filename(asset_name()).ok_or_else(|| { + anyhow::anyhow!("Unsupported archive format for asset: {}", asset_name()) + })?; + install_from_github(&self.client, &metadata, SERVER_NAME, asset_kind, None).await?; + Ok(()) + } } async fn fetch_latest_server_metadata(&self) -> anyhow::Result { - fetch_latest_metadata_from_github( - &self.client, - "rust-lang", - "rust-analyzer", - Some(asset_name()), - ) - .await + #[cfg(target_os = "freebsd")] + { + let _ = &self.client; + anyhow::bail!( + "rust-analyzer release metadata is unavailable on FreeBSD: \ + upstream GitHub releases publish no FreeBSD asset." + ); + } + #[cfg(not(target_os = "freebsd"))] + { + fetch_latest_metadata_from_github( + &self.client, + "rust-lang", + "rust-analyzer", + Some(asset_name()), + ) + .await + } } } From 91890721c85202a5d0ba1c0ade37d2abe4e7cbfd Mon Sep 17 00:00:00 2001 From: Rudrabhoj Bhati Date: Wed, 29 Apr 2026 11:54:24 +0700 Subject: [PATCH 3/3] Stop calling autoupdate::linux from debug_dump on FreeBSD `debug_dump.rs` prints `Package type:` from `crate::autoupdate::linux::UpdateMethod::detect()`. The previous commit reverted `autoupdate` back to Linux-only so the `linux` submodule no longer exists on FreeBSD, but the call site here was widened to `any(linux, freebsd)`. That breaks the FreeBSD build. Narrow the cfg back to Linux-only at the call site. FreeBSD has no package-type detection to report; the line is just a debug-dump nicety, so dropping it on FreeBSD is fine. --- app/src/debug_dump.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/debug_dump.rs b/app/src/debug_dump.rs index 6c1579dc..63c21edf 100644 --- a/app/src/debug_dump.rs +++ b/app/src/debug_dump.rs @@ -17,7 +17,7 @@ pub(crate) fn run() -> anyhow::Result<()> { println!("uname(1) output: {}", uname.trim_end()); } - #[cfg(any(target_os = "linux", target_os = "freebsd"))] + #[cfg(target_os = "linux")] println!( "Package type: {:?}", crate::autoupdate::linux::UpdateMethod::detect()