powerful but friendly backup program that runs in your tray, powered by restic devins.page/restray
go restic system-tray
2

Configure Feed

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

feat: check updates setting

intergrav (Jun 29, 2026, 6:46 AM EDT) bf7e6ca3 66bcba80

+23 -17
+7 -6
README.md
··· 42 42 43 43 ### `[general]` 44 44 45 - | Key | Type | Default | Description | 46 - | ------------------ | ------ | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | 47 - | `manage_restic` | bool | `false` | **Windows only.** If restic is not found in PATH, automatically downloads and updates a self-managed restic binary daily from GitHub. | 48 - | `notifications` | string | `"none"` | `"all"` (success + errors), `"errors"` (errors only), or `"none"` (silent) | 49 - | `schedule_display` | string | `"description"` | `"description"` (human-readable, e.g. "every 6 hours"), `"cron"` (raw expression, e.g. "0 \* \* \* \*"), or `"none"` | 50 - | `terminal` | string | `""` | Terminal emulator used in "Shell" and "View Log". If unset, MacOS will use `Terminal.app`. Linux will use default. Not used on Windows. e.g. "Ghostty" | 45 + | Key | Type | Default | Description | 46 + | ------------------ | ------ | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 47 + | `check_updates` | bool | `true` | **MacOS/Windows only.** Check for new Restray versions on startup and periodically. When an update is found, the version item in the menu changes to an update button | 48 + | `manage_restic` | bool | `false` | **Windows only.** If restic is not found in PATH, automatically downloads and updates a self-managed restic binary daily from GitHub. | 49 + | `notifications` | string | `"none"` | `"all"` (success + errors), `"errors"` (errors only), or `"none"` (silent) | 50 + | `schedule_display` | string | `"description"` | `"description"` (human-readable, e.g. "every 6 hours"), `"cron"` (raw expression, e.g. "0 \* \* \* \*"), or `"none"` | 51 + | `terminal` | string | `""` | Terminal emulator used in "Shell" and "View Log". If unset, MacOS will use `Terminal.app`. Linux will use default. Not used on Windows. e.g. "Ghostty" | 51 52 52 53 ### `[[profile]]` 53 54
+5
cmd/restray/config.go
··· 64 64 } 65 65 66 66 type General struct { 67 + CheckUpdates *bool `toml:"check_updates"` 67 68 ManageRestic bool `toml:"manage_restic"` 68 69 Notifications string `toml:"notifications"` 69 70 ScheduleDisplay string `toml:"schedule_display"` 70 71 Terminal string `toml:"terminal"` 72 + } 73 + 74 + func (g General) UpdatesEnabled() bool { 75 + return g.CheckUpdates == nil || *g.CheckUpdates 71 76 } 72 77 73 78 type Config struct {
+1
cmd/restray/templates/config.toml
··· 2 2 # Configuration reference: https://tangled.org/devins.page/restray#configuration 3 3 4 4 [general] 5 + # check_updates = true 5 6 # manage_restic = false 6 7 # notifications = "none" 7 8
+10 -11
cmd/restray/tray.go
··· 191 191 mFolder := mConfigure.AddSubMenuItem("Open Folder", "Open folder in file manager") 192 192 mAbout := mConfigure.AddSubMenuItem("Restray v"+version, "Open repository in browser") 193 193 systray.AddSeparator() 194 - mAppUpdate := systray.AddMenuItem("", "Download and install the latest version") 195 - mAppUpdate.Hide() 196 194 mQuit := systray.AddMenuItem("Quit", "Quit Restray") 197 195 198 196 sched := cron.New() ··· 666 664 case <-mFolder.ClickedCh: 667 665 openFile(configDir()) 668 666 case <-mAbout.ClickedCh: 669 - openFile("https://tangled.org/devins.page/restray") 670 - case <-mAppUpdate.ClickedCh: 671 - if v := latestKnownVersion.Load(); v != nil && applyUpdate(*v) { 672 - sched.Stop() 673 - stopAllMounts() 674 - systray.Quit() 667 + if v := latestKnownVersion.Load(); v != nil { 668 + if applyUpdate(*v) { 669 + sched.Stop() 670 + stopAllMounts() 671 + systray.Quit() 672 + } 673 + } else { 674 + openFile("https://tangled.org/devins.page/restray") 675 675 } 676 676 case <-mQuit.ClickedCh: 677 677 sched.Stop() ··· 681 681 } 682 682 }() 683 683 684 - if runtime.GOOS == "windows" || runtime.GOOS == "darwin" { 684 + if (runtime.GOOS == "windows" || runtime.GOOS == "darwin") && loadConfig().General.UpdatesEnabled() { 685 685 go func() { 686 686 check := func() { 687 687 latest, err := latestVersion() ··· 691 691 } 692 692 if compareVersion(latest, version) > 0 && artifactExists(artifactURL(latest)) { 693 693 latestKnownVersion.Store(&latest) 694 - mAppUpdate.SetTitle("Update to v" + latest) 695 - mAppUpdate.Show() 694 + mAbout.SetTitle("Update to v" + latest) 696 695 } 697 696 } 698 697 check()