Files

60 lines
1.7 KiB
Go
Raw Permalink Normal View History

//go:build windows
package notify
import (
"fmt"
"sync"
"golang.org/x/sys/windows/registry"
)
// appIDKey is where Windows looks up the identity (name, icon) of an
// unpackaged program that shows toasts: HKCU, so no admin rights.
const appIDKey = `Software\Classes\AppUserModelId\` + AppID
var (
identityMu sync.Mutex
identityKnown bool
identityOK bool
)
// UseIcon registers talk's own toast identity for the current user: the
// AppUserModelID AppID with display name "talk" and the icon at iconPath.
// Toasts then appear as coming from talk instead of Windows PowerShell.
// Idempotent; rewritten on every call so it follows the icon's location.
func UseIcon(iconPath string) error {
setIconPath(iconPath)
k, _, err := registry.CreateKey(registry.CURRENT_USER, appIDKey, registry.SET_VALUE)
if err != nil {
return fmt.Errorf("registering toast identity: %w", err)
}
defer k.Close()
if err := k.SetStringValue("DisplayName", Title); err != nil {
return fmt.Errorf("registering toast identity: %w", err)
}
if err := k.SetStringValue("IconUri", iconPath); err != nil {
return fmt.Errorf("registering toast identity: %w", err)
}
identityMu.Lock()
identityKnown, identityOK = true, true
identityMu.Unlock()
return nil
}
// ownIdentity reports whether AppID is registered for this user (by this
// process or an earlier daemon start); checked once per process.
func ownIdentity() bool {
identityMu.Lock()
defer identityMu.Unlock()
if !identityKnown {
identityKnown = true
identityOK = false
if k, err := registry.OpenKey(registry.CURRENT_USER, appIDKey, registry.QUERY_VALUE); err == nil {
_, _, err := k.GetStringValue("IconUri")
identityOK = err == nil
k.Close()
}
}
return identityOK
}