Add initial FreeBSD support (#20480)

This PR adds initial support for FreeBSD
(https://github.com/zed-industries/zed/issues/15309). While there is
still work left to be done, it seems to be usable. As discussed by
@syobocat (https://github.com/zed-industries/zed/discussions/10247), the
changes were just adding ```target_os = "freebsd"``` to wherever it
checks if the OS is Linux.


![image](https://github.com/user-attachments/assets/80ea5b29-047f-4cbd-8263-42e5fa6c94b7)

Needs to be build with ```RUSTFLAGS="-C link-dead-code"```

Known Issues:
- There's an issue in ```crates/project/src/environment.rs``` where a
command fails because ```/bin/sh``` on FreeBSD doesn't support the
```-l``` option.

![image](https://github.com/user-attachments/assets/c3c38633-160f-4f47-8840-e3da67f6ebc8)
- The file/folder choosers provided by the ```ashpd``` crate don't work
on FreeBSD (at least with KDE). This isn't that bad since a fallback
dialog is used.

![image](https://github.com/user-attachments/assets/29373006-1eb9-4ed0-bd52-2d0047fab418)
 - Moving to trash won't work.
- Numerous tests fail (when running on FreeBSD). While I haven't looked
into this much, it appears that the corresponding features seem to work
fine.

Release Notes:

- Added initial support for FreeBSD
This commit is contained in:
Caleb Heydon 2024-11-11 12:39:05 -05:00 committed by GitHub
parent b5da1198f5
commit a47759fd03
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 139 additions and 96 deletions

View file

@ -4,14 +4,17 @@
mod app_menu;
mod keystroke;
#[cfg(target_os = "linux")]
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
mod linux;
#[cfg(target_os = "macos")]
mod mac;
#[cfg(any(
all(target_os = "linux", any(feature = "x11", feature = "wayland")),
all(
any(target_os = "linux", target_os = "freebsd"),
any(feature = "x11", feature = "wayland")
),
target_os = "windows",
feature = "macos-blade"
))]
@ -57,7 +60,7 @@ use uuid::Uuid;
pub use app_menu::*;
pub use keystroke::*;
#[cfg(target_os = "linux")]
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
pub(crate) use linux::*;
#[cfg(target_os = "macos")]
pub(crate) use mac::*;
@ -72,7 +75,7 @@ pub(crate) fn current_platform(headless: bool) -> Rc<dyn Platform> {
Rc::new(MacPlatform::new(headless))
}
#[cfg(target_os = "linux")]
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
pub(crate) fn current_platform(headless: bool) -> Rc<dyn Platform> {
if headless {
return Rc::new(HeadlessClient::new());
@ -92,7 +95,7 @@ pub(crate) fn current_platform(headless: bool) -> Rc<dyn Platform> {
/// Return which compositor we're guessing we'll use.
/// Does not attempt to connect to the given compositor
#[cfg(target_os = "linux")]
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
#[inline]
pub fn guess_compositor() -> &'static str {
if std::env::var_os("ZED_HEADLESS").is_some() {
@ -192,10 +195,10 @@ pub(crate) trait Platform: 'static {
fn set_cursor_style(&self, style: CursorStyle);
fn should_auto_hide_scrollbars(&self) -> bool;
#[cfg(target_os = "linux")]
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
fn write_to_primary(&self, item: ClipboardItem);
fn write_to_clipboard(&self, item: ClipboardItem);
#[cfg(target_os = "linux")]
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
fn read_from_primary(&self) -> Option<ClipboardItem>;
fn read_from_clipboard(&self) -> Option<ClipboardItem>;
@ -508,7 +511,10 @@ pub(crate) enum AtlasKey {
impl AtlasKey {
#[cfg_attr(
all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))),
all(
any(target_os = "linux", target_os = "freebsd"),
not(any(feature = "x11", feature = "wayland"))
),
allow(dead_code)
)]
pub(crate) fn texture_kind(&self) -> AtlasTextureKind {
@ -572,7 +578,10 @@ pub(crate) struct AtlasTextureId {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
#[cfg_attr(
all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))),
all(
any(target_os = "linux", target_os = "freebsd"),
not(any(feature = "x11", feature = "wayland"))
),
allow(dead_code)
)]
pub(crate) enum AtlasTextureKind {
@ -603,7 +612,10 @@ pub(crate) struct PlatformInputHandler {
}
#[cfg_attr(
all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))),
all(
any(target_os = "linux", target_os = "freebsd"),
not(any(feature = "x11", feature = "wayland"))
),
allow(dead_code)
)]
impl PlatformInputHandler {
@ -625,7 +637,7 @@ impl PlatformInputHandler {
.flatten()
}
#[cfg_attr(target_os = "linux", allow(dead_code))]
#[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))]
fn text_for_range(&mut self, range_utf16: Range<usize>) -> Option<String> {
self.cx
.update(|cx| self.handler.text_for_range(range_utf16, cx))
@ -814,7 +826,10 @@ pub struct WindowOptions {
/// The variables that can be configured when creating a new window
#[derive(Debug)]
#[cfg_attr(
all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))),
all(
any(target_os = "linux", target_os = "freebsd"),
not(any(feature = "x11", feature = "wayland"))
),
allow(dead_code)
)]
pub(crate) struct WindowParams {
@ -825,17 +840,17 @@ pub(crate) struct WindowParams {
pub titlebar: Option<TitlebarOptions>,
/// The kind of window to create
#[cfg_attr(target_os = "linux", allow(dead_code))]
#[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))]
pub kind: WindowKind,
/// Whether the window should be movable by the user
#[cfg_attr(target_os = "linux", allow(dead_code))]
#[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))]
pub is_movable: bool,
#[cfg_attr(target_os = "linux", allow(dead_code))]
#[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))]
pub focus: bool,
#[cfg_attr(target_os = "linux", allow(dead_code))]
#[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))]
pub show: bool,
#[cfg_attr(feature = "wayland", allow(dead_code))]
@ -1341,7 +1356,7 @@ impl ClipboardString {
.and_then(|m| serde_json::from_str(m).ok())
}
#[cfg_attr(target_os = "linux", allow(dead_code))]
#[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))]
pub(crate) fn text_hash(text: &str) -> u64 {
let mut hasher = SeaHasher::new();
text.hash(&mut hasher);