diff --git a/notify_unix.go b/notify_unix.go index 04dffd6..6b2946f 100644 --- a/notify_unix.go +++ b/notify_unix.go @@ -5,16 +5,28 @@ package beeep import ( "errors" + "strconv" + "time" + "os/exec" "github.com/godbus/dbus/v5" ) -// Notify sends desktop notification. +// Notify sends desktop notification with default timeout // // On Linux it tries to send notification via D-Bus and it will fallback to `notify-send` binary. func Notify(title, message, appIcon string) error { + return NotifyEx(title, message, appIcon, -1) +} + +// NotifyEx sends notification with timeout +func NotifyEx(title, message, appIcon string, timeout time.Duration) error { appIcon = pathAbs(appIcon) + if timeout > 0 { + timeout = timeout / time.Millisecond + } + timeOut := strconv.Itoa(int(timeout)) cmd := func() error { send, err := exec.LookPath("sw-notify-send") @@ -25,7 +37,7 @@ func Notify(title, message, appIcon string) error { } } - c := exec.Command(send, title, message, "-i", appIcon) + c := exec.Command(send, title, message, "-i", appIcon, "-t", timeOut) return c.Run() } @@ -34,7 +46,8 @@ func Notify(title, message, appIcon string) error { if err != nil { return err } - c := exec.Command(send, "--title", title, "--passivepopup", message, "10", "--icon", appIcon) + c := exec.Command(send, "--title", title, "--passivepopup", + message, strconv.Itoa(int(timeout/1e3)), "--icon", appIcon) return c.Run() } @@ -44,7 +57,8 @@ func Notify(title, message, appIcon string) error { } obj := conn.Object("org.freedesktop.Notifications", dbus.ObjectPath("/org/freedesktop/Notifications")) - call := obj.Call("org.freedesktop.Notifications.Notify", 0, "", uint32(0), appIcon, title, message, []string{}, map[string]dbus.Variant{}, int32(-1)) + call := obj.Call("org.freedesktop.Notifications.Notify", + 0, "", uint32(0), appIcon, title, message, []string{}, map[string]dbus.Variant{}, int32(timeout)) if call.Err != nil { e := cmd() if e != nil { diff --git a/notify_unix_nodbus.go b/notify_unix_nodbus.go index 8daff29..18afbfa 100644 --- a/notify_unix_nodbus.go +++ b/notify_unix_nodbus.go @@ -6,11 +6,22 @@ package beeep import ( "errors" "os/exec" + "strconv" + "time" ) -// Notify sends desktop notification. +// Notify sends desktop notification with default timeout func Notify(title, message, appIcon string) error { + return NotifyEx(title, message, appIcon, -1) +} + +// NotifyEx sends desktop notification with timeout +func NotifyEx(title, message, appIcon string, timeout time.Duration) error { appIcon = pathAbs(appIcon) + if timeout > 0 { + timeout = timeout / time.Millisecond + } + timeOut := strconv.FormatInt(int64(timeout), 10) cmd := func() error { send, err := exec.LookPath("sw-notify-send") @@ -21,7 +32,7 @@ func Notify(title, message, appIcon string) error { } } - c := exec.Command(send, title, message, "-i", appIcon) + c := exec.Command(send, title, message, "-i", appIcon, "-t", timeOut) return c.Run() } @@ -30,7 +41,7 @@ func Notify(title, message, appIcon string) error { if err != nil { return err } - c := exec.Command(send, "--title", title, "--passivepopup", message, "10", "--icon", appIcon) + c := exec.Command(send, "--title", title, "--passivepopup", message, strconv.Itoa(timeout/1e3), "--icon", appIcon) return c.Run() } diff --git a/notify_windows.go b/notify_windows.go index fa14584..eaaf2ff 100644 --- a/notify_windows.go +++ b/notify_windows.go @@ -7,6 +7,7 @@ import ( "bufio" "bytes" "errors" + "fmt" "os/exec" "strings" "syscall" @@ -39,15 +40,20 @@ func init() { } } -// Notify sends desktop notification. +// Notify sends desktop notification with default timeout func Notify(title, message, appIcon string) error { + return NotifyEx(title, message, appIcon, 3*time.Second) +} + +// NotifyEx sends desktop notification with timeout +func NotifyEx(title, message, appIcon string, timeout time.Duration) error { if isWindows10 { return toastNotify(title, message, appIcon) } err := baloonNotify(title, message, appIcon, false) if err != nil { - e := msgNotify(title, message) + e := msgNotify(title, message, timeout) if e != nil { return errors.New("beeep: " + err.Error() + "; " + e.Error()) } @@ -57,12 +63,16 @@ func Notify(title, message, appIcon string) error { } -func msgNotify(title, message string) error { +func msgNotify(title, message string, timeout time.Duration) error { msg, err := exec.LookPath("msg") if err != nil { return err } - cmd := exec.Command(msg, "*", "/TIME:3", title+"\n\n"+message) + if timeout <= 0 { + timeout = time.Second * 3 + } + + cmd := exec.Command(msg, "*", fmt.Sprintf("/TIME:%d", timeout/time.Second), title+"\n\n"+message) cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} return cmd.Run() }