[v3 windows] Small icon updates

This commit is contained in:
Lea Anthony 2023-06-10 10:19:33 +10:00
commit ae691b8e52
No known key found for this signature in database
GPG key ID: 33DAF7BB90A58405
10 changed files with 83 additions and 34 deletions

View file

@ -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 | | | |

View file

@ -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 {

View file

@ -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()
}

View file

@ -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())
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 4 KiB

Before After
Before After

BIN
v3/pkg/icons/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -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

View file

@ -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))
}

View file

@ -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))