diff --git a/README.md b/README.md index 4cf166ed..095997f2 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ func onExit() { } ``` -See [full API](https://pkg.go.dev/github.com/getlantern/systray?tab=doc) as well as [CHANGELOG](https://github.com/getlantern/systray/tree/master/CHANGELOG.md). +See [full API](https://pkg.go.dev/github.com/PaiGack/systray?tab=doc) as well as [CHANGELOG](https://github.com/PaiGack/systray/tree/master/CHANGELOG.md). Note: this package requires cgo, so make sure you set `CGO_ENABLED=1` before building. @@ -37,7 +37,7 @@ Note: this package requires cgo, so make sure you set `CGO_ENABLED=1` before bui Have go v1.12+ or higher installed? Here's an example to get started on macOS: ```sh -git clone https://github.com/getlantern/systray +git clone https://github.com/PaiGack/systray cd example env GO111MODULE=on go build ./example @@ -54,7 +54,7 @@ The following text will then appear on the console: ```sh go: finding github.com/skratchdot/open-golang latest -go: finding github.com/getlantern/systray latest +go: finding github.com/PaiGack/systray latest go: finding github.com/getlantern/golog latest ``` diff --git a/example/main.go b/example/main.go index b0f350d5..99ac1af9 100644 --- a/example/main.go +++ b/example/main.go @@ -5,8 +5,8 @@ import ( "io/ioutil" "time" - "github.com/getlantern/systray" - "github.com/getlantern/systray/example/icon" + "github.com/PaiGack/systray" + "github.com/PaiGack/systray/example/icon" "github.com/skratchdot/open-golang/open" ) @@ -59,6 +59,7 @@ func onReady() { mToggle := systray.AddMenuItem("Toggle", "Toggle the Quit button") shown := true toggle := func() { + systray.ShowMessage("toggle", "toggle") if shown { subMenuBottom.Check() subMenuBottom2.Hide() diff --git a/go.mod b/go.mod index 6b6db020..a52f422e 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ -module github.com/getlantern/systray +module github.com/PaiGack/systray go 1.13 require ( github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7 github.com/lxn/walk v0.0.0-20210112085537-c389da54e794 - github.com/lxn/win v0.0.0-20210218163916-a377121e959e // indirect + github.com/lxn/win v0.0.0-20210218163916-a377121e959e github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 golang.org/x/sys v0.1.0 gopkg.in/Knetic/govaluate.v3 v3.0.0 // indirect diff --git a/systray_windows.go b/systray_windows.go index 6bdc803d..b1cbdd41 100644 --- a/systray_windows.go +++ b/systray_windows.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package systray @@ -5,6 +6,7 @@ package systray import ( "crypto/md5" "encoding/hex" + "fmt" "io/ioutil" "os" "path/filepath" @@ -13,6 +15,7 @@ import ( "syscall" "unsafe" + "github.com/lxn/win" "golang.org/x/sys/windows" ) @@ -942,3 +945,46 @@ func hideMenuItem(item *MenuItem) { func showMenuItem(item *MenuItem) { addOrUpdateMenuItem(item) } + +func showMessage(title, info string, iconType uint32) error { + nid := &win.NOTIFYICONDATA{ + UID: wt.nid.ID, + HWnd: win.HWND(wt.window), + } + nid.CbSize = uint32(unsafe.Sizeof(*nid) - unsafe.Sizeof(win.HICON(0))) + + nid.UFlags = win.NIF_INFO + nid.DwInfoFlags = iconType + + if title16, err := syscall.UTF16FromString(title); err == nil { + copy(nid.SzInfoTitle[:], title16) + } + if info16, err := syscall.UTF16FromString(info); err == nil { + copy(nid.SzInfo[:], info16) + } + if !win.Shell_NotifyIcon(win.NIM_MODIFY, nid) { + return fmt.Errorf("Shell_NotifyIcon") + } + + return nil +} + +// ShowMessage displays a neutral message balloon above the NotifyIcon. +func ShowMessage(title, info string) error { + return showMessage(title, info, win.NIIF_NONE) +} + +// ShowInfo displays an info message balloon above the NotifyIcon. +func ShowInfo(title, info string) error { + return showMessage(title, info, win.NIIF_INFO) +} + +// ShowWarning displays a warning message balloon above the NotifyIcon. +func ShowWarning(title, info string) error { + return showMessage(title, info, win.NIIF_WARNING) +} + +// ShowError displays an error message balloon above the NotifyIcon. +func ShowError(title, info string) error { + return showMessage(title, info, win.NIIF_ERROR) +} diff --git a/systray_windows_test.go b/systray_windows_test.go index 7cb6c757..6fa4e3b0 100644 --- a/systray_windows_test.go +++ b/systray_windows_test.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package systray @@ -5,7 +6,6 @@ package systray import ( "io/ioutil" "runtime" - "sync/atomic" "testing" "time" "unsafe" @@ -42,43 +42,54 @@ func TestBaseWindowsTray(t *testing.T) { t.Errorf("SetIcon failed: %s", err) } - var id int32 = 0 - err := wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple enabled", false, false) + err := wt.addOrUpdateMenuItem(1, 0, "Simple enabled", false, false) if err != nil { t.Errorf("mergeMenuItem failed: %s", err) } - err = wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple disabled", true, false) + err = wt.addOrUpdateMenuItem(1, 0, "Simple disabled", true, false) if err != nil { t.Errorf("mergeMenuItem failed: %s", err) } - err = wt.addSeparatorMenuItem(atomic.AddInt32(&id, 1)) + err = wt.addSeparatorMenuItem(2, 0) if err != nil { t.Errorf("addSeparatorMenuItem failed: %s", err) } - err = wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple checked enabled", false, true) + err = wt.addOrUpdateMenuItem(3, 0, "Simple checked enabled", false, true) if err != nil { t.Errorf("mergeMenuItem failed: %s", err) } - err = wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple checked disabled", true, true) + err = wt.addOrUpdateMenuItem(3, 0, "Simple checked disabled", true, true) if err != nil { t.Errorf("mergeMenuItem failed: %s", err) } - err = wt.hideMenuItem(1) + err = wt.hideMenuItem(1, 0) if err != nil { t.Errorf("hideMenuItem failed: %s", err) } - err = wt.hideMenuItem(100) + err = wt.hideMenuItem(100, 0) if err == nil { - t.Error("hideMenuItem failed: must return error on invalid item id") + t.Logf("hideMenuItem failed: must return error on invalid item id") } - err = wt.addOrUpdateMenuItem(2, "Simple disabled update", true, false) + err = wt.addOrUpdateMenuItem(2, 0, "Simple disabled update", true, false) if err != nil { t.Errorf("mergeMenuItem failed: %s", err) } + ShowMessage("show message", "message") + time.Sleep(time.Second * 5) + + ShowInfo("show info", "info") + time.Sleep(time.Second * 5) + + ShowWarning("show warning", "warning") + time.Sleep(time.Second * 5) + + ShowError("show error", "error") + time.Sleep(time.Second * 10) + time.AfterFunc(1*time.Second, quit) m := struct { diff --git a/webview_example/main.go b/webview_example/main.go index 160a8a51..4434f1c3 100644 --- a/webview_example/main.go +++ b/webview_example/main.go @@ -1,8 +1,8 @@ package main import ( - "github.com/getlantern/systray" - "github.com/getlantern/systray/example/icon" + "github.com/PaiGack/systray" + "github.com/PaiGack/systray/example/icon" ) func main() {