From ae691b8e524629329d9ab4a642bec0716274a9a3 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 10 Jun 2023 10:19:33 +1000 Subject: [PATCH] [v3 windows] Small icon updates --- v3/STATUS.md | 36 ++++++++++++++++------ v3/pkg/application/application.go | 2 +- v3/pkg/application/application_windows.go | 27 ++++++++-------- v3/pkg/application/systemtray_windows.go | 12 ++++---- v3/pkg/icons/ApplicationDarkMode-256.png | Bin 2994 -> 4176 bytes v3/pkg/icons/ApplicationLightMode-256.png | Bin 3328 -> 4138 bytes v3/pkg/icons/icon.ico | Bin 0 -> 21677 bytes v3/pkg/icons/icons.go | 3 ++ v3/pkg/w32/icon.go | 30 ++++++++++++++++-- v3/pkg/w32/window.go | 5 +++ 10 files changed, 82 insertions(+), 33 deletions(-) create mode 100644 v3/pkg/icons/icon.ico diff --git a/v3/STATUS.md b/v3/STATUS.md index 3b35a554a..e600dce2c 100644 --- a/v3/STATUS.md +++ b/v3/STATUS.md @@ -2,6 +2,15 @@ Status of features in v3. Incomplete - please add as you see fit. + +## Major Blockers + +- [ ] Dev Support - What will it look like? +- [ ] Translucency on Windows doesn't work right +- [ ] Events - cross-platform events, simplified event handling? +- [ ] Error handling - needs to be revised. Centralised system error handling? +- [ ] Documentation - needs to be written + ## Application Application interface methods @@ -14,7 +23,7 @@ Application interface methods | name() string | | | Y | | | getCurrentWindowID() uint | Y | | Y | | | showAboutDialog(name string, description string, icon []byte) | | | Y | | -| setIcon(icon []byte) | | | Y | | +| setIcon(icon []byte) | - | | Y | | | on(id uint) | | | Y | | | dispatchOnMainThread(fn func()) | Y | | Y | | | hide() | Y | | Y | | @@ -162,7 +171,7 @@ An 'X' indicates that the option is not supported by the platform. | Width | Y | | | | | Height | Y | | | | | AlwaysOnTop | Y | | | | -| URL | | | | | +| URL | Y | | | | | DisableResize | Y | | | | | Frameless | Y | | | | | MinWidth | Y | | | | @@ -173,9 +182,9 @@ An 'X' indicates that the option is not supported by the platform. | Mac | - | - | | | | BackgroundType | | | | Acrylic seems to work but the others don't | | BackgroundColour | Y | | | | -| HTML | | | | | -| JS | | | | | -| CSS | | | | | +| HTML | Y | | | | +| JS | Y | | | | +| CSS | Y | | | | | X | Y | | | | | Y | Y | | | | | HideOnClose | Y | | | | @@ -277,16 +286,21 @@ Built-in plugin support: | Start at login | | | Y | | | Server | | | | | + +TODO: + +- Ensure each plugin has a JS wrapper that can be injected into the window. + ## Packaging | | Windows | Linux | Mac | Notes | |-----------------|---------|-------|-----|-------| -| Icon Generation | | | Y | | -| Icon Embedding | | | Y | | +| Icon Generation | Y | | Y | | +| Icon Embedding | Y | | Y | | | Info.plist | - | | Y | | | NSIS Installer | | | - | | -| Mac bundle | | | Y | | -| Windows exe | | | - | | +| Mac bundle | - | | Y | | +| Windows exe | Y | | - | | ## Frameless Windows @@ -308,10 +322,11 @@ Built-in plugin support: | TitleBar | | Standard window decorations by default | | Appearance | DefaultAppearance | | | InvisibleTitleBarHeight | 0 | Creates an invisible title bar for frameless windows | +| DisableShadow | false | Disables the window drop shadow | ## Windows Specific -- [x] Translucency +- [ ] Translucency - [x] Custom Themes ### Windows Options @@ -348,3 +363,4 @@ Built-in plugin support: | window | | | | | windowjs | | | | | wml | | | | + diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index 7508afda3..0fdda3a12 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -391,8 +391,8 @@ func (a *App) Run() error { // set the application menu if runtime.GOOS == "darwin" { a.impl.setApplicationMenu(a.ApplicationMenu) - a.impl.setIcon(a.options.Icon) } + a.impl.setIcon(a.options.Icon) err := a.impl.run() if err != nil { diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index 9a2bd1c84..1c32e54bc 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -22,7 +22,8 @@ var windowClassName = lo.Must(syscall.UTF16PtrFromString("WailsWebviewWindow")) type windowsApp struct { parent *App - instance w32.HINSTANCE + windowClass w32.WNDCLASSEX + instance w32.HINSTANCE windowMap map[w32.HWND]*windowsWebviewWindow windowMapLock sync.RWMutex @@ -182,22 +183,20 @@ func (m *windowsApp) init() { icon := w32.LoadIconWithResourceID(m.instance, w32.IDI_APPLICATION) - var wc w32.WNDCLASSEX - wc.Size = uint32(unsafe.Sizeof(wc)) - wc.Style = w32.CS_HREDRAW | w32.CS_VREDRAW - wc.WndProc = syscall.NewCallback(m.wndProc) - wc.Instance = m.instance - wc.Background = w32.COLOR_BTNFACE + 1 - wc.Icon = icon - wc.Cursor = w32.LoadCursorWithResourceID(0, w32.IDC_ARROW) - wc.ClassName = windowClassName - wc.MenuName = nil - wc.IconSm = icon + m.windowClass.Size = uint32(unsafe.Sizeof(m.windowClass)) + m.windowClass.Style = w32.CS_HREDRAW | w32.CS_VREDRAW + m.windowClass.WndProc = syscall.NewCallback(m.wndProc) + m.windowClass.Instance = m.instance + m.windowClass.Background = w32.COLOR_BTNFACE + 1 + m.windowClass.Icon = icon + m.windowClass.Cursor = w32.LoadCursorWithResourceID(0, w32.IDC_ARROW) + m.windowClass.ClassName = windowClassName + m.windowClass.MenuName = nil + m.windowClass.IconSm = icon - if ret := w32.RegisterClassEx(&wc); ret == 0 { + if ret := w32.RegisterClassEx(&m.windowClass); ret == 0 { panic(syscall.GetLastError()) } - m.isDarkMode = w32.IsCurrentlyDarkMode() } diff --git a/v3/pkg/application/systemtray_windows.go b/v3/pkg/application/systemtray_windows.go index 827081ff9..16abd727c 100644 --- a/v3/pkg/application/systemtray_windows.go +++ b/v3/pkg/application/systemtray_windows.go @@ -71,14 +71,14 @@ func (s *windowsSystemTray) run() { } if s.parent.icon != nil { - s.lightModeIcon = lo.Must(w32.CreateHIconFromImage(s.parent.icon)) + s.lightModeIcon = lo.Must(w32.CreateSmallHIconFromImage(s.parent.icon)) } else { - s.lightModeIcon = lo.Must(w32.CreateHIconFromImage(icons.SystrayLight)) + s.lightModeIcon = lo.Must(w32.CreateSmallHIconFromImage(icons.SystrayLight)) } if s.parent.darkModeIcon != nil { - s.darkModeIcon = lo.Must(w32.CreateHIconFromImage(s.parent.darkModeIcon)) + s.darkModeIcon = lo.Must(w32.CreateSmallHIconFromImage(s.parent.darkModeIcon)) } else { - s.darkModeIcon = lo.Must(w32.CreateHIconFromImage(icons.SystrayDark)) + s.darkModeIcon = lo.Must(w32.CreateSmallHIconFromImage(icons.SystrayDark)) } s.uid = nid.UID @@ -149,7 +149,7 @@ func (s *windowsSystemTray) newNotifyIconData() w32.NOTIFYICONDATA { func (s *windowsSystemTray) setIcon(icon []byte) { var err error - s.lightModeIcon, err = w32.CreateHIconFromImage(icon) + s.lightModeIcon, err = w32.CreateSmallHIconFromImage(icon) if err != nil { panic(syscall.GetLastError()) } @@ -161,7 +161,7 @@ func (s *windowsSystemTray) setIcon(icon []byte) { } func (s *windowsSystemTray) setDarkModeIcon(icon []byte) { var err error - s.darkModeIcon, err = w32.CreateHIconFromImage(icon) + s.darkModeIcon, err = w32.CreateSmallHIconFromImage(icon) if err != nil { panic(syscall.GetLastError()) } diff --git a/v3/pkg/icons/ApplicationDarkMode-256.png b/v3/pkg/icons/ApplicationDarkMode-256.png index 10959272ace1737d2020b399578a2744c8bb69c7..68e5e7666cf23c4b4b8cd634956c828ebcd5b223 100644 GIT binary patch literal 4176 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 literal 2994 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 Ql=(aFNTb`|vt`Er8?4YRR{#J2 diff --git a/v3/pkg/icons/ApplicationLightMode-256.png b/v3/pkg/icons/ApplicationLightMode-256.png index 1652dfe91dedce1432cbafb92f179c9a5ab4ebac..fe74e60ea95968e0e9338c7b4e8e370bd90de7f0 100644 GIT binary patch literal 4138 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 HV)Xw2-!%cg diff --git a/v3/pkg/icons/icon.ico b/v3/pkg/icons/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..bfa0690b7f8aea8d793026b51f9fc4eed2e00af7 GIT binary patch literal 21677 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 ou5=8}@A^#05^yFjv{|%CV0m?W0y8r+H literal 0 HcmV?d00001 diff --git a/v3/pkg/icons/icons.go b/v3/pkg/icons/icons.go index 4023df127..7434ba33c 100644 --- a/v3/pkg/icons/icons.go +++ b/v3/pkg/icons/icons.go @@ -8,6 +8,9 @@ var SystrayMacTemplate []byte //go:embed systray-light.png var SystrayLight []byte +//go:embed icon.ico +var DefaultWindowsIcon []byte + //go:embed systray-dark.png var SystrayDark []byte diff --git a/v3/pkg/w32/icon.go b/v3/pkg/w32/icon.go index e84444e64..610dd3ca3 100644 --- a/v3/pkg/w32/icon.go +++ b/v3/pkg/w32/icon.go @@ -42,8 +42,8 @@ func isICO(fileData []byte) bool { return string(fileData[:4]) == "\x00\x00\x01\x00" } -// CreateHIconFromImage creates a HICON from a PNG or ICO file -func CreateHIconFromImage(fileData []byte) (HICON, error) { +// CreateSmallHIconFromImage creates a HICON from a PNG or ICO file +func CreateSmallHIconFromImage(fileData []byte) (HICON, error) { if len(fileData) < 8 { return 0, fmt.Errorf("invalid file format") } @@ -63,3 +63,29 @@ func CreateHIconFromImage(fileData []byte) (HICON, error) { LR_DEFAULTSIZE) return HICON(icon), err } + +// CreateLargeHIconFromImage creates a HICON from a PNG or ICO file +func CreateLargeHIconFromImage(fileData []byte) (HICON, error) { + if len(fileData) < 8 { + return 0, fmt.Errorf("invalid file format") + } + + if !isPNG(fileData) && !isICO(fileData) { + return 0, fmt.Errorf("unsupported file format") + } + iconWidth := GetSystemMetrics(SM_CXICON) + iconHeight := GetSystemMetrics(SM_CXICON) + icon, err := CreateIconFromResourceEx( + uintptr(unsafe.Pointer(&fileData[0])), + uint32(len(fileData)), + true, + 0x00030000, + iconWidth, + iconHeight, + LR_DEFAULTSIZE) + return HICON(icon), err +} + +func SetWindowIcon(hwnd HWND, icon HICON) { + SendMessage(hwnd, WM_SETICON, ICON_SMALL, uintptr(icon)) +} diff --git a/v3/pkg/w32/window.go b/v3/pkg/w32/window.go index e4aaafdc1..84fcda9ec 100644 --- a/v3/pkg/w32/window.go +++ b/v3/pkg/w32/window.go @@ -14,6 +14,7 @@ import ( const ( GCLP_HBRBACKGROUND int32 = -10 + GCLP_HICON int32 = -14 ) func ExtendFrameIntoClientArea(hwnd uintptr, extend bool) { @@ -70,6 +71,10 @@ func ShowWindowMinimised(hwnd uintptr) { showWindow(hwnd, SW_MINIMIZE) } +func SetApplicationIcon(hwnd uintptr, icon HICON) { + setClassLongPtr(hwnd, GCLP_HICON, icon) +} + func SetBackgroundColour(hwnd uintptr, r, g, b uint8) { col := uint32(r) | uint32(g)<<8 | uint32(b)<<16 hbrush, _, _ := procCreateSolidBrush.Call(uintptr(col))