Launch macOS app background-detached when no args passed

- Add `launchAppBackgroundDetached` that spawns with `--start --background` and `SUBMINER_BACKGROUND_CHILD=1`
- On darwin with empty appArgs, use detached background launch instead of inherited process
- Add `extraEnv` param to `launchAppCommandDetached` for env injection
- Inject deps into `runAppPassthroughCommand` for testability
- Bump vendor/subminer-yomitan submodule
This commit is contained in:
2026-05-25 02:12:41 -07:00
parent 920cbab1bc
commit 9fe13601fb
5 changed files with 114 additions and 6 deletions
+29
View File
@@ -14,6 +14,7 @@ import {
buildMpvEnv,
cleanupPlaybackSession,
detectBackend,
launchAppBackgroundDetached,
findAppBinary,
launchAppCommandDetached,
launchTexthookerOnly,
@@ -425,6 +426,34 @@ test('launchAppCommandDetached handles child process spawn errors', async () =>
}
});
test('launchAppBackgroundDetached starts background child directly', async () => {
const { dir } = createTempSocketPath();
const appPath = path.join(dir, 'fake-subminer.sh');
const argsPath = path.join(dir, 'args.txt');
const envPath = path.join(dir, 'env.txt');
fs.writeFileSync(
appPath,
[
'#!/bin/sh',
`printf '%s\\n' "$@" > ${JSON.stringify(argsPath)}`,
`printf '%s\\n' "$SUBMINER_BACKGROUND_CHILD" > ${JSON.stringify(envPath)}`,
'',
].join('\n'),
);
fs.chmodSync(appPath, 0o755);
launchAppBackgroundDetached(appPath, 'info');
const deadline = Date.now() + 1000;
while ((!fs.existsSync(argsPath) || !fs.existsSync(envPath)) && Date.now() < deadline) {
await new Promise((resolve) => setTimeout(resolve, 20));
}
assert.equal(fs.readFileSync(argsPath, 'utf8').trim(), '--start\n--background');
assert.equal(fs.readFileSync(envPath, 'utf8').trim(), '1');
fs.rmSync(dir, { recursive: true, force: true });
});
test('stopOverlay logs a warning when stop command cannot be spawned', () => {
const originalWrite = process.stdout.write;
const writes: string[] = [];