From d65fbba39e57f723fa6a93c393768b9c9dd2d60a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 6 Jan 2024 12:31:01 -0800 Subject: [PATCH] config: do not load command from SHELL when launched from desktop Fixes #139 From the issue: Looking into this now, I think I figured out the broken logic. When launching from open, the parent process of Ghostty is launchd which appears to set your SHELL env var to your configured shell when logging in. That's why a restart fixes it. However, I believe directory services (the macOS equivalent to /etc/passwd) is updated in real time. Ghostty does read directory services but at a lower priority than SHELL. This logic makes sense for CLI-launched terminals but not desktop-launched. From a CLI you want the terminal you're launching to probably inherit the shell from the CLI you launched it from. (Note that using open explicitly forces a launchd-style launch so it quacks as if it was double-clicked on the desktop). In conclusion, I believe the correct logic is to invert the priority on SHELL vs directory services when Ghostty detects it was launched from launchd. We already have this detection logic in Ghostty because we use it for a number of other things as well, so this should be easy to fix. I'll work on it later today. --- src/config/Config.zig | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/config/Config.zig b/src/config/Config.zig index 025d09412..9881580b9 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1674,16 +1674,22 @@ pub fn finalize(self: *Config) !void { // set to /bin/sh. if (self.command) |cmd| log.info("shell src=config value={s}", .{cmd}) - else { - if (!internal_os.isFlatpak()) { - if (std.process.getEnvVarOwned(alloc, "SHELL")) |value| { - log.info("default shell source=env value={s}", .{value}); - self.command = value; + else shell_env: { + // Flatpak always gets its shell from outside the sandbox + if (internal_os.isFlatpak()) break :shell_env; - // If we don't need the working directory, then we can exit now. - if (!wd_home) break :command; - } else |_| {} - } + // If we were launched from the desktop, our SHELL env var + // will represent our SHELL at login time. We want to use the + // latest shell from /etc/passwd or directory services. + if (internal_os.launchedFromDesktop()) break :shell_env; + + if (std.process.getEnvVarOwned(alloc, "SHELL")) |value| { + log.info("default shell source=env value={s}", .{value}); + self.command = value; + + // If we don't need the working directory, then we can exit now. + if (!wd_home) break :command; + } else |_| {} } switch (builtin.os.tag) {