-
Notifications
You must be signed in to change notification settings - Fork 37.4k
Use open -a in code.sh on mac #258824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use open -a in code.sh on mac #258824
Conversation
deepak1556
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shell script calls into a cli script in headless mode, the cli inturn opens the actual application based on the arguments via open
vscode/src/vs/code/node/cli.ts
Lines 493 to 567 in b234a54
| // On Big Sur, we spawn using the open command to obtain behavior | |
| // similar to if the app was launched from the dock | |
| // https://github.com/microsoft/vscode/issues/102975 | |
| // The following args are for the open command itself, rather than for VS Code: | |
| // -n creates a new instance. | |
| // Without -n, the open command re-opens the existing instance as-is. | |
| // -g starts the new instance in the background. | |
| // Later, Electron brings the instance to the foreground. | |
| // This way, Mac does not automatically try to foreground the new instance, which causes | |
| // focusing issues when the new instance only sends data to a previous instance and then closes. | |
| const spawnArgs = ['-n', '-g']; | |
| // -a opens the given application. | |
| spawnArgs.push('-a', process.execPath); // -a: opens a specific application | |
| if (args.verbose || args.status) { | |
| spawnArgs.push('--wait-apps'); // `open --wait-apps`: blocks until the launched app is closed (even if they were already running) | |
| // The open command only allows for redirecting stderr and stdout to files, | |
| // so we make it redirect those to temp files, and then use a logger to | |
| // redirect the file output to the console | |
| for (const outputType of args.verbose ? ['stdout', 'stderr'] : ['stdout']) { | |
| // Tmp file to target output to | |
| const tmpName = randomPath(tmpdir(), `code-${outputType}`); | |
| writeFileSync(tmpName, ''); | |
| spawnArgs.push(`--${outputType}`, tmpName); | |
| // Listener to redirect content to stdout/stderr | |
| processCallbacks.push(async child => { | |
| try { | |
| const stream = outputType === 'stdout' ? process.stdout : process.stderr; | |
| const cts = new CancellationTokenSource(); | |
| child.on('close', () => { | |
| // We must dispose the token to stop watching, | |
| // but the watcher might still be reading data. | |
| setTimeout(() => cts.dispose(true), 200); | |
| }); | |
| await watchFileContents(tmpName, chunk => stream.write(chunk), () => { /* ignore */ }, cts.token); | |
| } finally { | |
| unlinkSync(tmpName); | |
| } | |
| }); | |
| } | |
| } | |
| for (const e in env) { | |
| // Ignore the _ env var, because the open command | |
| // ignores it anyway. | |
| // Pass the rest of the env vars in to fix | |
| // https://github.com/microsoft/vscode/issues/134696. | |
| if (e !== '_') { | |
| spawnArgs.push('--env'); | |
| spawnArgs.push(`${e}=${env[e]}`); | |
| } | |
| } | |
| spawnArgs.push('--args', ...argv.slice(2)); // pass on our arguments | |
| if (env['VSCODE_DEV']) { | |
| // If we're in development mode, replace the . arg with the | |
| // vscode source arg. Because the OSS app isn't bundled, | |
| // it needs the full vscode source arg to launch properly. | |
| const curdir = '.'; | |
| const launchDirIndex = spawnArgs.indexOf(curdir); | |
| if (launchDirIndex !== -1) { | |
| spawnArgs[launchDirIndex] = resolve(curdir); | |
| } | |
| } | |
| // We already passed over the env variables | |
| // using the --env flags, so we can leave them out here. | |
| // Also, we don't need to pass env._, which is different from argv._ | |
| child = spawn('open', spawnArgs, { ...options, env: {} }); |
I don't see how this makes it any different than what we have today. Also we cannot skip the cli script since it takes of various argument processing, some don't require actual application to be opened.
|
Ah I see. Then it's mostly a design choice. Why are we using -n? This appears to be intentional to create a new instance. Don't most people want it to just open in the same existing instance? |
|
We have our own implementation of singleton instance vscode/src/vs/code/electron-main/main.ts Lines 292 to 420 in ce135b9
-n is used to route to our logic.
|
|
Then I guess this is a separate question. What it ends up doing visually is that it creates a new instance that instantly quits and transitions focus to the old instance, but then there's an extra VSC in my dock. |
|
Thanks for all the clarification |
Yup thats correct, the extra icon is something I can confirm as well but I tend to rule this out as macOS expectation. The icon takes the space of recently launched application, unless you have VSCode pinned to the dock then a different application launch should replace the extra icon. If there is an open option without changing our cli behavior, happy to try that. |
|
Hm I see. I'll try to see if I can think of something. |
|
Funnily enough, I don't seem to be able to reproduce it appearing as a recently quit app in the dock anymore. Either way, perhaps inserting |
|
Remembered we had a discussion around revisiting the use of |
|
all right, I'll give it a try |
In reference to #258821
Uses the
opencommand rather than launching via Electron directly.Test by replacing the contents of /usr/local/bin/code with the proposed changes (or rebuilding).