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

Configure Feed

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

gtk: remove config wrappers

Aly Raffauf (Jul 5, 2026, 3:43 PM EDT) ea4f2b5f fb7381f9

+33 -53
-34
gtk/config.go
··· 3 3 package gtk 4 4 5 5 import ( 6 - "fmt" 7 - "os" 8 - 9 6 appconfig "github.com/alyraffauf/switchyard/internal/config" 10 7 "github.com/alyraffauf/switchyard/internal/routing" 11 8 ) ··· 14 11 type Redirection = routing.Redirection 15 12 type Condition = routing.Condition 16 13 type Rule = routing.Rule 17 - 18 - func configPath() string { 19 - return appconfig.Path() 20 - } 21 - 22 - func loadConfig() *Config { 23 - config, err := appconfig.Load(configPath()) 24 - if err != nil { 25 - fmt.Fprintf(os.Stderr, "Warning: Failed to parse config file: %v\n", err) 26 - fmt.Fprintf(os.Stderr, "Using default configuration\n") 27 - } 28 - return config 29 - } 30 - 31 - func saveConfig(config *Config) error { 32 - return appconfig.Save(configPath(), config) 33 - } 34 - 35 - func exportConfig(config *Config, path string) error { 36 - return appconfig.Export(path, config) 37 - } 38 - 39 - func importConfig(config *Config, path string) error { 40 - importedConfig, err := appconfig.Import(path) 41 - if err != nil { 42 - return err 43 - } 44 - 45 - *config = *importedConfig 46 - return saveConfig(config) 47 - }
+3 -2
gtk/dialog_default_browser.go
··· 3 3 package gtk 4 4 5 5 import ( 6 + appconfig "github.com/alyraffauf/switchyard/internal/config" 6 7 "github.com/alyraffauf/switchyard/internal/host" 7 8 "github.com/diamondburned/gotk4-adwaita/pkg/adw" 8 9 "github.com/diamondburned/gotk4/pkg/gtk/v4" ··· 28 29 if response == "yes" { 29 30 host.SetDefaultBrowser(getAppID()) 30 31 cfg.CheckDefaultBrowser = false 31 - saveConfig(cfg) 32 + appconfig.Save(appconfig.Path(), cfg) 32 33 updateUI() 33 34 } else if response == "no" { 34 35 cfg.CheckDefaultBrowser = false 35 - saveConfig(cfg) 36 + appconfig.Save(appconfig.Path(), cfg) 36 37 updateUI() 37 38 } 38 39 })
+3 -1
gtk/launcher_actions.go
··· 8 8 "strings" 9 9 10 10 appbrowser "github.com/alyraffauf/switchyard/internal/browser" 11 + appconfig "github.com/alyraffauf/switchyard/internal/config" 11 12 "github.com/diamondburned/gotk4-adwaita/pkg/adw" 12 13 "github.com/diamondburned/gotk4/pkg/gio/v2" 13 14 "github.com/diamondburned/gotk4/pkg/glib/v2" ··· 49 50 50 51 settingsAction := gio.NewSimpleAction("settings", nil) 51 52 settingsAction.ConnectActivate(func(p *glib.Variant) { 52 - showSettingsWindow(app, browsers, loadConfig()) 53 + cfg, _ := appconfig.Load(appconfig.Path()) 54 + showSettingsWindow(app, browsers, cfg) 53 55 }) 54 56 actionGroup.AddAction(settingsAction) 55 57
+3 -2
gtk/run.go
··· 8 8 "os" 9 9 "strings" 10 10 11 + appconfig "github.com/alyraffauf/switchyard/internal/config" 11 12 "github.com/alyraffauf/switchyard/internal/host" 12 13 "github.com/alyraffauf/switchyard/internal/routing" 13 14 "github.com/diamondburned/gotk4-adwaita/pkg/adw" ··· 33 34 }) 34 35 35 36 app.ConnectActivate(func() { 36 - cfg := loadConfig() 37 + cfg, _ := appconfig.Load(appconfig.Path()) 37 38 if cfg.StayAlive { 38 39 app.Hold() 39 40 } ··· 43 44 }) 44 45 45 46 app.ConnectOpen(func(files []gio.Filer, hint string) { 46 - cfg := loadConfig() 47 + cfg, _ := appconfig.Load(appconfig.Path()) 47 48 if cfg.StayAlive { 48 49 app.Hold() 49 50 }
+11 -5
gtk/settings_advanced.go
··· 7 7 "fmt" 8 8 "os" 9 9 10 + appconfig "github.com/alyraffauf/switchyard/internal/config" 10 11 "github.com/alyraffauf/switchyard/internal/host" 11 12 "github.com/diamondburned/gotk4-adwaita/pkg/adw" 12 13 "github.com/diamondburned/gotk4/pkg/gio/v2" ··· 21 22 22 23 configRow := adw.NewActionRow() 23 24 configRow.SetTitle("Configuration File") 24 - configRow.SetSubtitle(configPath()) 25 + configRow.SetSubtitle(appconfig.Path()) 25 26 configRow.SetActivatable(true) 26 27 configRow.AddSuffix(gtk.NewImageFromIconName("document-edit-symbolic")) 27 28 configRow.ConnectActivated(func() { 28 - saveConfig(cfg) 29 - cmd := host.HostCommand("xdg-open", configPath()) 29 + appconfig.Save(appconfig.Path(), cfg) 30 + cmd := host.HostCommand("xdg-open", appconfig.Path()) 30 31 if err := cmd.Start(); err != nil { 31 32 fmt.Printf("Failed to open config file: %v\n", err) 32 33 } ··· 54 55 if path == "" { 55 56 return 56 57 } 57 - if err := exportConfig(cfg, path); err != nil { 58 + if err := appconfig.Export(path, cfg); err != nil { 58 59 fmt.Fprintf(os.Stderr, "Failed to export config: %v\n", err) 59 60 } 60 61 }) ··· 90 91 91 92 warnDialog.ConnectResponse(func(response string) { 92 93 if response == "import" { 93 - if err := importConfig(cfg, path); err != nil { 94 + imported, err := appconfig.Import(path) 95 + if err == nil { 96 + *cfg = *imported 97 + err = appconfig.Save(appconfig.Path(), cfg) 98 + } 99 + if err != nil { 94 100 fmt.Fprintf(os.Stderr, "Failed to import config: %v\n", err) 95 101 } 96 102 }
+4 -3
gtk/settings_redirections.go
··· 6 6 "fmt" 7 7 "html" 8 8 9 + appconfig "github.com/alyraffauf/switchyard/internal/config" 9 10 "github.com/alyraffauf/switchyard/internal/routing" 10 11 "github.com/diamondburned/gotk4-adwaita/pkg/adw" 11 12 "github.com/diamondburned/gotk4/pkg/gtk/v4" ··· 78 79 upButton.ConnectClicked(func() { 79 80 if redirectionIndex > 0 { 80 81 cfg.Redirections[redirectionIndex], cfg.Redirections[redirectionIndex-1] = cfg.Redirections[redirectionIndex-1], cfg.Redirections[redirectionIndex] 81 - saveConfig(cfg) 82 + appconfig.Save(appconfig.Path(), cfg) 82 83 rebuildRedirectionsList() 83 84 } 84 85 }) ··· 92 93 downButton.ConnectClicked(func() { 93 94 if redirectionIndex < len(cfg.Redirections)-1 { 94 95 cfg.Redirections[redirectionIndex], cfg.Redirections[redirectionIndex+1] = cfg.Redirections[redirectionIndex+1], cfg.Redirections[redirectionIndex] 95 - saveConfig(cfg) 96 + appconfig.Save(appconfig.Path(), cfg) 96 97 rebuildRedirectionsList() 97 98 } 98 99 }) ··· 107 108 deleteButton.SetTooltipText("Remove") 108 109 deleteButton.ConnectClicked(func() { 109 110 cfg.Redirections = append(cfg.Redirections[:redirectionIndex], cfg.Redirections[redirectionIndex+1:]...) 110 - saveConfig(cfg) 111 + appconfig.Save(appconfig.Path(), cfg) 111 112 rebuildRedirectionsList() 112 113 }) 113 114 row.AddSuffix(deleteButton)
+4 -3
gtk/settings_rules.go
··· 6 6 "html" 7 7 8 8 appbrowser "github.com/alyraffauf/switchyard/internal/browser" 9 + appconfig "github.com/alyraffauf/switchyard/internal/config" 9 10 "github.com/alyraffauf/switchyard/internal/routing" 10 11 "github.com/diamondburned/gotk4-adwaita/pkg/adw" 11 12 "github.com/diamondburned/gotk4/pkg/gtk/v4" ··· 103 104 upBtn.ConnectClicked(func() { 104 105 if ruleIndex > 0 { 105 106 cfg.Rules[ruleIndex], cfg.Rules[ruleIndex-1] = cfg.Rules[ruleIndex-1], cfg.Rules[ruleIndex] 106 - saveConfig(cfg) 107 + appconfig.Save(appconfig.Path(), cfg) 107 108 rebuildRulesList() 108 109 } 109 110 }) ··· 117 118 downBtn.ConnectClicked(func() { 118 119 if ruleIndex < len(cfg.Rules)-1 { 119 120 cfg.Rules[ruleIndex], cfg.Rules[ruleIndex+1] = cfg.Rules[ruleIndex+1], cfg.Rules[ruleIndex] 120 - saveConfig(cfg) 121 + appconfig.Save(appconfig.Path(), cfg) 121 122 rebuildRulesList() 122 123 } 123 124 }) ··· 132 133 deleteBtn.SetTooltipText("Delete rule") 133 134 deleteBtn.ConnectClicked(func() { 134 135 cfg.Rules = append(cfg.Rules[:ruleIndex], cfg.Rules[ruleIndex+1:]...) 135 - saveConfig(cfg) 136 + appconfig.Save(appconfig.Path(), cfg) 136 137 rebuildRulesList() 137 138 }) 138 139 row.AddSuffix(deleteBtn)
+2 -1
gtk/ui_helpers.go
··· 3 3 package gtk 4 4 5 5 import ( 6 + appconfig "github.com/alyraffauf/switchyard/internal/config" 6 7 "github.com/diamondburned/gotk4-adwaita/pkg/adw" 7 8 coreglib "github.com/diamondburned/gotk4/pkg/core/glib" 8 9 "github.com/diamondburned/gotk4/pkg/gdk/v4" ··· 253 254 savingMux.Lock() 254 255 isSaving = true 255 256 savingMux.Unlock() 256 - saveConfig(cfg) 257 + appconfig.Save(appconfig.Path(), cfg) 257 258 glib.TimeoutAdd(100, func() bool { 258 259 savingMux.Lock() 259 260 isSaving = false
+3 -2
gtk/window_settings.go
··· 5 5 import ( 6 6 "context" 7 7 8 + appconfig "github.com/alyraffauf/switchyard/internal/config" 8 9 "github.com/alyraffauf/switchyard/internal/host" 9 10 "github.com/diamondburned/gotk4-adwaita/pkg/adw" 10 11 "github.com/diamondburned/gotk4/pkg/gio/v2" ··· 190 191 } 191 192 192 193 func watchConfigFile(cfg *Config, onChange func()) { 193 - configFile := gio.NewFileForPath(configPath()) 194 + configFile := gio.NewFileForPath(appconfig.Path()) 194 195 monitorIface, err := configFile.Monitor(context.Background(), gio.FileMonitorNone) 195 196 if err == nil && monitorIface != nil { 196 197 monitor := gio.BaseFileMonitor(monitorIface) ··· 204 205 return 205 206 } 206 207 207 - newCfg := loadConfig() 208 + newCfg, _ := appconfig.Load(appconfig.Path()) 208 209 *cfg = *newCfg 209 210 210 211 if onChange != nil {