Rules-based browser launcher for TUI + GNOME. switchyard.aly.codes
tui gnome bowser go
0

Configure Feed

Select the types of activity you want to include in your feed.

add abstracted launchCommand for handling xdg vars and flatpak launches

Aly Raffauf (Jan 16, 2026, 1:23 AM EST) 92c9a2b5 6d9ad475

+59
+59
src/launch.go
··· 1 + // SPDX-License-Identifier: GPL-3.0-or-later 2 + 3 + package main 4 + 5 + import ( 6 + "os" 7 + "os/exec" 8 + "strings" 9 + 10 + "github.com/diamondburned/gotk4/pkg/gdk/v4" 11 + "github.com/diamondburned/gotk4/pkg/gio/v2" 12 + ) 13 + 14 + // launchCommand executes a desktop file command line with URL substitution 15 + // and proper activation token handling for window raising on Wayland. 16 + func launchCommand(cmdline, url string, appInfo *gio.AppInfo) error { 17 + // Replace %u, %U, %f, %F with URL 18 + cmdline = strings.ReplaceAll(cmdline, "%u", url) 19 + cmdline = strings.ReplaceAll(cmdline, "%U", url) 20 + cmdline = strings.ReplaceAll(cmdline, "%f", url) 21 + cmdline = strings.ReplaceAll(cmdline, "%F", url) 22 + 23 + // Remove other field codes 24 + for _, code := range []string{"%i", "%c", "%k"} { 25 + cmdline = strings.ReplaceAll(cmdline, code, "") 26 + } 27 + 28 + // Parse the command line 29 + parts := strings.Fields(cmdline) 30 + if len(parts) == 0 { 31 + return nil 32 + } 33 + 34 + // Get activation token from GDK launch context for window raising on Wayland 35 + var activationToken string 36 + if display := gdk.DisplayGetDefault(); display != nil { 37 + activationToken = display.AppLaunchContext().StartupNotifyID(appInfo, nil) 38 + } 39 + 40 + // When running in Flatpak, wrap with flatpak-spawn --host 41 + // and pass activation token via --env flag 42 + if os.Getenv("FLATPAK_ID") != "" && !strings.HasPrefix(parts[0], "flatpak-spawn") { 43 + parts = append([]string{"flatpak-spawn", "--host", "--env=XDG_ACTIVATION_TOKEN=" + activationToken}, parts...) 44 + activationToken = "" // Already handled via flatpak-spawn 45 + } 46 + 47 + // Execute the command 48 + cmd := exec.Command(parts[0], parts[1:]...) 49 + if activationToken != "" { 50 + cmd.Env = append(os.Environ(), "XDG_ACTIVATION_TOKEN="+activationToken) 51 + } 52 + 53 + if err := cmd.Start(); err != nil { 54 + return err 55 + } 56 + 57 + go cmd.Wait() 58 + return nil 59 + }