diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-09-10 21:51:57 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-10 21:51:57 +0300 |
| commit | 425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch) | |
| tree | e52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/src/main_ghostty.zig | |
| parent | 90e947a6e26e02f10ec7f1694c4eb5b78a86406b (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.zig | 95 |
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 { |
