Skip to content
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

Add prototype of mac open command #131213

Merged
merged 27 commits into from Sep 14, 2021
Merged

Add prototype of mac open command #131213

merged 27 commits into from Sep 14, 2021

Conversation

rzhao271
Copy link
Contributor

@rzhao271 rzhao271 commented Aug 19, 2021

This PR fixes #60579 and fixes #102975.

It switches the spawn call on macOS to use the open command, so that the application opens as though it were launched from the dock. In turn, launching the application from the console should now not result in as many bugs such as duplicated recently opened icons.

To test on macOS:

  1. Build the OSS project
  2. Run code-cli.sh in the terminal, e.g. ./scripts/code-cli.sh <your-flags-here>.

@rzhao271 rzhao271 added this to the August 2021 milestone Aug 19, 2021
@rzhao271 rzhao271 self-assigned this Aug 19, 2021
@rzhao271 rzhao271 added engineering VS Code - Build / issue tracking / etc. macos Issues with VS Code on MAC/OS X labels Aug 19, 2021
@bpasero
Copy link
Member

bpasero commented Aug 20, 2021

👍 , Some high level feedback:

  • not a big fan of the execPath thing, can we not launch using the Code - OSS.app that we have? maybe if changes are needed they could go into the existing scripts/code-cli.sh which serves as a way to test the CLI even when running out of sources
  • the way how to poll for output from the target seems quite involved, are we certain there is no way to use open and get the output piped back to the calling terminal?
  • I do not fully understand the issue with the extension CLI commands

@rzhao271
Copy link
Contributor Author

I added in --exec-path because when we use the open command in the spawn call, instead of just spawning process.execPath, we end up with the following command being passed to spawn: open -a vscode/.build/electron/Code\ -\ OSS.app/Contents/MacOS/Electron --args vscode/out/cli.js. --args only allows us to pass args to Electron, but not to cli.js itself, so we have an issue here. I'm also not sure whether Electron should really be the one responsible for passing down args to the child script @deepak1556. With --exec-path, I can run in the command line vscode/.build/electron/Code\ -\ OSS.app/Contents/MacOS/Electron vscode/out/cli.js --exec-path /Applications/Visual\ Studio\ Code.app --help, and then the open command becomes open -a /Applications/Visual\ Studio\ Code.app --args --help, which is what we want, since --help is being passed to a bundled app in this case rather than just a plain Electron wrapper.

I got an idea from your comment, though, and tried vscode/.build/electron/Code\ -\ OSS.app/Contents/MacOS/Electron vscode/out/cli.js --exec-path vscode/.build/electron/Code\ -\ OSS.app vscode-docs --verbose which results in the following:

Temp file location: /var/folders/7c/hr98w2kj1z5fjs_q959r68fr0000gn/T/vscode-wait-transfer-1629475671736.log
Unable to find application named 'vscode/.build/electron/Code - OSS.app'
ENOENT: no such file or directory, unlink '/var/folders/7c/hr98w2kj1z5fjs_q959r68fr0000gn/T/vscode-wait-transfer-error-1629475671736.log'

As for the open command, it provides --stdin, --stdout, and --stderr arguments, but I'm unable to do stdout directly to the stdout file descriptor (/dev/fd/1). I've only been able to use regular plain text files and then poll from there.

Copy link
Member

@bpasero bpasero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some more feedback in code. I still think we need to find an alternative solution for exec-path, i.e. we cannot really ship that CLI argument imho.

src/vs/platform/environment/node/userDataPath.js Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
@rzhao271
Copy link
Contributor Author

rzhao271 commented Aug 23, 2021

@bpasero it turns out that one can use the following command for the open call instead of having to add an --exec-path flag: open -a /Users/raymondzhao/work/vscode/.build/electron/Code\ -\ OSS.app --args --disable-crash-reporter /Users/raymondzhao/work/vscode.

Earlier attempts weren't working for me because

  1. I was using relative paths instead of absolute paths
  2. I was trying to point to other paths other than the vscode source path

@rzhao271
Copy link
Contributor Author

I did some more testing with the code-cli.sh script.
The only case where I can repro an issue is if I start one instance with --verbose dir1, and then start a second instance with --verbose -a dir2. In this case, a second instance of Code starts up, and the environment gets passed to the first instance, but the second instance doesn't get the signal to exit. In this case, the user ends up with two icons in the dock pointing to the same window. The window does display an untitled workspace containing both dir1 and dir2, though.
--telemetry also fails, but that's because OSS doesn't have a telemetry-core.json file.

@rzhao271
Copy link
Contributor Author

Ok, it seems the case above comes from me adding a wait arg for both VS Code and open for the --verbose flag. Adding the wait arg for just open is enough in that case.

