//go:build darwin // +build darwin package darwin /* #cgo CFLAGS: -x objective-c #cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit #import #import "Application.h" #import "WailsContext.h" #include */ import "C" import ( "unsafe" "github.com/wailsapp/wails/v2/pkg/menu" "github.com/wailsapp/wails/v2/pkg/menu/keys" ) type NSMenu struct { context unsafe.Pointer nsmenu unsafe.Pointer } func NewNSMenu(context unsafe.Pointer, name string) *NSMenu { c := NewCalloc() defer c.Free() title := c.String(name) nsmenu := C.NewMenu(title) return &NSMenu{ context: context, nsmenu: nsmenu, } } func (m *NSMenu) AddSubMenu(label string) *NSMenu { result := NewNSMenu(m.context, label) C.AppendSubmenu(m.nsmenu, result.nsmenu) return result } func (m *NSMenu) AppendRole(role menu.Role) { C.AppendRole(m.context, m.nsmenu, C.int(role)) } type MenuItem struct { id uint nsmenuitem unsafe.Pointer wailsMenuItem *menu.MenuItem radioGroupMembers []*MenuItem } func (m *NSMenu) AddMenuItem(menuItem *menu.MenuItem) *MenuItem { c := NewCalloc() defer c.Free() var modifier C.int var key *C.char if menuItem.Accelerator != nil { modifier = C.int(keys.ToMacModifier(menuItem.Accelerator)) key = c.String(menuItem.Accelerator.Key) } result := &MenuItem{ wailsMenuItem: menuItem, } result.id = createMenuItemID(result) result.nsmenuitem = C.AppendMenuItem(m.context, m.nsmenu, c.String(menuItem.Label), key, modifier, bool2Cint(menuItem.Disabled), bool2Cint(menuItem.Checked), C.int(result.id)) return result } //func (w *Window) SetApplicationMenu(menu *menu.Menu) { //w.applicationMenu = menu //processMenu(w, menu) //} func processMenu(parent *NSMenu, wailsMenu *menu.Menu) { var radioGroups []*MenuItem for _, menuItem := range wailsMenu.Items { if menuItem.SubMenu != nil { if len(radioGroups) > 0 { processRadioGroups(radioGroups) radioGroups = []*MenuItem{} } submenu := parent.AddSubMenu(menuItem.Label) processMenu(submenu, menuItem.SubMenu) } else { lastMenuItem := processMenuItem(parent, menuItem) if menuItem.Type == menu.RadioType { radioGroups = append(radioGroups, lastMenuItem) } else { if len(radioGroups) > 0 { processRadioGroups(radioGroups) radioGroups = []*MenuItem{} } } } } } func processRadioGroups(groups []*MenuItem) { for _, item := range groups { item.radioGroupMembers = groups } } func processMenuItem(parent *NSMenu, menuItem *menu.MenuItem) *MenuItem { if menuItem.Hidden { return nil } if menuItem.Role != 0 { parent.AppendRole(menuItem.Role) return nil } if menuItem.Type == menu.SeparatorType { C.AppendSeparator(parent.nsmenu) return nil } return parent.AddMenuItem(menuItem) } func (f *Frontend) MenuSetApplicationMenu(menu *menu.Menu) { f.mainWindow.SetApplicationMenu(menu) } func (f *Frontend) MenuUpdateApplicationMenu() { f.mainWindow.UpdateApplicationMenu() }