aboutsummaryrefslogtreecommitdiffstats
path: root/systray_windows.go
diff options
context:
space:
mode:
authorfffw2015-02-13 15:20:13 +0800
committerfffw2015-02-13 15:20:13 +0800
commitc00cfb38ee3aee8da409898fed17e80716095e89 (patch)
treee6997d1ab53bfb8e1dfeafec7e239f8cfbc35838 /systray_windows.go
parent85d3e528d5a1d1ef8b60dcafc901c633343b4a37 (diff)
parent6a81309bde4a67b2d5d1cb57b2e89945ba63fde6 (diff)
downloadsystray-issue-2143-lib.tar.bz2
merge xcompileissue-2143-lib
Diffstat (limited to 'systray_windows.go')
-rw-r--r--systray_windows.go151
1 files changed, 151 insertions, 0 deletions
diff --git a/systray_windows.go b/systray_windows.go
new file mode 100644
index 0000000..9ae9520
--- /dev/null
+++ b/systray_windows.go
@@ -0,0 +1,151 @@
+package systray
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path"
+ "syscall"
+ "unsafe"
+
+ "github.com/getlantern/tarfs"
+)
+
+var (
+ iconFiles = make([]*os.File, 0)
+ dllDir = path.Join(os.Getenv("APPDATA"), "systray")
+ dllFile = path.Join(dllDir, "systray.dll")
+
+ mod = syscall.NewLazyDLL(dllFile)
+ _nativeLoop = mod.NewProc("nativeLoop")
+ _quit = mod.NewProc("quit")
+ _setIcon = mod.NewProc("setIcon")
+ _setTitle = mod.NewProc("setTitle")
+ _setTooltip = mod.NewProc("setTooltip")
+ _add_or_update_menu_item = mod.NewProc("add_or_update_menu_item")
+)
+
+func init() {
+ // Write DLL to file
+ fs, err := tarfs.New(systraydll, "")
+ if err != nil {
+ panic(fmt.Errorf("Unable to open systray.dll: %v", err))
+ }
+
+ b, err := fs.Get("systray.dll")
+ if err != nil {
+ panic(fmt.Errorf("Unable to read systray.dll: %v", err))
+ }
+
+ err = os.MkdirAll(dllDir, 755)
+ if err != nil {
+ panic(fmt.Errorf("Unable to create directory %v to hold systray.dll: %v", dllDir, err))
+ }
+
+ err = ioutil.WriteFile(dllFile, b, 0644)
+ if err != nil {
+ panic(fmt.Errorf("Unable to save systray.dll to %v: %v", dllFile, err))
+ }
+}
+
+func nativeLoop() {
+ _nativeLoop.Call(
+ syscall.NewCallback(systray_ready),
+ syscall.NewCallback(systray_menu_item_selected))
+}
+
+func quit() {
+ _quit.Call()
+ for _, f := range iconFiles {
+ err := os.Remove(f.Name())
+ if err != nil {
+ log.Debugf("Unable to delete temporary icon file %v: %v", f.Name(), err)
+ }
+ }
+}
+
+// SetIcon sets the systray icon.
+// iconBytes should be the content of .ico for windows and .ico/.jpg/.png
+// for other platforms.
+func SetIcon(iconBytes []byte) {
+ f, err := ioutil.TempFile("", "systray_temp_icon")
+ if err != nil {
+ log.Errorf("Unable to create temp icon: %v", err)
+ return
+ }
+ defer f.Close()
+ _, err = f.Write(iconBytes)
+ if err != nil {
+ log.Errorf("Unable to write icon to temp file %v: %v", f.Name(), f)
+ return
+ }
+ f.Close()
+ name, err := strPtr(f.Name())
+ if err != nil {
+ log.Errorf("Unable to convert name to string pointer: %v", err)
+ return
+ }
+ _setIcon.Call(name)
+}
+
+// SetTitle sets the systray title, only available on Mac.
+func SetTitle(title string) {
+ // do nothing
+}
+
+// SetTooltip sets the systray tooltip to display on mouse hover of the tray icon,
+// only available on Mac and Windows.
+func SetTooltip(tooltip string) {
+ t, err := strPtr(tooltip)
+ if err != nil {
+ log.Errorf("Unable to convert tooltip to string pointer: %v", err)
+ return
+ }
+ _setTooltip.Call(t)
+}
+
+func addOrUpdateMenuItem(item *MenuItem) {
+ var disabled = 0
+ if item.disabled {
+ disabled = 1
+ }
+ var checked = 0
+ if item.checked {
+ checked = 1
+ }
+ title, err := strPtr(item.title)
+ if err != nil {
+ log.Errorf("Unable to convert title to string pointer: %v", err)
+ return
+ }
+ tooltip, err := strPtr(item.tooltip)
+ if err != nil {
+ log.Errorf("Unable to convert tooltip to string pointer: %v", err)
+ return
+ }
+ _add_or_update_menu_item.Call(
+ uintptr(item.id),
+ title,
+ tooltip,
+ uintptr(disabled),
+ uintptr(checked),
+ )
+}
+
+func strPtr(s string) (uintptr, error) {
+ bp, err := syscall.BytePtrFromString(s)
+ if err != nil {
+ return 0, err
+ }
+ return uintptr(unsafe.Pointer(bp)), nil
+}
+
+func systray_ready() uintptr {
+ systrayReady()
+ return 0
+}
+
+func systray_menu_item_selected(id uintptr) uintptr {
+ systrayMenuItemSelected(int32(id))
+ return 0
+}