fix(desktop): open default browser on startup by reddynitish · Pull Request #2095 · maplibre/maputnik · GitHub
Skip to content

fix(desktop): open default browser on startup - #2095

Merged
HarelM merged 3 commits into
maplibre:mainfrom
reddynitish:fix-desktop-open-browser-934
Aug 24, 2026
Merged

HarelM merged 3 commits into
maplibre:mainfrom
reddynitish:fix-desktop-open-browser-934

Conversation

@reddynitish

Copy link
Copy Markdown
Contributor

Fixes #934

Summary

The Go desktop binary started its local server and printed the URL,
but never opened a browser automatically.

This PR:

  • opens the default browser after the listener successfully binds
  • uses the actual runtime URL
  • uses a stdlib-only cross-platform launcher
  • keeps browser-open failures non-fatal
  • adds --no-browser for headless/Docker use
  • leaves the normal Vite/web development flow unchanged

The listener is created before launching the browser so the browser
cannot race the server startup path.

Platform behavior

  • Windows: rundll32 url.dll,FileProtocolHandler
  • macOS: open
  • Linux: xdg-open

No shell command strings are used; arguments are passed directly through
exec.Command.

Testing

  • go test ./...
  • go vet ./...
  • go build ./...
  • git diff --check
  • repeated manual Windows startup verification (3 clean runs, confirmed the
    browser opened and hit the server, no duplicate launches)
  • --no-browser verification (confirmed no launch attempt occurs)
  • non-fatal launcher failure covered by a unit test that injects a
    nonexistent opener binary

macOS/Linux launch paths were not runtime-tested on this Windows machine —
they follow the standard open/xdg-open convention used across other Go
CLIs but are unverified here. The full packaged release flow (gox,
go.rice, go-winres) was not exercised locally.

The Go desktop binary printed its URL but never launched a browser.
Add a stdlib-only, GOOS-dispatched opener, bind the listener before
opening to avoid a startup race, and add --no-browser for headless use.

Browser-launch failure remains non-fatal.

Fixes maplibre#934.
@codecov

codecov Bot commented Aug 22, 2026 •

Copy link
Copy Markdown

@HarelM

HarelM commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Thanks for taking the time to open this PR!

Is there a way to do it without being os specific?

Also worth de-vibing the excessive comments...

@HarelM

HarelM commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

I'm also not sure the tests are really valuable here...

Address review from maplibre#2095: replace the hand-rolled GOOS switch with
github.com/pkg/browser so this package carries no OS-specific launch
code of its own; run it in a goroutine since xdg-open is known to hang
on some headless Linux setups, so a stuck opener can't stall server
startup. Trim comments and collapse the tests to the one invariant
that actually matters: a failed/absent opener doesn't block or crash
the server.
@reddynitish

Copy link
Copy Markdown
Contributor Author

Thanks for the review — pushed 5d8048b addressing all three points:

  • OS-specific code: swapped the hand-rolled rundll32/open/xdg-open switch for github.com/pkg/browser. This package no longer has any OS-specific branching of its own; it's delegated to a maintained library. I kept the launch in a goroutine because pkg/browser calls cmd.Run() (blocking), and xdg-open is known to hang on some headless Linux setups — that goroutine is what keeps a stuck opener from stalling server startup, so it's not just leftover complexity.
  • Comments: trimmed the explanatory ones down, kept only what's non-obvious (why the goroutine exists).
  • Tests: dropped the OS-command-mapping tests since that logic now lives in the dependency, not here. Kept one: that a failing/missing opener doesn't block or crash the server. That's the one behavior e2e can't reach and the one this PR actually depends on being true.

Let me know if you'd rather see this simplified further (e.g. drop the goroutine/test entirely and accept the rare hang risk) — happy to go either way.

Comment thread desktop/browser_test.go Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is a thin wrapper on browser package, I think it's not worth the tests...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed — pushed e6ffc5b: removed both browser.go and browser_test.go, inlined the goroutine directly into maputnik.go's app.Action. It really was just a thin wrapper with no logic worth isolating or testing separately.

@HarelM

HarelM commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Per review: browser.go was a 21-line wrapper around pkg/browser with
no logic of its own, and browser_test.go was testing that wrapper
rather than project behavior. Inlined the goroutine directly into
maputnik.go's app.Action and removed both files.
@HarelM
HarelM merged commit 29cf3f1 into maplibre:main Aug 24, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Desktop version should open browser

2 participants