Files
autoPriority/tray_native_test.go
T

71 lines
1.7 KiB
Go

//go:build windows
package main
import (
"os"
"sync"
"testing"
"time"
"unsafe"
)
func requireNativeGUI(t *testing.T) {
t.Helper()
if os.Getenv("AP_NATIVE_GUI") != "1" {
t.Skip("opt-in native GUI test; no process scanner is run")
}
}
func TestNativeTrayOneExitItemAndGracefulCommand(t *testing.T) {
requireNativeGUI(t)
requested := make(chan struct{})
restored := make(chan struct{})
close(restored)
var once sync.Once
tr, err := newTray(func() { once.Do(func() { close(requested) }) }, restored)
if err != nil {
t.Fatal(err)
}
defer tr.Close()
h := tr.hwnd.Load()
count, _, _ := u32.NewProc("GetMenuItemCount").Call(tr.menu)
if count != 1 {
t.Fatalf("want exactly one menu item, got %d", count)
}
var label [32]uint16
item := menuItemInfo{Size: uint32(unsafe.Sizeof(menuItemInfo{})), Mask: 0x40 | 0x2 | 0x80, Text: &label[0], TextLen: uint32(len(label))}
ok, _, e := u32.NewProc("GetMenuItemInfoW").Call(tr.menu, 0, 1, uintptr(unsafe.Pointer(&item)))
if ok == 0 {
t.Fatal(e)
}
if item.ID != menuExitID || item.Bitmap == 0 || string(utf16Runes(label[:])) != "Выход" {
t.Fatal("missing Exit label, command, or cross bitmap")
}
ok, _, e = pPostMessage.Call(h, 0x111, menuExitID, 0)
if ok == 0 {
t.Fatal(e)
}
select {
case <-requested:
case <-time.After(3 * time.Second):
t.Fatal("Exit command did not request graceful shutdown")
}
if err = tr.Close(); err != nil {
t.Fatal(err)
}
valid, _, _ := u32.NewProc("IsWindow").Call(h)
if valid != 0 {
t.Fatal("tray window leaked")
}
}
func utf16Runes(in []uint16) []rune {
out := []rune{}
for _, v := range in {
if v == 0 {
break
}
out = append(out, rune(v))
}
return out
}