@rzhao271
Copy link
Contributor Author

I have switched the implementation to use a file watcher, and made a new file cliVerboseLogger.ts to hold that component.

@rzhao271 rzhao271 requested a review from bpasero August 31, 2021 18:52
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cliVerboseLogger.ts Outdated Show resolved Hide resolved
src/vs/code/node/cliVerboseLogger.ts Outdated Show resolved Hide resolved
Copy link
Member

@bpasero bpasero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments inline.

Besides, on Windows/Linux we are specifically dealing with waitMarkerFilePath and stdinFilePath but I am not seeing relevant code for the macOS case now. Specifically:

// Complete when wait marker file is deleted
whenDeleted(waitMarkerFilePath!).then(resolve, resolve);

and

// Make sure to delete the tmp stdin file if we have any
if (stdinFilePath) {
unlinkSync(stdinFilePath);
}

src/vs/code/node/cliVerboseLogger.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Show resolved Hide resolved
src/vs/code/node/cliVerboseLogger.ts Outdated Show resolved Hide resolved
src/vs/code/node/cliVerboseLogger.ts Outdated Show resolved Hide resolved
src/vs/code/node/cliVerboseLogger.ts Outdated Show resolved Hide resolved
src/vs/code/node/cliVerboseLogger.ts Outdated Show resolved Hide resolved
@rzhao271
Copy link
Contributor Author

rzhao271 commented Sep 2, 2021

Even when --wait is passed to VS Code, it seems we need to pass -W to open, otherwise VS Code doesn't wait. I've moved out the wait block and turned it into a promise at 9fd7736#diff-20d6c291a7c88c482614d5d317aff06e45562df7178e850602f5e8b9e365f395R378

One use case where both --wait and -W become significant is when a user does the following on macOS:

  1. Run code-cli.sh --verbose absolute-path-to-dir-1 in a terminal
  2. Run code-cli.sh --verbose --wait -a absolute-path-to-dir-2 in a second terminal
  3. 🐛 There are now two OSS icons in the dock, but they point to the same window. If the user quits the second window, the second terminal stops logging, but if the user quits the first window, both terminals stop logging. I don't think passing the -r flag to VS Code helps with this issue. On Windows, there's just one window in the taskbar, and closing that window stops both processes. I also confirmed on macOS that the current Stable build has the same issue.

@bpasero
Copy link
Member

bpasero commented Sep 3, 2021

For a long time we used to call app.dock.hide() to prevent the second instance from showing up in the dock but then we removed that code because in some cases it resulted in the dock icon to become buggy. I wonder whether:

  • we could revisit this given we use open command with this PR
  • this get's fixed when we use the request singleton API from Chrome

@deepak1556
Copy link
Contributor

For a long time we used to call app.dock.hide() to prevent the second instance from showing up in the dock but then we removed that code because in some cases it resulted in the dock icon to become buggy.

It should be fine to use the api since we now launch the app in a way expected by the OS.

But the problem of double icon should definitely not happen when using the singleinstance api as all the work will be done by the first instance including waiting on the marker file. I am not sure why this is happening with today's code path, IIUC of the wait logic,

  1. Second instance launched with --wait flag
  2. Creates a marker file and passes it as argument to the first instance
  3. First instance opens a new window or reuses existing window depending on other flags
  4. Wait marker file deletion will now be handled by the corresponding window close event
  5. Second instance app should now quit
  6. Second instance cli will wait on the marker file deletion to exit

Step 5) should have made the second icon from the dock dismissed, atleast in singleinstance api case Step 5) will be moved up to Step 3) so we definitely don't have to handle hiding the dock icon.

@deepak1556
Copy link
Contributor

Even when --wait is passed to VS Code, it seems we need to pass -W to open, otherwise VS Code doesn't wait

The cli process should wait on the marker file not on the application process, -W flag will not work correctly when we switch to singleinstance.

src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cliVerboseLogger.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
src/vs/code/node/cli.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@deepak1556 deepak1556 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM on the open command usages

@rzhao271 rzhao271 merged commit 254c5c7 into main Sep 14, 2021
@rzhao271 rzhao271 deleted the rzhao271/mac-open-file branch September 14, 2021 17:03
@memeplex
Copy link

Should this be working by now?

In 1.61.2 opening files with code <file> from the terminal still leaves a trail of "duplicated recently opened icons" and folks in #60579 are happy defining an alias with "open -b" that's an old hack that should supposedly be unnecessary now that #60579 is closed?

@github-actions github-actions bot locked and limited conversation to collaborators Oct 29, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
engineering VS Code - Build / issue tracking / etc. macos Issues with VS Code on MAC/OS X
Projects
None yet
4 participants