All checks were successful
Release / build (push) Successful in 2m34s
Embed the blue SyncWarden shield icon in the panel binary and set it as the window icon via Win32 SendMessage/WM_SETICON on startup. Uses the syncing (blue) variant as the status-independent panel icon. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
//go:build windows
|
|
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
_ "embed"
|
|
"encoding/binary"
|
|
"os"
|
|
"path/filepath"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
//go:embed panel_icon.png
|
|
var panelIconPNG []byte
|
|
|
|
func setWindowIcon(windowPtr unsafe.Pointer) {
|
|
hwnd := uintptr(windowPtr)
|
|
if hwnd == 0 {
|
|
return
|
|
}
|
|
|
|
// Write a temp ICO file (Windows LoadImage needs a file path)
|
|
icoData := wrapPNG(panelIconPNG, 64, 64)
|
|
icoPath := filepath.Join(os.TempDir(), "syncwarden-panel.ico")
|
|
if err := os.WriteFile(icoPath, icoData, 0644); err != nil {
|
|
return
|
|
}
|
|
|
|
user32 := syscall.NewLazyDLL("user32.dll")
|
|
loadImage := user32.NewProc("LoadImageW")
|
|
sendMessage := user32.NewProc("SendMessageW")
|
|
|
|
pathW, _ := syscall.UTF16PtrFromString(icoPath)
|
|
|
|
const (
|
|
imageIcon = 1
|
|
lrLoadFromFile = 0x0010
|
|
wmSetIcon = 0x0080
|
|
iconBig = 1
|
|
iconSmall = 0
|
|
)
|
|
|
|
hBig, _, _ := loadImage.Call(0, uintptr(unsafe.Pointer(pathW)), imageIcon, 32, 32, lrLoadFromFile)
|
|
if hBig != 0 {
|
|
sendMessage.Call(hwnd, wmSetIcon, iconBig, hBig)
|
|
}
|
|
|
|
hSmall, _, _ := loadImage.Call(0, uintptr(unsafe.Pointer(pathW)), imageIcon, 16, 16, lrLoadFromFile)
|
|
if hSmall != 0 {
|
|
sendMessage.Call(hwnd, wmSetIcon, iconSmall, hSmall)
|
|
}
|
|
}
|
|
|
|
func wrapPNG(pngData []byte, width, height int) []byte {
|
|
const headerSize = 6
|
|
const entrySize = 16
|
|
imageOffset := headerSize + entrySize
|
|
|
|
buf := new(bytes.Buffer)
|
|
binary.Write(buf, binary.LittleEndian, uint16(0))
|
|
binary.Write(buf, binary.LittleEndian, uint16(1))
|
|
binary.Write(buf, binary.LittleEndian, uint16(1))
|
|
|
|
w := byte(width)
|
|
if width >= 256 {
|
|
w = 0
|
|
}
|
|
h := byte(height)
|
|
if height >= 256 {
|
|
h = 0
|
|
}
|
|
buf.WriteByte(w)
|
|
buf.WriteByte(h)
|
|
buf.WriteByte(0)
|
|
buf.WriteByte(0)
|
|
binary.Write(buf, binary.LittleEndian, uint16(1))
|
|
binary.Write(buf, binary.LittleEndian, uint16(32))
|
|
binary.Write(buf, binary.LittleEndian, uint32(len(pngData)))
|
|
binary.Write(buf, binary.LittleEndian, uint32(imageOffset))
|
|
|
|
buf.Write(pngData)
|
|
return buf.Bytes()
|
|
}
|