feat(notify): Windows toasts under talk's own identity, icon on Linux
release / release (push) Canceled after 0s
test / test (push) Canceled after 0s

The daemon (and talk test --toast) now register the AppUserModelID
m3ta.talk under HKCU with display name and the installed icon, so
toasts appear as "talk" with the icon instead of Windows PowerShell;
the PowerShell identity stays as fallback until the registration has
run once. The redundant "talk" title line is dropped under the own
identity. notify.Setup bundles icon install, identity and the talk:
protocol handler for both callers. Linux notifications carry the
installed icon as app_icon. doctor names the active identity.

Verified on the Windows 11 VM: registry key, icon file, toast with
working Cancel button, exe icon; Linux via quickshell.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
m3ta-chironandClaude Fable 5.1 committed 2026-10-25 12:43:14 +01:00
1 parent 2e77cf0a11
commit 2d9d2a86e9
10 files changed
+290 -48

No files matched your search

+11 -2
View File
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"time"
@@ -50,7 +51,7 @@ func runTest(args []string, opts *sayOptions, _ io.Reader, stdout, stderr io.Wri
lang = cfg.Lang
}
if opts.toast {
return runToastTest(lang, stdout, stderr)
return runToastTest(lang, getenv, stdout, stderr)
}
if dir, err := config.Dir(getenv); err == nil {
if (queue.MuteStore{Path: filepath.Join(dir, queue.MuteFileName)}).Muted() {
@@ -92,7 +93,15 @@ func runTest(args []string, opts *sayOptions, _ io.Reader, stdout, stderr io.Wri
// gets one (with a Cancel button where supported), waits a few seconds for a
// click and reports what happened. Exit 1 when no tool exists or the call
// fails.
func runToastTest(lang string, stdout, stderr io.Writer) int {
func runToastTest(lang string, getenv func(string) string, stdout, stderr io.Writer) int {
// Same desktop setup as the daemon, so the test shows what announcements
// will show (icon, identity, Cancel button).
if dir, err := config.Dir(getenv); err == nil {
exe, _ := os.Executable()
if err := notify.Setup(dir, exe); err != nil {
fmt.Fprintf(stderr, "talk test: %v\n", err)
}
}
fmt.Fprintf(stdout, "toast: %s\n", notify.Describe())
if !notify.Available() {
fmt.Fprintln(stderr, "talk test: no notification path found; on Linux install libnotify (notify-send) or run a notification daemon, macOS and Windows have one built in")