aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkali2018-11-08 20:36:30 +0100
committerKali Kaneko2018-11-14 20:42:10 +0100
commitf5df9ef609c410eddc16af7681008f4ea58fe49c (patch)
tree1d9acf5e65c90fbb9aeed6909bbb3c63f20161cc
parent19c034af4717bf1737fc722e1804f5eb57e3bec5 (diff)
downloadsystray-f5df9ef609c410eddc16af7681008f4ea58fe49c.tar.bz2
keep a slice with the visible items to fix positioning bug
in windows, Hide() destroys a menuItem. this has problems when later we try to Show() it and end up using the original menuID, for instance if we did hide several elements in a row: if we insert the element in the original position, it will end up inserted past some other elements that were intended to be placed after the items that were hidden. by keeping a slice where we insert and delete the id of the elements that are shown, we can sort this slice and take the index of a given element as the correct index in which we want to insert the menuItem when calling Show() again. - Resolves: #72
-rw-r--r--systray_windows.go58
1 files changed, 41 insertions, 17 deletions
diff --git a/systray_windows.go b/systray_windows.go
index 26a0f80..9d560b7 100644
--- a/systray_windows.go
+++ b/systray_windows.go
@@ -8,6 +8,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "sort"
"syscall"
"unsafe"
@@ -172,6 +173,8 @@ type winTray struct {
wmSystrayMessage,
wmTaskbarCreated uint32
+
+ visibleItems []uint32
}
// Loads an image from file and shows it in tray.
@@ -462,29 +465,25 @@ func (t *winTray) addOrUpdateMenuItem(menuId int32, title string, disabled, chec
}
mi.Size = uint32(unsafe.Sizeof(mi))
- // The return value is the identifier of the specified menu item.
- // If the menu item identifier is NULL or if the specified item opens a submenu, the return value is -1.
- // If the given menu identifier is not found (becase we deleted the menu item when hiding it),
- // the call will return the next integer that is available as an existing menu item.
- res, _, err := pGetMenuItemID.Call(uintptr(t.menu), uintptr(menuId))
- if int32(res) == -1 || int32(res) != menuId {
+ // We set the menu item info based on the menuID
+ res, _, err := pSetMenuItemInfo.Call(
+ uintptr(t.menu),
+ uintptr(menuId),
+ 0,
+ uintptr(unsafe.Pointer(&mi)),
+ )
+
+ if res == 0 {
+ t.addToVisibleItems(menuId)
+ position := t.getVisibleItemIndex(menuId)
res, _, err = pInsertMenuItem.Call(
uintptr(t.menu),
- uintptr(menuId),
+ uintptr(position),
1,
uintptr(unsafe.Pointer(&mi)),
)
if res == 0 {
- return err
- }
- } else {
- res, _, err = pSetMenuItemInfo.Call(
- uintptr(t.menu),
- uintptr(menuId),
- 0,
- uintptr(unsafe.Pointer(&mi)),
- )
- if res == 0 {
+ t.delFromVisibleItems(menuId)
return err
}
}
@@ -535,6 +534,7 @@ func (t *winTray) hideMenuItem(menuId int32) error {
if res == 0 && err.(syscall.Errno) != ERROR_SUCCESS {
return err
}
+ t.delFromVisibleItems(menuId)
return nil
}
@@ -567,6 +567,30 @@ func (t *winTray) showMenu() error {
return nil
}
+func (t *winTray) delFromVisibleItems(val int32) {
+ for i, itemval := range t.visibleItems {
+ if uint32(val) == itemval {
+ t.visibleItems = append(t.visibleItems[:i], t.visibleItems[i+1:]...)
+ break
+ }
+ }
+}
+
+func (t *winTray) addToVisibleItems(val int32) {
+ newvisible := append(t.visibleItems, uint32(val))
+ sort.Slice(newvisible, func(i, j int) bool { return newvisible[i] < newvisible[j] })
+ t.visibleItems = newvisible
+}
+
+func (t *winTray) getVisibleItemIndex(val int32) int {
+ for i, itemval := range t.visibleItems {
+ if uint32(val) == itemval {
+ return i
+ }
+ }
+ return -1
+}
+
func nativeLoop() {
if err := wt.initInstance(); err != nil {
log.Errorf("Unable to init instance: %v", err)