Release 3.8.2.7: Windows taskbar/tray sea-wave icon when connected.
Match macOS Dock behavior using the same idle/connected glyph assets. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,3 +8,6 @@ func start(appName string, h Hooks) bool {
|
||||
_ = h
|
||||
return false
|
||||
}
|
||||
|
||||
// SetConnectedIcon is a no-op when tray is unsupported.
|
||||
func SetConnectedIcon(connected bool) { _ = connected }
|
||||
|
||||
@@ -4,8 +4,11 @@ package trayhost
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"vpnclient/internal/dockicon"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
@@ -90,6 +93,12 @@ type msg struct {
|
||||
Pt point
|
||||
}
|
||||
|
||||
var (
|
||||
trayMu sync.Mutex
|
||||
trayNID *notifyIconData
|
||||
trayLastUp *bool
|
||||
)
|
||||
|
||||
func start(appName string, h Hooks) bool {
|
||||
if h.Quit == nil {
|
||||
return false
|
||||
@@ -102,6 +111,35 @@ func start(appName string, h Hooks) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SetConnectedIcon updates the tray glyph (sea-wave N when connected).
|
||||
func SetConnectedIcon(connected bool) {
|
||||
trayMu.Lock()
|
||||
nid := trayNID
|
||||
if trayLastUp != nil && *trayLastUp == connected {
|
||||
trayMu.Unlock()
|
||||
return
|
||||
}
|
||||
v := connected
|
||||
trayLastUp = &v
|
||||
trayMu.Unlock()
|
||||
if nid == nil {
|
||||
return
|
||||
}
|
||||
icon := dockicon.StatusIcon(connected)
|
||||
if icon == 0 {
|
||||
return
|
||||
}
|
||||
trayMu.Lock()
|
||||
if trayNID == nil {
|
||||
trayMu.Unlock()
|
||||
return
|
||||
}
|
||||
trayNID.HIcon = icon
|
||||
trayNID.UFlags = nifMessage | nifIcon | nifTip
|
||||
procShellNotify.Call(nimModify, uintptr(unsafe.Pointer(trayNID)))
|
||||
trayMu.Unlock()
|
||||
}
|
||||
|
||||
func runTray(appName string, h Hooks) {
|
||||
className, _ := windows.UTF16PtrFromString("NavisTrayClass")
|
||||
title, _ := windows.UTF16PtrFromString(appName)
|
||||
@@ -155,17 +193,27 @@ func runTray(appName string, h Hooks) {
|
||||
return
|
||||
}
|
||||
|
||||
icon, _, _ := procLoadIcon.Call(0, uintptr(idiApplication))
|
||||
icon := dockicon.StatusIcon(false)
|
||||
if icon == 0 {
|
||||
h, _, _ := procLoadIcon.Call(0, uintptr(idiApplication))
|
||||
icon = windows.Handle(h)
|
||||
}
|
||||
var nid notifyIconData
|
||||
nid.CbSize = uint32(unsafe.Sizeof(nid))
|
||||
nid.Hwnd = windows.Handle(hwnd)
|
||||
nid.UID = 1
|
||||
nid.UFlags = nifMessage | nifIcon | nifTip
|
||||
nid.UCallbackMessage = wmTray
|
||||
nid.HIcon = windows.Handle(icon)
|
||||
nid.HIcon = icon
|
||||
tip, _ := windows.UTF16FromString(appName)
|
||||
copy(nid.SzTip[:], tip)
|
||||
procShellNotify.Call(nimAdd, uintptr(unsafe.Pointer(&nid)))
|
||||
trayMu.Lock()
|
||||
trayNID = &nid
|
||||
trayMu.Unlock()
|
||||
if h.IsUp != nil {
|
||||
SetConnectedIcon(h.IsUp())
|
||||
}
|
||||
|
||||
var m msg
|
||||
for {
|
||||
@@ -176,6 +224,9 @@ func runTray(appName string, h Hooks) {
|
||||
procTranslate.Call(uintptr(unsafe.Pointer(&m)))
|
||||
procDispatch.Call(uintptr(unsafe.Pointer(&m)))
|
||||
}
|
||||
trayMu.Lock()
|
||||
trayNID = nil
|
||||
trayMu.Unlock()
|
||||
procShellNotify.Call(nimDelete, uintptr(unsafe.Pointer(&nid)))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user