//go:build windows package main import ( "fmt" "log" "os" "path/filepath" "unsafe" "github.com/crgimenes/glaze" "golang.org/x/sys/windows" ) func openExternal(raw string) error { verb, err := windows.UTF16PtrFromString("open") if err != nil { return err } file, err := windows.UTF16PtrFromString(raw) if err != nil { return err } return windows.ShellExecute(0, verb, file, nil, nil, windows.SW_SHOWNORMAL) } func fatalf(format string, args ...any) { msg := fmt.Sprintf(format, args...) log.Println(msg) messageBox(msg) os.Exit(1) } func shutdownSignals() []os.Signal { return []os.Signal{os.Interrupt} } func decorateWindow(w glaze.WebView) { if w == nil { return } applyWindowIcon(w.Window()) } func applyWindowIcon(hwnd unsafe.Pointer) { ico := findIconPath() if ico == "" || hwnd == nil { return } pathPtr, err := windows.UTF16PtrFromString(ico) if err != nil { return } user32 := windows.NewLazySystemDLL("user32.dll") loadImage := user32.NewProc("LoadImageW") sendMessage := user32.NewProc("SendMessageW") const ( imageIcon = 1 lrLoadFromFile = 0x0010 lrDefaultSize = 0x0040 wmSetIcon = 0x0080 iconSmall = 0 iconBig = 1 ) h, _, _ := loadImage.Call(0, uintptr(unsafe.Pointer(pathPtr)), imageIcon, 0, 0, lrLoadFromFile|lrDefaultSize) if h == 0 { return } sendMessage.Call(uintptr(hwnd), wmSetIcon, iconSmall, h) sendMessage.Call(uintptr(hwnd), wmSetIcon, iconBig, h) } func findIconPath() string { candidates := []string{} if exe, err := os.Executable(); err == nil { dir := filepath.Dir(exe) candidates = append(candidates, filepath.Join(dir, "assets", "navis.ico"), filepath.Join(dir, "navis.ico"), ) } if cwd, err := os.Getwd(); err == nil { candidates = append(candidates, filepath.Join(cwd, "assets", "navis.ico")) } for _, c := range candidates { if st, err := os.Stat(c); err == nil && !st.IsDir() { return c } } return "" }