mirror of
https://github.com/wailsapp/wails.git
synced 2026-03-14 14:45:49 +01:00
Support menu.Menu
This commit is contained in:
parent
c63f8160a6
commit
68bdc7c5eb
6 changed files with 62 additions and 45 deletions
9
v2/internal/platform/menu/windows.go
Normal file
9
v2/internal/platform/menu/windows.go
Normal 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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue