Files
kage/viewer/browser.go
T
Duc-Tam Nguyen 5b7f7d9f31 Add an optional native-window viewer behind the webview tag
A packed binary opened the system browser, so it felt like a tab, not
an app. Build with -tags webview (cgo) and the viewer instead opens the
site in its own window backed by the OS WebView: WKWebView on macOS,
WebView2 on Windows, WebKitGTK on Linux.

The viewer package picks an implementation at build time. The default
file opens the browser and keeps the build pure Go, so CGO_ENABLED=0 and
the release pipeline are untouched. The webview file links the platform
WebView and runs its event loop on the main goroutine, which main now
pins with LockOSThread before anything else, since macOS requires UI on
the initial thread. Both kage open and the embedded viewer serve over
HTTP in a goroutine and hand the URL to the viewer, then tear the server
down when the window closes or Ctrl-C cancels.

The window title comes from the archive's M/Title. OpenInBrowser moves
out of pack into the viewer package, its only caller.
2026-06-14 21:07:53 +07:00

42 lines
1.0 KiB
Go

//go:build !webview
package viewer
import (
"context"
"os/exec"
"runtime"
)
// Native is false in the default pure-Go build: there is no native window, so
// the viewer hands the URL to the system browser.
const Native = false
// LockMainThread is a no-op without a native UI to pin to the main thread.
func LockMainThread() {}
// Show opens the system browser at o.URL when o.Browser is set, then blocks
// until the context is cancelled (Ctrl-C), leaving the caller's HTTP server up
// in the meantime. Launching the browser is best-effort; a failure is ignored
// because the URL has already been printed for the user to open by hand.
func Show(ctx context.Context, o Options) error {
if o.Browser {
_ = openInBrowser(o.URL)
}
<-ctx.Done()
return nil
}
func openInBrowser(url string) error {
var cmd *exec.Cmd
switch runtime.GOOS {
case "darwin":
cmd = exec.Command("open", url)
case "windows":
cmd = exec.Command("rundll32", "url.dll,FileProtocolHandler", url)
default:
cmd = exec.Command("xdg-open", url)
}
return cmd.Start()
}