Turn the desktop client into a system tray application
Started without a command, keeporg now shows a padlock in the system tray with a menu like midi-webhook's: a status line, the mirror folder, each database with its state, Sync Now, browser sign-in and sign-out, the web interface, the configuration, the log, Start at Login, About and Quit. The commands are unchanged. config.json now carries every client setting (device_label, request_timeout_seconds, ca_file, log_file, notifications), is written in full on first start and is reloaded by the tray when saved. A lock in the mirror directory admits one agent at a time, since the tray, `keeporg run` and a service unit could otherwise race each other. The tray uses fyne.io/systray: pure Go on Linux, BSD and Windows, cgo on macOS only. The server keeps no third-party dependencies. Desktop versions go to 0.5.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d314188247
commit
ead82dc777
@@ -0,0 +1,46 @@
|
||||
// Command genicon writes the application icon for packaging.
|
||||
//
|
||||
// genicon -hicolor <dir> <dir>/<n>x<n>/apps/keeporg.png, the Linux icon theme layout
|
||||
// genicon -iconset <dir> <dir>/icon_<n>x<n>[@2x].png, the input iconutil turns into .icns
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"cc.tiredsysadmin.keeporg/internal/icon"
|
||||
)
|
||||
|
||||
func main() {
|
||||
hicolor := flag.String("hicolor", "", "write a hicolor icon theme tree under this directory")
|
||||
iconset := flag.String("iconset", "", "write a macOS .iconset directory")
|
||||
flag.Parse()
|
||||
if *hicolor == "" && *iconset == "" {
|
||||
flag.Usage()
|
||||
os.Exit(2)
|
||||
}
|
||||
if *hicolor != "" {
|
||||
for _, n := range []int{16, 32, 48, 64, 128, 256, 512} {
|
||||
write(filepath.Join(*hicolor, fmt.Sprintf("%dx%d", n, n), "apps", "keeporg.png"), n)
|
||||
}
|
||||
}
|
||||
if *iconset != "" {
|
||||
for _, n := range []int{16, 32, 128, 256, 512} {
|
||||
write(filepath.Join(*iconset, fmt.Sprintf("icon_%dx%d.png", n, n)), n)
|
||||
write(filepath.Join(*iconset, fmt.Sprintf("icon_%dx%d@2x.png", n, n)), 2*n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func write(path string, size int) {
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "genicon:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := os.WriteFile(path, icon.PNG(icon.App(size)), 0o644); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "genicon:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user