fix(tray): support Windows socket paths and always run the tray companion on Windows
The tray IPC socket was hardcoded to /run/theta/tray.sock and /tmp/theta-tray.sock, which cannot be bound on Windows (they resolve to C:\run\... and C:\tmp\... and need admin rights). The daemon now binds a Unix socket under the per-user temp dir on Windows, and the tray companion dials the same path. The tray also exited immediately on Windows because it checked DISPLAY/WAYLAND_DISPLAY, which are never set there. That graphical-session guard is now Windows-only; the tray always runs on Windows.
This commit is contained in:
@@ -26,6 +26,8 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"fyne.io/systray"
|
||||
@@ -33,7 +35,16 @@ import (
|
||||
|
||||
// ── IPC types (duplicated from the main agent package; tray is its own binary) ──
|
||||
|
||||
const TraySocket = "/run/theta/tray.sock"
|
||||
// traySocketPaths returns the daemon IPC socket paths for this platform, in
|
||||
// the same order the daemon tries to bind them. Windows has no /run or /tmp,
|
||||
// so it uses a Unix socket under the per-user temp dir; Linux keeps the
|
||||
// original pair.
|
||||
func traySocketPaths() []string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return []string{filepath.Join(os.TempDir(), "theta-tray.sock")}
|
||||
}
|
||||
return []string{"/run/theta/tray.sock", "/tmp/theta-tray.sock"}
|
||||
}
|
||||
|
||||
type TrayColor string
|
||||
|
||||
@@ -73,8 +84,10 @@ var (
|
||||
// ── Main ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
func main() {
|
||||
// Silent exit if no graphical session is available.
|
||||
if os.Getenv("DISPLAY") == "" && os.Getenv("WAYLAND_DISPLAY") == "" {
|
||||
// Silent exit if no graphical session is available. Only meaningful on
|
||||
// X11/Wayland: Windows never sets these variables and the tray is simply
|
||||
// always a valid thing to run there.
|
||||
if runtime.GOOS != "windows" && os.Getenv("DISPLAY") == "" && os.Getenv("WAYLAND_DISPLAY") == "" {
|
||||
log.Println("theta-agent-tray: no graphical session detected (DISPLAY/WAYLAND_DISPLAY not set), exiting")
|
||||
os.Exit(0)
|
||||
}
|
||||
@@ -149,7 +162,7 @@ func onReady() {
|
||||
// between attempts. On connect it streams status updates until the connection
|
||||
// drops, then retries.
|
||||
func connectWithRetry() {
|
||||
socketPaths := []string{"/run/theta/tray.sock", "/tmp/theta-tray.sock"}
|
||||
socketPaths := traySocketPaths()
|
||||
for {
|
||||
var conn net.Conn
|
||||
var err error
|
||||
|
||||
+25
-7
@@ -7,15 +7,33 @@ package main
|
||||
// Protocol: newline-delimited JSON. The daemon streams TrayStatus messages to
|
||||
// any connected tray client. The tray sends TrayCommand messages to the daemon.
|
||||
|
||||
import "encoding/json"
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// TraySocket is the path to the IPC socket the daemon listens on.
|
||||
// Falls back to /tmp/theta-tray.sock if /run/theta/ is not writable.
|
||||
var TraySocketPaths = []string{
|
||||
"/run/theta/tray.sock",
|
||||
"/tmp/theta-tray.sock",
|
||||
// TraySocketPaths are the paths the daemon tries to bind, in order.
|
||||
//
|
||||
// Windows has no /run or /tmp; a Unix socket in the per-user temp dir works
|
||||
// there (AF_UNIX is supported since Windows 10 1803) and needs no admin
|
||||
// rights. Linux keeps the original /run/theta path with a /tmp fallback.
|
||||
var TraySocketPaths = func() []string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return []string{filepath.Join(os.TempDir(), "theta-tray.sock")}
|
||||
}
|
||||
const TraySocket = "/tmp/theta-tray.sock"
|
||||
return []string{"/run/theta/tray.sock", "/tmp/theta-tray.sock"}
|
||||
}()
|
||||
|
||||
// TraySocket is the canonical socket path the tray dials. It matches the last
|
||||
// entry in TraySocketPaths on each platform.
|
||||
var TraySocket = func() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return filepath.Join(os.TempDir(), "theta-tray.sock")
|
||||
}
|
||||
return "/tmp/theta-tray.sock"
|
||||
}()
|
||||
|
||||
|
||||
// TrayColor represents the icon color state.
|
||||
|
||||
Reference in New Issue
Block a user