From e09657e263d563e9bfc776f2dcfe2d13dba13781 Mon Sep 17 00:00:00 2001 From: -k Date: Thu, 12 Jun 2025 21:15:11 -0400 Subject: [PATCH] Add FreeBSD support Following https://github.com/cryptocode/ghostty/commit/7aeadb06ee5c38c440ac86b975d713a8ccfa3e0b --- src/Command.zig | 2 +- src/apprt/gtk/App.zig | 4 ++-- src/config/Config.zig | 4 ++-- src/input/keycodes.zig | 2 +- src/os/desktop.zig | 3 +++ src/os/homedir.zig | 4 ++-- src/os/i18n.zig | 30 ++++++++++++++++-------------- src/os/open.zig | 2 +- src/pty.zig | 4 ++++ 9 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/Command.zig b/src/Command.zig index 281dcce40..7ed026efe 100644 --- a/src/Command.zig +++ b/src/Command.zig @@ -323,7 +323,7 @@ fn setupFd(src: File.Handle, target: i32) !void { } } }, - .ios, .macos => { + .freebsd, .ios, .macos => { // Mac doesn't support dup3 so we use dup2. We purposely clear // CLO_ON_EXEC for this fd. const flags = try posix.fcntl(src, posix.F.GETFD, 0); diff --git a/src/apprt/gtk/App.zig b/src/apprt/gtk/App.zig index 099a051a4..df32204f8 100644 --- a/src/apprt/gtk/App.zig +++ b/src/apprt/gtk/App.zig @@ -143,8 +143,8 @@ pub fn init(core_app: *CoreApp, opts: Options) !App { if (config.@"async-backend" != .auto) { const result: bool = switch (config.@"async-backend") { .auto => unreachable, - .epoll => xev.prefer(.epoll), - .io_uring => xev.prefer(.io_uring), + .epoll => if (comptime xev.dynamic) xev.prefer(.epoll) else false, + .io_uring => if (comptime xev.dynamic) xev.prefer(.io_uring) else false, }; if (result) { diff --git a/src/config/Config.zig b/src/config/Config.zig index aabf4f6ba..e45546e7b 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -2817,7 +2817,7 @@ pub fn loadCliArgs(self: *Config, alloc_gpa: Allocator) !void { .windows => {}, // Fast-path if we are Linux and have no args. - .linux => if (std.os.argv.len <= 1) return, + .linux, .freebsd => if (std.os.argv.len <= 1) return, // Everything else we have to at least try because it may // not use std.os.argv. @@ -2835,7 +2835,7 @@ pub fn loadCliArgs(self: *Config, alloc_gpa: Allocator) !void { // styling, etc. based on the command. // // See: https://github.com/Vladimir-csp/xdg-terminal-exec - if (comptime builtin.os.tag == .linux) { + if ((comptime builtin.os.tag == .linux) or (comptime builtin.os.tag == .freebsd)) { if (internal_os.xdg.parseTerminalExec(std.os.argv)) |args| { const arena_alloc = self._arena.?.allocator(); diff --git a/src/input/keycodes.zig b/src/input/keycodes.zig index a85f36d31..2fa0665ea 100644 --- a/src/input/keycodes.zig +++ b/src/input/keycodes.zig @@ -11,7 +11,7 @@ pub const entries: []const Entry = entries: { const native_idx = switch (builtin.os.tag) { .ios, .macos => 4, // mac .windows => 3, // win - .linux => 2, // xkb + .freebsd, .linux => 2, // xkb else => @compileError("unsupported platform"), }; diff --git a/src/os/desktop.zig b/src/os/desktop.zig index c73f150e0..e92c7f86a 100644 --- a/src/os/desktop.zig +++ b/src/os/desktop.zig @@ -56,6 +56,9 @@ pub fn launchedFromDesktop() bool { // iPhone/iPad is always launched from the "desktop" .ios => true, + // Assume we are launching from the "desktop" + .freebsd => true, + else => @compileError("unsupported platform"), }; } diff --git a/src/os/homedir.zig b/src/os/homedir.zig index b5629fd65..f3d6e4498 100644 --- a/src/os/homedir.zig +++ b/src/os/homedir.zig @@ -14,7 +14,7 @@ const Error = error{ /// is generally an expensive process so the value should be cached. pub inline fn home(buf: []u8) !?[]const u8 { return switch (builtin.os.tag) { - inline .linux, .macos => try homeUnix(buf), + inline .linux, .freebsd, .macos => try homeUnix(buf), .windows => try homeWindows(buf), // iOS doesn't have a user-writable home directory @@ -122,7 +122,7 @@ pub const ExpandError = error{ /// than `buf.len`. pub fn expandHome(path: []const u8, buf: []u8) ExpandError![]const u8 { return switch (builtin.os.tag) { - .linux, .macos => try expandHomeUnix(path, buf), + .linux, .freebsd, .macos => try expandHomeUnix(path, buf), .ios => return path, else => @compileError("unimplemented"), }; diff --git a/src/os/i18n.zig b/src/os/i18n.zig index 475f5e705..69194b4fb 100644 --- a/src/os/i18n.zig +++ b/src/os/i18n.zig @@ -69,22 +69,24 @@ pub const InitError = error{ /// used by libghostty. pub fn init(resources_dir: []const u8) InitError!void { // i18n is unsupported on Windows - if (builtin.os.tag == .windows) return; + switch (builtin.os.tag) { + .windows, .freebsd => return, + else => { + // Our resources dir is always nested below the share dir that + // is standard for translations. + const share_dir = std.fs.path.dirname(resources_dir) orelse + return error.InvalidResourcesDir; - // Our resources dir is always nested below the share dir that - // is standard for translations. - const share_dir = std.fs.path.dirname(resources_dir) orelse - return error.InvalidResourcesDir; + // Build our locale path + var buf: [std.fs.max_path_bytes]u8 = undefined; + const path = std.fmt.bufPrintZ(&buf, "{s}/locale", .{share_dir}) catch + return error.OutOfMemory; - // Build our locale path - var buf: [std.fs.max_path_bytes]u8 = undefined; - const path = std.fmt.bufPrintZ(&buf, "{s}/locale", .{share_dir}) catch - return error.OutOfMemory; - - // Bind our bundle ID to the given locale path - log.debug("binding domain={s} path={s}", .{ build_config.bundle_id, path }); - _ = bindtextdomain(build_config.bundle_id, path.ptr) orelse - return error.OutOfMemory; + // Bind our bundle ID to the given locale path + log.debug("binding domain={s} path={s}", .{ build_config.bundle_id, path }); + _ = bindtextdomain(build_config.bundle_id, path.ptr) orelse + return error.OutOfMemory; + }} } /// Set the global gettext domain to our bundle ID, allowing unqualified diff --git a/src/os/open.zig b/src/os/open.zig index f7eadd06e..39f28036f 100644 --- a/src/os/open.zig +++ b/src/os/open.zig @@ -19,7 +19,7 @@ pub fn open( url: []const u8, ) !void { const cmd: OpenCommand = switch (builtin.os.tag) { - .linux => .{ .child = std.process.Child.init( + .linux, .freebsd => .{ .child = std.process.Child.init( &.{ "xdg-open", url }, alloc, ) }, diff --git a/src/pty.zig b/src/pty.zig index a36de9adc..02906b778 100644 --- a/src/pty.zig +++ b/src/pty.zig @@ -99,6 +99,10 @@ const PosixPty = struct { @cInclude("sys/ioctl.h"); // ioctl and constants @cInclude("util.h"); // openpty() }), + .freebsd => @cImport({ + @cInclude("termios.h"); // ioctl and constants + @cInclude("libutil.h"); // openpty() + }), else => @cImport({ @cInclude("sys/ioctl.h"); // ioctl and constants @cInclude("pty.h");