Support menu.Menu

This commit is contained in:
Lea Anthony 2022-10-05 19:22:03 +11:00
commit 68bdc7c5eb
No known key found for this signature in database
GPG key ID: 33DAF7BB90A58405
6 changed files with 62 additions and 45 deletions

View file

@ -0,0 +1,9 @@
//go:build windows
package menu
import "github.com/wailsapp/wails/v2/internal/platform/win32"
type Menu struct {
menu win32.HMENU
}

View file

@ -15,9 +15,7 @@ type SysTray interface {
Hide() error
Run() error
Close()
AppendMenu(label string, callback menu.Callback)
AppendMenuItem(item *menu.MenuItem)
AppendSeparator()
SetMenu(menu *menu.Menu) error
SetIcons(lightModeIcon, darkModeIcon *options.SystemTrayIcon) error
}

View file

@ -6,10 +6,15 @@ import (
"github.com/wailsapp/wails/v2/pkg/menu"
)
func displayMenu(hwnd win32.HWND, menuItems []*menu.MenuItem) error {
popupMenu := win32.CreatePopupMenu()
type PopupMenu struct {
menu win32.HMENU
parent win32.HWND
menuMapping map[int]*menu.MenuItem
}
for index, item := range menuItems {
func buildMenu(parentMenu win32.HMENU, inputMenu *menu.Menu) (map[int]*menu.MenuItem, error) {
menuMapping := make(map[int]*menu.MenuItem)
for index, item := range inputMenu.Items {
var ret bool
itemID := win32.MenuItemMsgID + index
flags := win32.MF_STRING
@ -26,28 +31,52 @@ func displayMenu(hwnd win32.HWND, menuItems []*menu.MenuItem) error {
flags = flags | win32.MF_SEPARATOR
}
ret = win32.AppendMenu(popupMenu, uintptr(flags), uintptr(itemID), item.Label)
menuMapping[itemID] = item
ret = win32.AppendMenu(parentMenu, uintptr(flags), uintptr(itemID), item.Label)
if ret == false {
return errors.New("AppendMenu failed")
return nil, errors.New("AppendMenu failed")
}
}
return menuMapping, nil
}
func NewPopupMenu(parent win32.HWND, inputMenu *menu.Menu) (*PopupMenu, error) {
popupMenu := win32.CreatePopupMenu()
mappings, err := buildMenu(popupMenu, inputMenu)
if err != nil {
return nil, err
}
return &PopupMenu{
parent: parent,
menu: popupMenu,
menuMapping: mappings,
}, nil
}
func (p *PopupMenu) ShowAtCursor() error {
x, y, ok := win32.GetCursorPos()
if ok == false {
return errors.New("GetCursorPos failed")
}
if win32.SetForegroundWindow(hwnd) == false {
if win32.SetForegroundWindow(p.parent) == false {
return errors.New("SetForegroundWindow failed")
}
if win32.TrackPopupMenu(popupMenu, win32.TPM_LEFTALIGN, x, y-5, hwnd) == false {
if win32.TrackPopupMenu(p.menu, win32.TPM_LEFTALIGN, x, y-5, p.parent) == false {
return errors.New("TrackPopupMenu failed")
}
if win32.PostMessage(hwnd, win32.WM_NULL, 0, 0) == 0 {
if win32.PostMessage(p.parent, win32.WM_NULL, 0, 0) == 0 {
return errors.New("PostMessage failed")
}
return nil
}
func (p *PopupMenu) ProcessCommand(cmdMsgID int) {
item := p.menuMapping[cmdMsgID]
if item != nil {
item.Click(&menu.CallbackData{MenuItem: item})
}
}

View file

@ -36,7 +36,7 @@ type Systray struct {
darkModeIcon win32.HICON
currentIcon win32.HICON
Menu []*menu.MenuItem
menu *PopupMenu
quit chan struct{}
icon *options.SystemTrayIcon
@ -136,19 +136,9 @@ func (p *Systray) HWND() win32.HWND {
return p.hwnd
}
// AppendMenu add menu item.
func (p *Systray) AppendMenu(label string, onclick menu.Callback) {
p.Menu = append(p.Menu, &menu.MenuItem{Type: menu.TextType, Label: label, Click: onclick})
}
// AppendMenuItem add menu item.
func (p *Systray) AppendMenuItem(item *menu.MenuItem) {
p.Menu = append(p.Menu, item)
}
// AppendSeparator to the menu.
func (p *Systray) AppendSeparator() {
p.Menu = append(p.Menu, menu.Separator())
func (p *Systray) SetMenu(popupMenu *menu.Menu) (err error) {
p.menu, err = NewPopupMenu(p.hwnd, popupMenu)
return
}
func (p *Systray) Stop() error {
@ -273,16 +263,16 @@ func (p *Systray) WinProc(hwnd win32.HWND, msg uint32, wparam, lparam uintptr) u
case win32.NotifyIconMessageId:
if lparam == win32.WM_LBUTTONUP {
p.lclick()
if len(p.Menu) > 0 {
err := displayMenu(p.hwnd, p.Menu)
if p.menu != nil {
err := p.menu.ShowAtCursor()
if err != nil {
return 0
}
}
} else if lparam == win32.WM_RBUTTONUP {
p.rclick()
if len(p.Menu) > 0 {
err := displayMenu(p.hwnd, p.Menu)
if p.menu != nil {
err := p.menu.ShowAtCursor()
if err != nil {
return 0
}
@ -301,11 +291,7 @@ func (p *Systray) WinProc(hwnd win32.HWND, msg uint32, wparam, lparam uintptr) u
cmdMsgID := int(wparam & 0xffff)
switch cmdMsgID {
default:
if cmdMsgID >= win32.MenuItemMsgID && cmdMsgID < (win32.MenuItemMsgID+len(p.Menu)) {
itemIndex := cmdMsgID - win32.MenuItemMsgID
menuItem := p.Menu[itemIndex]
menuItem.Click(nil)
}
p.menu.ProcessCommand(cmdMsgID)
}
}

View file

@ -14,6 +14,7 @@ type SystemTray struct {
darkModeIcon *options.SystemTrayIcon
tooltip string
startHidden bool
menu *menu.Menu
// The platform specific implementation
impl platform.SysTray
@ -27,6 +28,7 @@ func newSystemTray(options *options.SystemTray) *SystemTray {
darkModeIcon: options.DarkModeIcon,
tooltip: options.Tooltip,
startHidden: options.StartHidden,
menu: options.Menu,
}
}
@ -37,6 +39,7 @@ func (t *SystemTray) run() {
if !t.startHidden {
t.impl.Show()
}
t.impl.SetMenu(t.menu)
t.impl.Run()
}
@ -44,9 +47,6 @@ func (t *SystemTray) SetTitle(title string) {
t.title = title
t.impl.SetTitle(title)
}
func (t *SystemTray) AppendMenu(label string, callback menu.Callback) {
t.impl.AppendMenu(label, callback)
}
func (t *SystemTray) Run() error {
t.run()
@ -56,11 +56,3 @@ func (t *SystemTray) Run() error {
func (t *SystemTray) Close() {
t.impl.Close()
}
func (t *SystemTray) AppendSeperator() {
t.impl.AppendSeparator()
}
func (t *SystemTray) AppendMenuItem(item *menu.MenuItem) {
t.impl.AppendMenuItem(item)
}

View file

@ -1,5 +1,7 @@
package options
import "github.com/wailsapp/wails/v2/pkg/menu"
// SystemTray contains options for the system tray
type SystemTray struct {
LightModeIcon *SystemTrayIcon
@ -7,6 +9,7 @@ type SystemTray struct {
Title string
Tooltip string
StartHidden bool
Menu *menu.Menu
}
// SystemTrayIcon represents a system tray icon