Skip to content

Comments

Make browser detection more robust on Linux#2257

Merged
mjcheetham merged 2 commits intogit-ecosystem:mainfrom
mjcheetham:linux-browser-fix
Feb 6, 2026
Merged

Make browser detection more robust on Linux#2257
mjcheetham merged 2 commits intogit-ecosystem:mainfrom
mjcheetham:linux-browser-fix

Conversation

@mjcheetham
Copy link
Contributor

@mjcheetham mjcheetham commented Feb 3, 2026

In non-WSL environments we make our checks for a browser more robust by checking for a 'shell execute' handler (like xdg-open).

Previously we just relied on a desktop session (DISPLAY or WAYLAND_DISPLAY), which isn't accurate since in OpenBrowser we require a shell execute handler. The check and implementation are now aligned!

In a Visual Studio Code remote session, we may be able to launch a browser without the DISPLAY environment variable set. This is because VSCode sets the BROWSER environment variable in remote sessions, such that it can forward requests to start a browser to the client machine.

However! There are several types of remote session in VSCode, and the way they handle automatic port forwarding differs slightly. Since a very common case in GCM for launching the user browser is the ability to connect back to GCM via localhost:<port>, we only consider a subset of remote sessions to be able to launch a browser:

  • Remote SSH ✅
image
  • Dev Containers ✅
image
  • Remote Tunnel ❌
image

Sadly, for whatever reason, the remote connection over Microsoft Dev Tunnels does NOT automatically surface a forwarded port to localhost on the client. The forwarded port is only available via the devtunnels.ms URLs.

Dev Tunnels SSH
image image

Detecting the different types of remote session is tricky as it's not always as explicit as we'd like.

All types: VSCODE_IPC_HOOK_CLI is set.

Dev Containers : REMOTE_CONTAINERS is set.
Remote SSH : SSH_CONNECTION is set.
Remote Tunnel : absense of REMOTE_CONTAINERS and SSH_CONNECTION.

Note, when starting a tunnel server from a regular SSH connection the SSH_CONNECTION variable gets inherited by the tunnel connections themselves! This means we need to also check for the absence of SSH_TTY because the tunnel server unsets this. SSH_TTY is set only in regular SSH sessions.

@mjcheetham mjcheetham requested a review from a team as a code owner February 3, 2026 14:05
@mjcheetham mjcheetham added the platform:linux Specific to a Linux-based platform label Feb 3, 2026
@mjcheetham mjcheetham marked this pull request as draft February 4, 2026 16:55
@mjcheetham mjcheetham changed the title Support BROWSER variable on Linux and make browser launching more robust Make browser detection more robust on Linux Feb 4, 2026
@mjcheetham mjcheetham requested review from dscho and mpysson February 4, 2026 17:03
Copy link
Contributor

@dscho dscho left a comment

Choose a reason for hiding this comment

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

I like when changes make it easier to debug things!

In non-WSL environments we make our checks for a browser more
robust by checking for a 'shell execute' handler (like xdg-open).
Previously we just relied on a desktop session ($DISPLAY or
$WAYLAND_DISPLAY), which isn't accurate since in `OpenBrowser`
we require a shell execute handler. The check and implementation
are now aligned!

We refactor the method to avoid nesting `if`s and use early returns to
make things a little clearer.

Helped-by: Marc Becker <becm@gmx.de>
Co-authored-by: Kyle Rader <kyrader@microsoft.com>
Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
In a Visual Studio Code remote session, we may be able to launch a
browser without the `DISPLAY` environment variable set. This is because
VSCode sets the `BROWSER` environment variable in remote sessions, such
that it can forward requests to start a browser to the client machine.

However! There are several types of remote session in VSCode, and the
way they handle automatic port forwarding differs slightly. Since a very
common case in GCM for launching the user browser is the ability to
connect back to GCM via localhost:<port>, we only consider a subset of
remote sessions to be able to launch a browser:

* Remote SSH     [YES]
* Dev Containers [YES]
* Remote Tunnel  [NO]

Sadly, for whatever reason, the remote connection over Microsoft Dev
Tunnels does NOT automatically surface a forwarded port to localhost on
the client. The forwarded port is only available via the devtunnels.ms
URLs.

Detecting the different types of remote session is tricky as it's not
always as explicit as we'd like.

All types: VSCODE_IPC_HOOK_CLI is set.

Dev Containers : REMOTE_CONTAINERS is set.
Remote SSH     : SSH_CONNECTION is set.
Remote Tunnel  : absense of REMOTE_CONTAINERS and SSH_CONNECTION.

Note, when starting a tunnel server from a regular SSH connection the
SSH_CONNECTION variable gets inherited by the tunnel connections
themselves! This means we need to also check for the absence of SSH_TTY
because the tunnel server unsets this. SSH_TTY is set only in regular
SSH sessions.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
@mjcheetham mjcheetham marked this pull request as ready for review February 5, 2026 15:14
@mjcheetham mjcheetham requested a review from dscho February 5, 2026 15:25
@mjcheetham
Copy link
Contributor Author

mjcheetham commented Feb 5, 2026

Sadly, for whatever reason, the remote connection over Microsoft Dev Tunnels does NOT automatically surface a forwarded port to localhost on the client. The forwarded port is only available via the devtunnels.ms URLs.

@kyle-rader-msft are you able to confirm how you connect to the "WaveSpace VMs" (dev tunnel or SSH), and confirm the behaviour of the auto-forwarded ports?

In my testing, forwarded ports in a tunnel remote session are not accessible via localhost:<port> on the client end of the tunnel. This means the localhost:<port> redirect required by MSAL cannot work. I'm curious you seemed to indicate this does work?

I'd imagine because dev tunnel ports are forwarded only to the relay, and not the client. SSH forwarding happens peer-to-peer.

Copy link
Contributor

@dscho dscho left a comment

Choose a reason for hiding this comment

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

Looks good (even if I would have had a slight preference to keep the Trace changes in their own commit).

@mjcheetham mjcheetham merged commit cb802a1 into git-ecosystem:main Feb 6, 2026
10 checks passed
@mjcheetham mjcheetham deleted the linux-browser-fix branch February 6, 2026 12:08
@mjcheetham mjcheetham mentioned this pull request Feb 11, 2026
mjcheetham added a commit that referenced this pull request Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform:linux Specific to a Linux-based platform

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants