60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
//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
|
||
|
|
}
|