mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-05 00:49:29 +08:00
222 lines
4.6 KiB
Go
222 lines
4.6 KiB
Go
//go:build windows
|
|
|
|
package application
|
|
|
|
import (
|
|
"github.com/samber/lo"
|
|
"github.com/wailsapp/wails/v3/pkg/events"
|
|
"github.com/wailsapp/wails/v3/pkg/w32"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
type windowsSystemTray struct {
|
|
parent *SystemTray
|
|
|
|
// Platform specific implementation
|
|
uid uint32
|
|
hwnd w32.HWND
|
|
appIcon w32.HICON
|
|
lightModeIcon w32.HICON
|
|
darkModeIcon w32.HICON
|
|
currentIcon w32.HICON
|
|
//menu *w32.PopupMenu
|
|
}
|
|
|
|
func (s *windowsSystemTray) setIconPosition(position int) {
|
|
// Unsupported - do nothing
|
|
}
|
|
|
|
func (s *windowsSystemTray) setMenu(menu *Menu) {
|
|
//s.menu = menu
|
|
panic("implement me")
|
|
}
|
|
|
|
func (s *windowsSystemTray) run() {
|
|
|
|
NotifyIconClassName := "WailsSystray"
|
|
_, err := w32.RegisterWindow(NotifyIconClassName, getNativeApplication().wndProc)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
s.hwnd = w32.CreateWindowEx(
|
|
0,
|
|
w32.MustStringToUTF16Ptr(NotifyIconClassName),
|
|
nil,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
w32.HWND_MESSAGE,
|
|
0,
|
|
0,
|
|
nil)
|
|
if s.hwnd == 0 {
|
|
panic(syscall.GetLastError())
|
|
}
|
|
|
|
nid := w32.NOTIFYICONDATA{
|
|
HWnd: s.hwnd,
|
|
UID: uint32(s.parent.id),
|
|
UFlags: w32.NIF_ICON | w32.NIF_MESSAGE,
|
|
HIcon: s.currentIcon,
|
|
UCallbackMessage: w32.WM_USER + uint32(s.parent.id),
|
|
}
|
|
nid.CbSize = uint32(unsafe.Sizeof(nid))
|
|
|
|
if !w32.ShellNotifyIcon(w32.NIM_ADD, &nid) {
|
|
panic(syscall.GetLastError())
|
|
}
|
|
|
|
nid.UVersion = w32.NOTIFYICON_VERSION
|
|
|
|
if !w32.ShellNotifyIcon(w32.NIM_SETVERSION, &nid) {
|
|
panic(syscall.GetLastError())
|
|
}
|
|
|
|
if s.parent.icon != nil {
|
|
s.lightModeIcon = lo.Must(w32.CreateHIconFromPNG(s.parent.icon))
|
|
} else {
|
|
s.lightModeIcon = lo.Must(w32.CreateHIconFromPNG(DefaultApplicationIcon))
|
|
}
|
|
if s.parent.darkModeIcon != nil {
|
|
s.darkModeIcon = lo.Must(w32.CreateHIconFromPNG(s.parent.darkModeIcon))
|
|
} else {
|
|
s.darkModeIcon = s.lightModeIcon
|
|
}
|
|
s.uid = nid.UID
|
|
|
|
// TODO: Set Menu
|
|
|
|
// Update the icon
|
|
s.updateIcon()
|
|
|
|
// Listen for dark mode changes
|
|
globalApplication.On(events.Windows.SystemThemeChanged, func() {
|
|
s.updateIcon()
|
|
})
|
|
|
|
// Register the system tray
|
|
getNativeApplication().registerSystemTray(s)
|
|
|
|
}
|
|
|
|
func (s *windowsSystemTray) updateIcon() {
|
|
|
|
var newIcon w32.HICON
|
|
if w32.IsCurrentlyDarkMode() {
|
|
newIcon = s.darkModeIcon
|
|
} else {
|
|
newIcon = s.lightModeIcon
|
|
}
|
|
if s.currentIcon == newIcon {
|
|
return
|
|
}
|
|
|
|
s.currentIcon = newIcon
|
|
nid := s.newNotifyIconData()
|
|
nid.UFlags = w32.NIF_ICON | w32.NIF_MESSAGE
|
|
if s.currentIcon != 0 {
|
|
nid.HIcon = s.currentIcon
|
|
}
|
|
|
|
if !w32.ShellNotifyIcon(w32.NIM_MODIFY, &nid) {
|
|
panic(syscall.GetLastError())
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *windowsSystemTray) newNotifyIconData() w32.NOTIFYICONDATA {
|
|
nid := w32.NOTIFYICONDATA{
|
|
UID: s.uid,
|
|
HWnd: s.hwnd,
|
|
}
|
|
nid.CbSize = uint32(unsafe.Sizeof(nid))
|
|
return nid
|
|
}
|
|
|
|
func (s *windowsSystemTray) setIcon(icon []byte) {
|
|
var err error
|
|
s.lightModeIcon, err = w32.CreateHIconFromPNG(icon)
|
|
if err != nil {
|
|
panic(syscall.GetLastError())
|
|
}
|
|
if s.darkModeIcon == 0 {
|
|
s.darkModeIcon = s.lightModeIcon
|
|
}
|
|
// Update the icon
|
|
s.updateIcon()
|
|
}
|
|
func (s *windowsSystemTray) setDarkModeIcon(icon []byte) {
|
|
var err error
|
|
s.darkModeIcon, err = w32.CreateHIconFromPNG(icon)
|
|
if err != nil {
|
|
panic(syscall.GetLastError())
|
|
}
|
|
if s.lightModeIcon == 0 {
|
|
s.lightModeIcon = s.darkModeIcon
|
|
}
|
|
// Update the icon
|
|
s.updateIcon()
|
|
}
|
|
|
|
func newSystemTrayImpl(parent *SystemTray) systemTrayImpl {
|
|
return &windowsSystemTray{
|
|
parent: parent,
|
|
}
|
|
}
|
|
|
|
func (s *windowsSystemTray) destroy() {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (s *windowsSystemTray) wndProc(msg uint32, wParam, lParam uintptr) uintptr {
|
|
switch msg {
|
|
case w32.WM_USER + uint32(s.parent.id):
|
|
switch lParam {
|
|
case w32.WM_LBUTTONUP:
|
|
if s.parent.leftButtonClickHandler != nil {
|
|
s.parent.leftButtonClickHandler()
|
|
}
|
|
case w32.WM_RBUTTONUP:
|
|
if s.parent.rightButtonClickHandler != nil {
|
|
s.parent.rightButtonClickHandler()
|
|
}
|
|
case w32.WM_LBUTTONDBLCLK:
|
|
if s.parent.leftButtonDoubleClickHandler != nil {
|
|
s.parent.leftButtonDoubleClickHandler()
|
|
}
|
|
case w32.WM_RBUTTONDBLCLK:
|
|
if s.parent.rightButtonDoubleClickHandler != nil {
|
|
s.parent.rightButtonDoubleClickHandler()
|
|
}
|
|
default:
|
|
println(w32.WMMessageToString(lParam))
|
|
}
|
|
// TODO: Menu processing
|
|
//case w32.WM_COMMAND:
|
|
// cmdMsgID := int(wparam & 0xffff)
|
|
// switch cmdMsgID {
|
|
// default:
|
|
// p.menu.ProcessCommand(cmdMsgID)
|
|
// }
|
|
default:
|
|
msg := int(wParam & 0xffff)
|
|
println(w32.WMMessageToString(uintptr(msg)))
|
|
}
|
|
|
|
return w32.DefWindowProc(s.hwnd, msg, wParam, lParam)
|
|
}
|
|
|
|
// ---- Unsupported ----
|
|
|
|
func (s *windowsSystemTray) setLabel(_ string) {
|
|
// Unsupported - do nothing
|
|
}
|
|
|
|
func (s *windowsSystemTray) setTemplateIcon(_ []byte) {
|
|
// Unsupported - do nothing
|
|
}
|