Skip to content

Commit b6798bb

Browse files
committed
smart fork for macos - in app builds, block the terminal only if there isn't one
1 parent 3ac6ada commit b6798bb

2 files changed

Lines changed: 26 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# GG Changelog
22

3+
## [Unreleased]
4+
5+
### Added
6+
- The MacOS app build will now detect when it's run from a terminal like the CLI build does, spawning in the background by default (--foreground to block the shell). (Windows already had behaviour similar to this.)
7+
38
## [0.39.0](releases/tag/v0.39.0)
49
This release is based on Jujutsu 0.39.
510

src/main.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ struct Args {
6060
#[arg(long, global = true)]
6161
ignore_immutable: bool,
6262

63-
#[cfg(not(feature = "app"))]
6463
#[arg(
6564
long,
6665
global = true,
@@ -133,21 +132,34 @@ fn main() -> Result<()> {
133132

134133
let args = Args::parse();
135134

136-
// cargo run/install: act like a CLI that spawns a GUI in the background
137-
#[cfg(not(feature = "app"))]
138-
if !args.foreground {
135+
if !args.foreground && should_spawn() {
139136
spawn_app()
140137
} else {
141138
run_app(args)
142139
}
140+
}
141+
142+
/// whether to fork a background process and return the shell to the user
143+
fn should_spawn() -> bool {
144+
// crate builds always fork - they act as a CLI that spawns the GUI
145+
#[cfg(not(feature = "app"))]
146+
return true;
143147

144-
#[cfg(feature = "app")]
148+
// app builds on macOS fork when launched from a terminal, so that
149+
// running `gg` from a shell prompt returns control to the user.
150+
// when launched from Finder/Dock/Spotlight there's no terminal.
151+
#[cfg(all(feature = "app", target_os = "macos"))]
145152
{
146-
run_app(args)
153+
use std::io::IsTerminal;
154+
return std::io::stderr().is_terminal();
147155
}
156+
157+
// windows app builds don't need to fork - windows_subsystem = "windows"
158+
// already detaches from the console
159+
#[cfg(all(feature = "app", not(target_os = "macos")))]
160+
return false;
148161
}
149162

150-
#[cfg(not(feature = "app"))]
151163
fn spawn_app() -> Result<()> {
152164
use std::io::{BufRead, BufReader};
153165
use std::process::{Command, Stdio, exit};
@@ -157,6 +169,7 @@ fn spawn_app() -> Result<()> {
157169

158170
cmd.args(std::env::args().skip(1)); // forward all original arguments
159171
cmd.arg("--foreground");
172+
cmd.env("GG_SPAWNED", "1");
160173
cmd.stdout(Stdio::piped());
161174
cmd.stderr(Stdio::inherit()); // forward logs until startup is complete
162175

@@ -195,11 +208,7 @@ fn run_app(args: Args) -> Result<()> {
195208
let mode = args.mode().unwrap_or_else(|| default_mode(&settings));
196209
let context = tauri::generate_context!();
197210

198-
// When spawned as a child process, foreground flag is set by the parent
199-
#[cfg(not(feature = "app"))]
200-
let is_child = args.foreground;
201-
#[cfg(feature = "app")]
202-
let is_child = false;
211+
let is_child = std::env::var_os("GG_SPAWNED").is_some();
203212

204213
let options = RunOptions {
205214
context,

0 commit comments

Comments
 (0)