diff --git a/notify_windows.go b/notify_windows.go index fe37067..266c101 100644 --- a/notify_windows.go +++ b/notify_windows.go @@ -4,10 +4,13 @@ import ( "runtime" "syscall" "unsafe" + + "github.com/ncruces/zenity/internal/zenutil" ) var ( shellNotifyIcon = shell32.NewProc("Shell_NotifyIconW") + wtsSendMessage = wtsapi32.NewProc("WTSSendMessageW") ) func notify(text string, options []Option) error { @@ -44,7 +47,7 @@ func notify(text string, options []Option) error { s, _, err := shellNotifyIcon.Call(0 /* NIM_ADD */, uintptr(unsafe.Pointer(&args))) if s == 0 { if errno, ok := err.(syscall.Errno); ok && errno == 0 { - _, err = Info(text, Title(opts.title), Icon(opts.icon)) + return wtsMessage(text, opts) } return err } @@ -53,6 +56,47 @@ func notify(text string, options []Option) error { return nil } +func wtsMessage(text string, opts options) error { + var flags uintptr + + switch opts.icon { + case ErrorIcon: + flags |= 0x10 // MB_ICONERROR + case QuestionIcon: + flags |= 0x20 // MB_ICONQUESTION + case WarningIcon: + flags |= 0x30 // MB_ICONWARNING + case InfoIcon: + flags |= 0x40 // MB_ICONINFORMATION + } + + title := opts.title + if title == "" { + title = "Notification" + } + + timeout := zenutil.Timeout + if timeout == 0 { + timeout = 10 + } + + ptext := syscall.StringToUTF16(text) + ptitle := syscall.StringToUTF16(title) + + var res uint32 + s, _, err := wtsSendMessage.Call( + 0, // WTS_CURRENT_SERVER_HANDLE + 0xffffffff, // WTS_CURRENT_SESSION + uintptr(unsafe.Pointer(&ptitle[0])), uintptr(2*len(ptitle)), + uintptr(unsafe.Pointer(&ptext[0])), uintptr(2*len(ptext)), + flags, uintptr(timeout), uintptr(unsafe.Pointer(&res)), 0) + + if s == 0 { + return err + } + return nil +} + type _NOTIFYICONDATA struct { StructSize uint32 Owner uintptr diff --git a/util_windows.go b/util_windows.go index 46d6113..cb6c928 100644 --- a/util_windows.go +++ b/util_windows.go @@ -14,6 +14,7 @@ var ( ole32 = syscall.NewLazyDLL("ole32.dll") shell32 = syscall.NewLazyDLL("shell32.dll") user32 = syscall.NewLazyDLL("user32.dll") + wtsapi32 = syscall.NewLazyDLL("wtsapi32.dll") commDlgExtendedError = comdlg32.NewProc("CommDlgExtendedError")