go-toast

Send toast notifications in Windows
Log | Files | Refs | README | LICENSE

commit bc9200482b415b309b45e1da61817f1fa8798c28
parent 8da8bfc2fa3fcce7958093e99235ec3290ccb578
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date:   Wed, 15 Mar 2023 18:23:32 +0800

toast: make API reflect global nature

This change makes the exported API reflect the global nature
of the state involved. Having a per Notification field as the
callback implies a coulping between the callback and the
Notification.

In reality, subsequent invocations will totally replace the prior
callback instance - so that API is misleading.

Instead we just offer a plain global function that sets the callback.

...

If a need arises we can implement some kind of routing so that
individual notification objects can have their own true callback.

Eg we would register a global callback that maintains a map of callbacks
corresponding to each indidual notification.

Signed-off-by: Jack Mordaunt <jackmordaunt.dev@gmail.com>

Diffstat:
Mcmd/toast-cli/main.go | 11++++++-----
Mtoast.go | 28+++++++++++++++++++---------
2 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/cmd/toast-cli/main.go b/cmd/toast-cli/main.go @@ -79,18 +79,19 @@ func main() { <-done }() - n.OnActivate = func(_ string, _ []toast.UserData) { - fmt.Printf("OnActivate\n") + toast.SetActivationCallback(func(args string, data []toast.UserData) { + fmt.Printf("OnActivate args: %q, userdata: %v\n", args, data) done <- struct{}{} - } + }) } else { - n.OnActivate = func(_ string, _ []toast.UserData) { + toast.SetActivationCallback(func(_ string, _ []toast.UserData) { fmt.Printf("OnActivate\n") - } + }) } if err := n.Push(); err != nil { fmt.Printf("error: %v\n", err) } + } diff --git a/toast.go b/toast.go @@ -86,10 +86,6 @@ type Notification struct { // This is an absolute path to an executable that will launched by the // Windows Runtime when the COM server is not running. ActivationExe string - - // OnActivate is a global activation callback. If supplied, it will be invoked when - // any notification is activated, not necessary _this_ one. - OnActivate func(args string, data []UserData) } // UserData contains user supplied data from the notification, such as text input @@ -179,13 +175,27 @@ func (n *Notification) Push() error { if err != nil { return err } - if n.OnActivate != nil { - bind.SetActivationCallback(func(_, args string, data []bind.UserData) { - n.OnActivate(args, data) - }) - } if err := bind.ConfigureRegistry(n.AppID, n.AppID, n.IconBackgroundColor, n.ActivationExe); err != nil { return fmt.Errorf("configuring registry: %w", err) } return bind.GenerateToast(n.AppID, xml) } + +// SetActivationCallback sets the global activation callback. +// +// The first argument contains application defined data (embedded within the xml), +// which is how the callback knows which part of the toast was activated. +// Argument data is defined by `toast.Action.Arguments` on the notification. +// +// The second argument contains user defined data (input/selected by user). +// All elements of user input will be supplied here, even if the value is empty. +// User inputs correspond to all `toast.Input`s defined on the notification. +// +// This function will be invoked when a toast notification is interacted with. +// +// This will do nothing if the the powershell fallback is in-effect. +func SetActivationCallback(cb func(args string, data []UserData)) { + bind.SetActivationCallback(func(appUserModelId, invokedArgs string, userData []bind.UserData) { + cb(invokedArgs, userData) + }) +}