aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/main_ghostty.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-10 21:51:57 +0300
committerGitHub <noreply@github.com>2026-09-10 21:51:57 +0300
commit425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch)
treee52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/src/main_ghostty.zig
parent90e947a6e26e02f10ec7f1694c4eb5b78a86406b (diff)
chore: upgrade libghostty and preserve terminal behavior (#3906)
Diffstat (limited to 'vendor/libghostty-vt/src/main_ghostty.zig')
-rw-r--r--vendor/libghostty-vt/src/main_ghostty.zig95
1 files changed, 74 insertions, 21 deletions
diff --git a/vendor/libghostty-vt/src/main_ghostty.zig b/vendor/libghostty-vt/src/main_ghostty.zig
index 531a0646..f4fa7413 100644
--- a/vendor/libghostty-vt/src/main_ghostty.zig
+++ b/vendor/libghostty-vt/src/main_ghostty.zig
@@ -13,7 +13,7 @@ const apprt = @import("apprt.zig");
const App = @import("App.zig");
const Ghostty = @import("main_c.zig").Ghostty;
-const state = &@import("global.zig").state;
+const global = @import("global.zig");
/// The return type for main() depends on the build artifact. The lib build
/// also calls "main" in order to run the CLI actions, but it calls it as
@@ -23,16 +23,19 @@ const MainReturn = switch (build_config.artifact) {
else => void,
};
-pub fn main() !MainReturn {
+pub fn main(minimal: std.process.Init.Minimal) !MainReturn {
// We first start by initializing our global state. This will setup
// process-level state we need to run the terminal. The reason we use
// a global is because the C API needs to be able to access this state;
// no other Zig code should EVER access the global state.
- state.init() catch |err| {
+ global.init(.{ .main = minimal }) catch |err| {
var buffer: [1024]u8 = undefined;
- var stderr_writer = std.fs.File.stderr().writer(&buffer);
+ var stderr_writer = std.Io.File.stderr().writer(
+ std.Io.Threaded.global_single_threaded.io(),
+ &buffer,
+ );
const stderr = &stderr_writer.interface;
- defer posix.exit(1);
+ defer std.process.exit(1);
const ErrSet = @TypeOf(err) || error{Unknown};
switch (@as(ErrSet, @errorCast(err))) {
error.MultipleActions => try stderr.print(
@@ -52,8 +55,8 @@ pub fn main() !MainReturn {
}
try stderr.flush();
};
- defer state.deinit();
- const alloc = state.alloc;
+ defer global.deinit();
+ const alloc = global.alloc();
if (comptime builtin.mode == .Debug) {
std.log.warn("This is a debug build. Performance will be very poor.", .{});
@@ -62,9 +65,9 @@ pub fn main() !MainReturn {
}
// Execute our action if we have one
- if (state.action) |action| {
+ if (global.action()) |action| {
std.log.info("executing CLI action={}", .{action});
- posix.exit(action.run(alloc) catch |err| err: {
+ std.process.exit(action.run(alloc) catch |err| err: {
std.log.err("CLI action failed error={}", .{err});
break :err 1;
});
@@ -90,7 +93,7 @@ pub fn main() !MainReturn {
.{},
);
- posix.exit(0);
+ std.process.exit(0);
}
// Create our app state
@@ -125,7 +128,7 @@ fn logFn(
// macOS logging is thread safe so no need for locks/mutexes
macos: {
if (comptime !builtin.target.os.tag.isDarwin()) break :macos;
- if (!state.logging.macos) break :macos;
+ if (!global.logging().macos) break :macos;
const prefix = if (scope == .default) "" else @tagName(scope) ++ ": ";
@@ -137,11 +140,12 @@ fn logFn(
.err => .fault,
};
- // Initialize a logger. This is slow to do on every operation
- // but we shouldn't be logging too much.
- const logger = macos.os.Log.create(build_config.bundle_id, @tagName(scope));
- defer logger.release();
- logger.log(std.heap.c_allocator, mac_level, prefix ++ format, args);
+ macosLogger(scope).log(
+ std.heap.c_allocator,
+ mac_level,
+ prefix ++ format,
+ args,
+ );
}
stderr: {
@@ -149,20 +153,51 @@ fn logFn(
if (comptime builtin.mode != .Debug and level == .debug) break :stderr;
// skip if we are not logging to stderr
- if (!state.logging.stderr) break :stderr;
+ if (!global.logging().stderr) break :stderr;
// Lock so we are thread-safe
var buf: [64]u8 = undefined;
- const stderr = std.debug.lockStderrWriter(&buf);
- defer std.debug.unlockStderrWriter();
+ const stderr = std.debug.lockStderr(&buf);
+ defer std.debug.unlockStderr();
const level_txt = comptime level.asText();
const prefix = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
- nosuspend stderr.print(level_txt ++ prefix ++ format ++ "\n", args) catch break :stderr;
- nosuspend stderr.flush() catch break :stderr;
+ nosuspend stderr.file_writer.interface.print(level_txt ++ prefix ++ format ++ "\n", args) catch break :stderr;
+ nosuspend stderr.file_writer.interface.flush() catch break :stderr;
}
}
+/// Returns the macOS unified logging logger for the given scope. The
+/// logger is created once per scope and cached for the lifetime of the
+/// process, because os_log object creation is slow (it shows up in
+/// startup profiles when done per log call) and Apple's guidance is to
+/// create loggers once and reuse them.
+fn macosLogger(comptime scope: @TypeOf(.EnumLiteral)) *macos.os.Log {
+ const S = struct {
+ var cached: std.atomic.Value(?*macos.os.Log) = .init(null);
+ };
+
+ if (S.cached.load(.acquire)) |v| return v;
+
+ // Create and attempt to store our logger. If we race with another
+ // thread then we use theirs and release ours.
+ const created = macos.os.Log.create(
+ build_config.bundle_id,
+ @tagName(scope),
+ );
+ if (S.cached.cmpxchgStrong(
+ null,
+ created,
+ .acq_rel,
+ .acquire,
+ )) |existing| {
+ created.release();
+ return existing.?;
+ }
+
+ return created;
+}
+
pub const std_options: std.Options = .{
// Our log level is always at least info in every build mode.
//
@@ -176,6 +211,24 @@ pub const std_options: std.Options = .{
},
.logFn = logFn,
+
+ // If are building for a non-MacOS Darwin target (e.g., iOS), we need to
+ // disable stack tracing for the time being. This is due to the fact that
+ // Zig switched to using _dyld_get_image_header_containing_address and some
+ // other (deprecated) calls to speed up stack unwinding; these calls are
+ // available on MacOS, but not on other platforms.
+ //
+ // A fix has already been submitted to exempt non-MacOS (but still Darwin)
+ // targets, so this can likely be removed in Zig 0.17.0, or a 0.16.x patch
+ // version if it releases beforehand.
+ //
+ // More details:
+ // https://codeberg.org/ziglang/zig/commit/89f86e46d278a35a613bbc662cdd3f65ffc76ed7
+ //
+ .allow_stack_tracing = if (builtin.target.os.tag.isDarwin() and builtin.target.os.tag != .macos)
+ false
+ else
+ !builtin.strip_debug_info,
};
test {