diff --git a/macos/Sources/App/macOS/AppDelegate.swift b/macos/Sources/App/macOS/AppDelegate.swift index efc09ede9..53b6dce88 100644 --- a/macos/Sources/App/macOS/AppDelegate.swift +++ b/macos/Sources/App/macOS/AppDelegate.swift @@ -256,9 +256,8 @@ class AppDelegate: NSObject, // Setup signal handlers setupSignals() - // This is a hack used by our build scripts, specifically `zig build run`, - // to force our app to the foreground. - if ProcessInfo.processInfo.environment["GHOSTTY_MAC_ACTIVATE"] == "1" { + // If we launched via zig run then we need to force foreground. + if Ghostty.launchSource == .zig_run { // This never gets called until we click the dock icon. This forces it // activate immediately. applicationDidBecomeActive(.init(name: NSApplication.didBecomeActiveNotification)) diff --git a/macos/Sources/Ghostty/Package.swift b/macos/Sources/Ghostty/Package.swift index 125a09825..e96f555d3 100644 --- a/macos/Sources/Ghostty/Package.swift +++ b/macos/Sources/Ghostty/Package.swift @@ -48,6 +48,26 @@ extension Ghostty { } } +// MARK: General Helpers + +extension Ghostty { + enum LaunchSource: String { + case cli + case app + case zig_run + } + + /// Returns the mechanism that launched the app. This is based on an env var so + /// its up to the env var being set in the correct circumstance. + static var launchSource: LaunchSource { + guard let envValue = ProcessInfo.processInfo.environment["GHOSTTY_MAC_LAUNCH_SOURCE"] else { + return .app + } + + return LaunchSource(rawValue: envValue) ?? .app + } +} + // MARK: Swift Types for C Types extension Ghostty { diff --git a/src/build/GhosttyXcodebuild.zig b/src/build/GhosttyXcodebuild.zig index 9b472eda8..052c9f3e4 100644 --- a/src/build/GhosttyXcodebuild.zig +++ b/src/build/GhosttyXcodebuild.zig @@ -88,6 +88,19 @@ pub fn init( // Our step to open the resulting Ghostty app. const open = open: { + const disable_save_state = RunStep.create(b, "disable save state"); + disable_save_state.has_side_effects = true; + disable_save_state.addArgs(&.{ + "/usr/libexec/PlistBuddy", + "-c", + // We'll have to change this to `Set` if we ever put this + // into our Info.plist. + "Add :NSQuitAlwaysKeepsWindows bool false", + b.fmt("{s}/Contents/Info.plist", .{app_path}), + }); + disable_save_state.expectExitCode(0); + disable_save_state.step.dependOn(&build.step); + const open = RunStep.create(b, "run Ghostty app"); open.has_side_effects = true; open.cwd = b.path(""); @@ -98,15 +111,14 @@ pub fn init( // Open depends on the app open.step.dependOn(&build.step); + open.step.dependOn(&disable_save_state.step); // This overrides our default behavior and forces logs to show // up on stderr (in addition to the centralized macOS log). open.setEnvironmentVariable("GHOSTTY_LOG", "1"); - // This is hack so that we can activate the app and bring it to - // the front forcibly even though we're executing directly - // via the binary and not launch services. - open.setEnvironmentVariable("GHOSTTY_MAC_ACTIVATE", "1"); + // Configure how we're launching + open.setEnvironmentVariable("GHOSTTY_MAC_LAUNCH_SOURCE", "zig_run"); if (b.args) |args| { open.addArgs(args);