mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-04 00:10:47 +08:00
Menu improvements (#3492)
* Expose `DefaultApplicationMenu`. Add `FindByLabel` and `ItemAt` for finding menu items in a menu * Add `Menu.RemoveMenuItem()`, `MneuItem.GetAccelerator()` and `MenuItem.RemoveAccelerator()` * Remove `Update` * Iterate when removing menu items * Add `GetSubmenu()`
This commit is contained in:
parent
939d22d670
commit
e424a85a99
@ -210,7 +210,7 @@ func (m *macosApp) getCurrentWindowID() uint {
|
||||
func (m *macosApp) setApplicationMenu(menu *Menu) {
|
||||
if menu == nil {
|
||||
// Create a default menu for mac
|
||||
menu = defaultApplicationMenu()
|
||||
menu = DefaultApplicationMenu()
|
||||
}
|
||||
menu.Update()
|
||||
|
||||
|
@ -85,7 +85,7 @@ func (a *linuxApp) setApplicationMenu(menu *Menu) {
|
||||
// FIXME: How do we avoid putting a menu?
|
||||
if menu == nil {
|
||||
// Create a default menu
|
||||
menu = defaultApplicationMenu()
|
||||
menu = DefaultApplicationMenu()
|
||||
globalApplication.ApplicationMenu = menu
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ func (m *windowsApp) getCurrentWindowID() uint {
|
||||
func (m *windowsApp) setApplicationMenu(menu *Menu) {
|
||||
if menu == nil {
|
||||
// Create a default menu for windows
|
||||
menu = defaultApplicationMenu()
|
||||
menu = DefaultApplicationMenu()
|
||||
}
|
||||
menu.Update()
|
||||
|
||||
|
@ -16,24 +16,24 @@ func NewMenu() *Menu {
|
||||
}
|
||||
|
||||
func (m *Menu) Add(label string) *MenuItem {
|
||||
result := newMenuItem(label)
|
||||
result := NewMenuItem(label)
|
||||
m.items = append(m.items, result)
|
||||
return result
|
||||
}
|
||||
|
||||
func (m *Menu) AddSeparator() {
|
||||
result := newMenuItemSeparator()
|
||||
result := NewMenuItemSeparator()
|
||||
m.items = append(m.items, result)
|
||||
}
|
||||
|
||||
func (m *Menu) AddCheckbox(label string, enabled bool) *MenuItem {
|
||||
result := newMenuItemCheckbox(label, enabled)
|
||||
result := NewMenuItemCheckbox(label, enabled)
|
||||
m.items = append(m.items, result)
|
||||
return result
|
||||
}
|
||||
|
||||
func (m *Menu) AddRadio(label string, enabled bool) *MenuItem {
|
||||
result := newMenuItemRadio(label, enabled)
|
||||
result := NewMenuItemRadio(label, enabled)
|
||||
m.items = append(m.items, result)
|
||||
return result
|
||||
}
|
||||
@ -47,13 +47,13 @@ func (m *Menu) Update() {
|
||||
}
|
||||
|
||||
func (m *Menu) AddSubmenu(s string) *Menu {
|
||||
result := newSubMenuItem(s)
|
||||
result := NewSubMenuItem(s)
|
||||
m.items = append(m.items, result)
|
||||
return result.submenu
|
||||
}
|
||||
|
||||
func (m *Menu) AddRole(role Role) *Menu {
|
||||
result := newRole(role)
|
||||
result := NewRole(role)
|
||||
if result != nil {
|
||||
m.items = append(m.items, result)
|
||||
}
|
||||
@ -95,13 +95,51 @@ func (m *Menu) setContextData(data *ContextMenuData) {
|
||||
}
|
||||
}
|
||||
|
||||
// FindByLabel recursively searches for a menu item with the given label
|
||||
// and returns the first match, or nil if not found.
|
||||
func (m *Menu) FindByLabel(label string) *MenuItem {
|
||||
for _, item := range m.items {
|
||||
if item.label == label {
|
||||
return item
|
||||
}
|
||||
if item.submenu != nil {
|
||||
found := item.submenu.FindByLabel(label)
|
||||
if found != nil {
|
||||
return found
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Menu) RemoveMenuItem(target *MenuItem) {
|
||||
for i, item := range m.items {
|
||||
if item == target {
|
||||
// Remove the item from the slice
|
||||
m.items = append(m.items[:i], m.items[i+1:]...)
|
||||
break
|
||||
}
|
||||
if item.submenu != nil {
|
||||
item.submenu.RemoveMenuItem(target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ItemAt returns the menu item at the given index, or nil if the index is out of bounds.
|
||||
func (m *Menu) ItemAt(index int) *MenuItem {
|
||||
if index < 0 || index >= len(m.items) {
|
||||
return nil
|
||||
}
|
||||
return m.items[index]
|
||||
}
|
||||
|
||||
// Clone recursively clones the menu and all its submenus.
|
||||
func (m *Menu) clone() *Menu {
|
||||
func (m *Menu) Clone() *Menu {
|
||||
result := &Menu{
|
||||
label: m.label,
|
||||
}
|
||||
for _, item := range m.items {
|
||||
result.items = append(result.items, item.clone())
|
||||
result.items = append(result.items, item.Clone())
|
||||
}
|
||||
return result
|
||||
}
|
||||
@ -113,3 +151,17 @@ func (m *Menu) Append(in *Menu) {
|
||||
func (a *App) NewMenu() *Menu {
|
||||
return &Menu{}
|
||||
}
|
||||
|
||||
func NewMenuFromItems(item *MenuItem, items ...*MenuItem) *Menu {
|
||||
result := &Menu{
|
||||
items: []*MenuItem{item},
|
||||
}
|
||||
result.items = append(result.items, items...)
|
||||
return result
|
||||
}
|
||||
|
||||
func NewSubmenu(s string, items *Menu) *MenuItem {
|
||||
result := NewSubMenuItem(s)
|
||||
result.submenu = items
|
||||
return result
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ func (m *macosMenu) processMenu(parent unsafe.Pointer, menu *Menu) {
|
||||
}
|
||||
}
|
||||
|
||||
func defaultApplicationMenu() *Menu {
|
||||
func DefaultApplicationMenu() *Menu {
|
||||
menu := NewMenu()
|
||||
menu.AddRole(AppMenu)
|
||||
menu.AddRole(FileMenu)
|
||||
|
@ -106,7 +106,7 @@ func (l *linuxMenu) createMenu(name string, items []*MenuItem) *Menu {
|
||||
return menu
|
||||
}
|
||||
|
||||
func defaultApplicationMenu() *Menu {
|
||||
func DefaultApplicationMenu() *Menu {
|
||||
menu := NewMenu()
|
||||
menu.AddRole(AppMenu)
|
||||
menu.AddRole(FileMenu)
|
||||
|
140
v3/pkg/application/menu_test.go
Normal file
140
v3/pkg/application/menu_test.go
Normal file
@ -0,0 +1,140 @@
|
||||
package application_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
func TestMenu_FindByLabel(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
menu *application.Menu
|
||||
label string
|
||||
shouldError bool
|
||||
}{
|
||||
{
|
||||
name: "Find top-level item",
|
||||
menu: application.NewMenuFromItems(
|
||||
application.NewMenuItem("Target"),
|
||||
),
|
||||
label: "Target",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
name: "Find item in submenu",
|
||||
menu: application.NewMenuFromItems(
|
||||
application.NewMenuItem("Item 1"),
|
||||
application.NewSubmenu("Submenu", application.NewMenuFromItems(
|
||||
application.NewMenuItem("Subitem 1"),
|
||||
application.NewMenuItem("Target"),
|
||||
)),
|
||||
),
|
||||
label: "Target",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
name: "Not find item",
|
||||
menu: application.NewMenuFromItems(
|
||||
application.NewMenuItem("Item 1"),
|
||||
application.NewSubmenu("Submenu", application.NewMenuFromItems(
|
||||
application.NewMenuItem("Subitem 1"),
|
||||
application.NewMenuItem("Target"),
|
||||
)),
|
||||
),
|
||||
label: "Random",
|
||||
shouldError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
found := test.menu.FindByLabel(test.label)
|
||||
if test.shouldError && found != nil {
|
||||
t.Errorf("Expected error, but found %v", found)
|
||||
}
|
||||
if !test.shouldError && found == nil {
|
||||
t.Errorf("Expected item, but found none")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMenu_ItemAt(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
menu *application.Menu
|
||||
index int
|
||||
shouldError bool
|
||||
}{
|
||||
{
|
||||
name: "Valid index",
|
||||
menu: application.NewMenuFromItems(
|
||||
application.NewMenuItem("Item 1"),
|
||||
application.NewMenuItem("Item 2"),
|
||||
application.NewMenuItem("Target"),
|
||||
),
|
||||
index: 2,
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
name: "Index out of bounds (negative)",
|
||||
menu: application.NewMenuFromItems(
|
||||
application.NewMenuItem("Item 1"),
|
||||
application.NewMenuItem("Item 2"),
|
||||
),
|
||||
index: -1,
|
||||
shouldError: true,
|
||||
},
|
||||
{
|
||||
name: "Index out of bounds (too large)",
|
||||
menu: application.NewMenuFromItems(
|
||||
application.NewMenuItem("Item 1"),
|
||||
application.NewMenuItem("Item 2"),
|
||||
),
|
||||
index: 2,
|
||||
shouldError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
item := test.menu.ItemAt(test.index)
|
||||
if test.shouldError && item != nil {
|
||||
t.Errorf("Expected error, but found %v", item)
|
||||
}
|
||||
if !test.shouldError && item == nil {
|
||||
t.Errorf("Expected item, but found none")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMenu_RemoveMenuItem(t *testing.T) {
|
||||
itemToRemove := application.NewMenuItem("Target")
|
||||
itemToKeep := application.NewMenuItem("Item 1")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
menu *application.Menu
|
||||
item *application.MenuItem
|
||||
shouldFind bool
|
||||
}{
|
||||
{
|
||||
name: "Remove existing item",
|
||||
menu: application.NewMenuFromItems(itemToKeep, itemToRemove),
|
||||
item: itemToRemove,
|
||||
shouldFind: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
test.menu.RemoveMenuItem(test.item)
|
||||
found := test.menu.FindByLabel(test.item.Label())
|
||||
if !test.shouldFind && found != nil {
|
||||
t.Errorf("Expected item to be removed, but found %v", found)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -113,7 +113,7 @@ func (w *windowsMenu) ProcessCommand(cmdMsgID int) {
|
||||
item.handleClick()
|
||||
}
|
||||
|
||||
func defaultApplicationMenu() *Menu {
|
||||
func DefaultApplicationMenu() *Menu {
|
||||
menu := NewMenu()
|
||||
menu.AddRole(FileMenu)
|
||||
menu.AddRole(EditMenu)
|
||||
|
@ -62,7 +62,7 @@ type MenuItem struct {
|
||||
radioGroupMembers []*MenuItem
|
||||
}
|
||||
|
||||
func newMenuItem(label string) *MenuItem {
|
||||
func NewMenuItem(label string) *MenuItem {
|
||||
result := &MenuItem{
|
||||
id: uint(atomic.AddUintptr(&menuItemID, 1)),
|
||||
label: label,
|
||||
@ -72,7 +72,7 @@ func newMenuItem(label string) *MenuItem {
|
||||
return result
|
||||
}
|
||||
|
||||
func newMenuItemSeparator() *MenuItem {
|
||||
func NewMenuItemSeparator() *MenuItem {
|
||||
result := &MenuItem{
|
||||
id: uint(atomic.AddUintptr(&menuItemID, 1)),
|
||||
itemType: separator,
|
||||
@ -80,7 +80,7 @@ func newMenuItemSeparator() *MenuItem {
|
||||
return result
|
||||
}
|
||||
|
||||
func newMenuItemCheckbox(label string, checked bool) *MenuItem {
|
||||
func NewMenuItemCheckbox(label string, checked bool) *MenuItem {
|
||||
result := &MenuItem{
|
||||
id: uint(atomic.AddUintptr(&menuItemID, 1)),
|
||||
label: label,
|
||||
@ -91,7 +91,7 @@ func newMenuItemCheckbox(label string, checked bool) *MenuItem {
|
||||
return result
|
||||
}
|
||||
|
||||
func newMenuItemRadio(label string, checked bool) *MenuItem {
|
||||
func NewMenuItemRadio(label string, checked bool) *MenuItem {
|
||||
result := &MenuItem{
|
||||
id: uint(atomic.AddUintptr(&menuItemID, 1)),
|
||||
label: label,
|
||||
@ -102,7 +102,7 @@ func newMenuItemRadio(label string, checked bool) *MenuItem {
|
||||
return result
|
||||
}
|
||||
|
||||
func newSubMenuItem(label string) *MenuItem {
|
||||
func NewSubMenuItem(label string) *MenuItem {
|
||||
result := &MenuItem{
|
||||
id: uint(atomic.AddUintptr(&menuItemID, 1)),
|
||||
label: label,
|
||||
@ -115,7 +115,7 @@ func newSubMenuItem(label string) *MenuItem {
|
||||
return result
|
||||
}
|
||||
|
||||
func newRole(role Role) *MenuItem {
|
||||
func NewRole(role Role) *MenuItem {
|
||||
switch role {
|
||||
case AppMenu:
|
||||
return newAppMenu()
|
||||
@ -126,7 +126,7 @@ func newRole(role Role) *MenuItem {
|
||||
case ViewMenu:
|
||||
return newViewMenu()
|
||||
case ServicesMenu:
|
||||
return newServicesMenu()
|
||||
return NewServicesMenu()
|
||||
case SpeechMenu:
|
||||
return newSpeechMenu()
|
||||
case WindowMenu:
|
||||
@ -189,8 +189,8 @@ func newRole(role Role) *MenuItem {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newServicesMenu() *MenuItem {
|
||||
serviceMenu := newSubMenuItem("Services")
|
||||
func NewServicesMenu() *MenuItem {
|
||||
serviceMenu := NewSubMenuItem("Services")
|
||||
serviceMenu.role = ServicesMenu
|
||||
return serviceMenu
|
||||
}
|
||||
@ -237,6 +237,17 @@ func (m *MenuItem) SetAccelerator(shortcut string) *MenuItem {
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *MenuItem) GetAccelerator() string {
|
||||
if m.accelerator == nil {
|
||||
return ""
|
||||
}
|
||||
return m.accelerator.String()
|
||||
}
|
||||
|
||||
func (m *MenuItem) RemoveAccelerator() {
|
||||
m.accelerator = nil
|
||||
}
|
||||
|
||||
func (m *MenuItem) SetTooltip(s string) *MenuItem {
|
||||
m.tooltip = s
|
||||
if m.impl != nil {
|
||||
@ -285,6 +296,12 @@ func (m *MenuItem) SetHidden(hidden bool) *MenuItem {
|
||||
return m
|
||||
}
|
||||
|
||||
// GetSubmenu returns the submenu of the MenuItem.
|
||||
// If the MenuItem is not a submenu, it returns nil.
|
||||
func (m *MenuItem) GetSubmenu() *Menu {
|
||||
return m.submenu
|
||||
}
|
||||
|
||||
func (m *MenuItem) Checked() bool {
|
||||
return m.checked
|
||||
}
|
||||
@ -333,8 +350,8 @@ func (m *MenuItem) setContextData(data *ContextMenuData) {
|
||||
}
|
||||
}
|
||||
|
||||
// clone returns a deep copy of the MenuItem
|
||||
func (m *MenuItem) clone() *MenuItem {
|
||||
// Clone returns a deep copy of the MenuItem
|
||||
func (m *MenuItem) Clone() *MenuItem {
|
||||
result := &MenuItem{
|
||||
id: m.id,
|
||||
label: m.label,
|
||||
@ -348,7 +365,7 @@ func (m *MenuItem) clone() *MenuItem {
|
||||
role: m.role,
|
||||
}
|
||||
if m.submenu != nil {
|
||||
result.submenu = m.submenu.clone()
|
||||
result.submenu = m.submenu.Clone()
|
||||
}
|
||||
if m.accelerator != nil {
|
||||
result.accelerator = m.accelerator.clone()
|
||||
|
@ -419,13 +419,13 @@ func newSpeechMenu() *MenuItem {
|
||||
OnClick(func(ctx *Context) {
|
||||
C.stopSpeaking()
|
||||
})
|
||||
subMenu := newSubMenuItem("Speech")
|
||||
subMenu := NewSubMenuItem("Speech")
|
||||
subMenu.submenu = speechMenu
|
||||
return subMenu
|
||||
}
|
||||
|
||||
func newHideMenuItem() *MenuItem {
|
||||
return newMenuItem("Hide " + globalApplication.options.Name).
|
||||
return NewMenuItem("Hide " + globalApplication.options.Name).
|
||||
SetAccelerator("CmdOrCtrl+h").
|
||||
OnClick(func(ctx *Context) {
|
||||
C.hideApplication()
|
||||
@ -433,7 +433,7 @@ func newHideMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newHideOthersMenuItem() *MenuItem {
|
||||
return newMenuItem("Hide Others").
|
||||
return NewMenuItem("Hide Others").
|
||||
SetAccelerator("CmdOrCtrl+OptionOrAlt+h").
|
||||
OnClick(func(ctx *Context) {
|
||||
C.hideOthers()
|
||||
@ -441,14 +441,14 @@ func newHideOthersMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newUnhideMenuItem() *MenuItem {
|
||||
return newMenuItem("Show All").
|
||||
return NewMenuItem("Show All").
|
||||
OnClick(func(ctx *Context) {
|
||||
C.showAll()
|
||||
})
|
||||
}
|
||||
|
||||
func newUndoMenuItem() *MenuItem {
|
||||
return newMenuItem("Undo").
|
||||
return NewMenuItem("Undo").
|
||||
SetAccelerator("CmdOrCtrl+z").
|
||||
OnClick(func(ctx *Context) {
|
||||
C.undo()
|
||||
@ -457,7 +457,7 @@ func newUndoMenuItem() *MenuItem {
|
||||
|
||||
// newRedoMenuItem creates a new menu item for redoing the last action
|
||||
func newRedoMenuItem() *MenuItem {
|
||||
return newMenuItem("Redo").
|
||||
return NewMenuItem("Redo").
|
||||
SetAccelerator("CmdOrCtrl+Shift+z").
|
||||
OnClick(func(ctx *Context) {
|
||||
C.redo()
|
||||
@ -465,7 +465,7 @@ func newRedoMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newCutMenuItem() *MenuItem {
|
||||
return newMenuItem("Cut").
|
||||
return NewMenuItem("Cut").
|
||||
SetAccelerator("CmdOrCtrl+x").
|
||||
OnClick(func(ctx *Context) {
|
||||
C.cut()
|
||||
@ -473,7 +473,7 @@ func newCutMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newCopyMenuItem() *MenuItem {
|
||||
return newMenuItem("Copy").
|
||||
return NewMenuItem("Copy").
|
||||
SetAccelerator("CmdOrCtrl+c").
|
||||
OnClick(func(ctx *Context) {
|
||||
C.copy()
|
||||
@ -481,7 +481,7 @@ func newCopyMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newPasteMenuItem() *MenuItem {
|
||||
return newMenuItem("Paste").
|
||||
return NewMenuItem("Paste").
|
||||
SetAccelerator("CmdOrCtrl+v").
|
||||
OnClick(func(ctx *Context) {
|
||||
C.paste()
|
||||
@ -489,7 +489,7 @@ func newPasteMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newPasteAndMatchStyleMenuItem() *MenuItem {
|
||||
return newMenuItem("Paste and Match Style").
|
||||
return NewMenuItem("Paste and Match Style").
|
||||
SetAccelerator("CmdOrCtrl+OptionOrAlt+Shift+v").
|
||||
OnClick(func(ctx *Context) {
|
||||
C.pasteAndMatchStyle()
|
||||
@ -497,7 +497,7 @@ func newPasteAndMatchStyleMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newDeleteMenuItem() *MenuItem {
|
||||
return newMenuItem("Delete").
|
||||
return NewMenuItem("Delete").
|
||||
SetAccelerator("backspace").
|
||||
OnClick(func(ctx *Context) {
|
||||
C.delete()
|
||||
@ -505,7 +505,7 @@ func newDeleteMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newQuitMenuItem() *MenuItem {
|
||||
return newMenuItem("Quit " + globalApplication.options.Name).
|
||||
return NewMenuItem("Quit " + globalApplication.options.Name).
|
||||
SetAccelerator("CmdOrCtrl+q").
|
||||
OnClick(func(ctx *Context) {
|
||||
globalApplication.Quit()
|
||||
@ -513,7 +513,7 @@ func newQuitMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newSelectAllMenuItem() *MenuItem {
|
||||
return newMenuItem("Select All").
|
||||
return NewMenuItem("Select All").
|
||||
SetAccelerator("CmdOrCtrl+a").
|
||||
OnClick(func(ctx *Context) {
|
||||
C.selectAll()
|
||||
@ -521,14 +521,14 @@ func newSelectAllMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newAboutMenuItem() *MenuItem {
|
||||
return newMenuItem("About " + globalApplication.options.Name).
|
||||
return NewMenuItem("About " + globalApplication.options.Name).
|
||||
OnClick(func(ctx *Context) {
|
||||
globalApplication.ShowAboutDialog()
|
||||
})
|
||||
}
|
||||
|
||||
func newCloseMenuItem() *MenuItem {
|
||||
return newMenuItem("Close").
|
||||
return NewMenuItem("Close").
|
||||
SetAccelerator("CmdOrCtrl+w").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -539,7 +539,7 @@ func newCloseMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newReloadMenuItem() *MenuItem {
|
||||
return newMenuItem("Reload").
|
||||
return NewMenuItem("Reload").
|
||||
SetAccelerator("CmdOrCtrl+r").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -550,7 +550,7 @@ func newReloadMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newForceReloadMenuItem() *MenuItem {
|
||||
return newMenuItem("Force Reload").
|
||||
return NewMenuItem("Force Reload").
|
||||
SetAccelerator("CmdOrCtrl+Shift+r").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -561,7 +561,7 @@ func newForceReloadMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newToggleFullscreenMenuItem() *MenuItem {
|
||||
result := newMenuItem("Toggle Full Screen").
|
||||
result := NewMenuItem("Toggle Full Screen").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
if currentWindow != nil {
|
||||
@ -578,7 +578,7 @@ func newToggleFullscreenMenuItem() *MenuItem {
|
||||
|
||||
func newZoomResetMenuItem() *MenuItem {
|
||||
// reset zoom menu item
|
||||
return newMenuItem("Actual Size").
|
||||
return NewMenuItem("Actual Size").
|
||||
SetAccelerator("CmdOrCtrl+0").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -589,7 +589,7 @@ func newZoomResetMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newZoomInMenuItem() *MenuItem {
|
||||
return newMenuItem("Zoom In").
|
||||
return NewMenuItem("Zoom In").
|
||||
SetAccelerator("CmdOrCtrl+plus").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -600,7 +600,7 @@ func newZoomInMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newZoomOutMenuItem() *MenuItem {
|
||||
return newMenuItem("Zoom Out").
|
||||
return NewMenuItem("Zoom Out").
|
||||
SetAccelerator("CmdOrCtrl+-").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -611,7 +611,7 @@ func newZoomOutMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newMinimizeMenuItem() *MenuItem {
|
||||
return newMenuItem("Minimize").
|
||||
return NewMenuItem("Minimize").
|
||||
SetAccelerator("CmdOrCtrl+M").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -622,7 +622,7 @@ func newMinimizeMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newZoomMenuItem() *MenuItem {
|
||||
return newMenuItem("Zoom").
|
||||
return NewMenuItem("Zoom").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
if currentWindow != nil {
|
||||
@ -632,7 +632,7 @@ func newZoomMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newFullScreenMenuItem() *MenuItem {
|
||||
return newMenuItem("Fullscreen").
|
||||
return NewMenuItem("Fullscreen").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
if currentWindow != nil {
|
||||
|
@ -3,7 +3,7 @@
|
||||
package application
|
||||
|
||||
func newOpenDevToolsMenuItem() *MenuItem {
|
||||
return newMenuItem("Open Developer Tools").
|
||||
return NewMenuItem("Open Developer Tools").
|
||||
SetAccelerator("Alt+Command+I").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
|
@ -136,13 +136,13 @@ func newSpeechMenu() *MenuItem {
|
||||
OnClick(func(ctx *Context) {
|
||||
// C.stopSpeaking()
|
||||
})
|
||||
subMenu := newSubMenuItem("Speech")
|
||||
subMenu := NewSubMenuItem("Speech")
|
||||
subMenu.submenu = speechMenu
|
||||
return subMenu
|
||||
}
|
||||
|
||||
func newHideMenuItem() *MenuItem {
|
||||
return newMenuItem("Hide " + globalApplication.options.Name).
|
||||
return NewMenuItem("Hide " + globalApplication.options.Name).
|
||||
SetAccelerator("CmdOrCtrl+h").
|
||||
OnClick(func(ctx *Context) {
|
||||
|
||||
@ -151,7 +151,7 @@ func newHideMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newHideOthersMenuItem() *MenuItem {
|
||||
return newMenuItem("Hide Others").
|
||||
return NewMenuItem("Hide Others").
|
||||
SetAccelerator("CmdOrCtrl+OptionOrAlt+h").
|
||||
OnClick(func(ctx *Context) {
|
||||
// C.hideOthers()
|
||||
@ -159,14 +159,14 @@ func newHideOthersMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newUnhideMenuItem() *MenuItem {
|
||||
return newMenuItem("Show All").
|
||||
return NewMenuItem("Show All").
|
||||
OnClick(func(ctx *Context) {
|
||||
// C.showAll()
|
||||
})
|
||||
}
|
||||
|
||||
func newUndoMenuItem() *MenuItem {
|
||||
return newMenuItem("Undo").
|
||||
return NewMenuItem("Undo").
|
||||
SetAccelerator("CmdOrCtrl+z").
|
||||
OnClick(func(ctx *Context) {
|
||||
// C.undo()
|
||||
@ -175,7 +175,7 @@ func newUndoMenuItem() *MenuItem {
|
||||
|
||||
// newRedoMenuItem creates a new menu item for redoing the last action
|
||||
func newRedoMenuItem() *MenuItem {
|
||||
return newMenuItem("Redo").
|
||||
return NewMenuItem("Redo").
|
||||
SetAccelerator("CmdOrCtrl+Shift+z").
|
||||
OnClick(func(ctx *Context) {
|
||||
// C.redo()
|
||||
@ -183,7 +183,7 @@ func newRedoMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newCutMenuItem() *MenuItem {
|
||||
return newMenuItem("Cut").
|
||||
return NewMenuItem("Cut").
|
||||
SetAccelerator("CmdOrCtrl+x").
|
||||
OnClick(func(ctx *Context) {
|
||||
// C.cut()
|
||||
@ -191,7 +191,7 @@ func newCutMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newCopyMenuItem() *MenuItem {
|
||||
return newMenuItem("Copy").
|
||||
return NewMenuItem("Copy").
|
||||
SetAccelerator("CmdOrCtrl+c").
|
||||
OnClick(func(ctx *Context) {
|
||||
// C.copy()
|
||||
@ -199,7 +199,7 @@ func newCopyMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newPasteMenuItem() *MenuItem {
|
||||
return newMenuItem("Paste").
|
||||
return NewMenuItem("Paste").
|
||||
SetAccelerator("CmdOrCtrl+v").
|
||||
OnClick(func(ctx *Context) {
|
||||
// C.paste()
|
||||
@ -207,7 +207,7 @@ func newPasteMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newPasteAndMatchStyleMenuItem() *MenuItem {
|
||||
return newMenuItem("Paste and Match Style").
|
||||
return NewMenuItem("Paste and Match Style").
|
||||
SetAccelerator("CmdOrCtrl+OptionOrAlt+Shift+v").
|
||||
OnClick(func(ctx *Context) {
|
||||
// C.pasteAndMatchStyle()
|
||||
@ -215,7 +215,7 @@ func newPasteAndMatchStyleMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newDeleteMenuItem() *MenuItem {
|
||||
return newMenuItem("Delete").
|
||||
return NewMenuItem("Delete").
|
||||
SetAccelerator("backspace").
|
||||
OnClick(func(ctx *Context) {
|
||||
// C.delete()
|
||||
@ -223,7 +223,7 @@ func newDeleteMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newQuitMenuItem() *MenuItem {
|
||||
return newMenuItem("Quit " + globalApplication.options.Name).
|
||||
return NewMenuItem("Quit " + globalApplication.options.Name).
|
||||
SetAccelerator("CmdOrCtrl+q").
|
||||
OnClick(func(ctx *Context) {
|
||||
globalApplication.Quit()
|
||||
@ -231,7 +231,7 @@ func newQuitMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newSelectAllMenuItem() *MenuItem {
|
||||
return newMenuItem("Select All").
|
||||
return NewMenuItem("Select All").
|
||||
SetAccelerator("CmdOrCtrl+a").
|
||||
OnClick(func(ctx *Context) {
|
||||
// C.selectAll()
|
||||
@ -239,14 +239,14 @@ func newSelectAllMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newAboutMenuItem() *MenuItem {
|
||||
return newMenuItem("About " + globalApplication.options.Name).
|
||||
return NewMenuItem("About " + globalApplication.options.Name).
|
||||
OnClick(func(ctx *Context) {
|
||||
globalApplication.ShowAboutDialog()
|
||||
})
|
||||
}
|
||||
|
||||
func newCloseMenuItem() *MenuItem {
|
||||
return newMenuItem("Close").
|
||||
return NewMenuItem("Close").
|
||||
SetAccelerator("CmdOrCtrl+w").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -257,7 +257,7 @@ func newCloseMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newReloadMenuItem() *MenuItem {
|
||||
return newMenuItem("Reload").
|
||||
return NewMenuItem("Reload").
|
||||
SetAccelerator("CmdOrCtrl+r").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -268,7 +268,7 @@ func newReloadMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newForceReloadMenuItem() *MenuItem {
|
||||
return newMenuItem("Force Reload").
|
||||
return NewMenuItem("Force Reload").
|
||||
SetAccelerator("CmdOrCtrl+Shift+r").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -279,7 +279,7 @@ func newForceReloadMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newToggleFullscreenMenuItem() *MenuItem {
|
||||
result := newMenuItem("Toggle Full Screen").
|
||||
result := NewMenuItem("Toggle Full Screen").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
if currentWindow != nil {
|
||||
@ -296,7 +296,7 @@ func newToggleFullscreenMenuItem() *MenuItem {
|
||||
|
||||
func newZoomResetMenuItem() *MenuItem {
|
||||
// reset zoom menu item
|
||||
return newMenuItem("Actual Size").
|
||||
return NewMenuItem("Actual Size").
|
||||
SetAccelerator("CmdOrCtrl+0").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -307,7 +307,7 @@ func newZoomResetMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newZoomInMenuItem() *MenuItem {
|
||||
return newMenuItem("Zoom In").
|
||||
return NewMenuItem("Zoom In").
|
||||
SetAccelerator("CmdOrCtrl+plus").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -318,7 +318,7 @@ func newZoomInMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newZoomOutMenuItem() *MenuItem {
|
||||
return newMenuItem("Zoom Out").
|
||||
return NewMenuItem("Zoom Out").
|
||||
SetAccelerator("CmdOrCtrl+-").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -329,7 +329,7 @@ func newZoomOutMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newMinimizeMenuItem() *MenuItem {
|
||||
return newMenuItem("Minimize").
|
||||
return NewMenuItem("Minimize").
|
||||
SetAccelerator("CmdOrCtrl+M").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -340,7 +340,7 @@ func newMinimizeMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newZoomMenuItem() *MenuItem {
|
||||
return newMenuItem("Zoom").
|
||||
return NewMenuItem("Zoom").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
if currentWindow != nil {
|
||||
@ -350,7 +350,7 @@ func newZoomMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newFullScreenMenuItem() *MenuItem {
|
||||
return newMenuItem("Fullscreen").
|
||||
return NewMenuItem("Fullscreen").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
if currentWindow != nil {
|
||||
|
61
v3/pkg/application/menuitem_test.go
Normal file
61
v3/pkg/application/menuitem_test.go
Normal file
@ -0,0 +1,61 @@
|
||||
package application_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
func TestMenuItem_GetAccelerator(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
menuItem *application.MenuItem
|
||||
expectedAcc string
|
||||
}{
|
||||
{
|
||||
name: "Get existing accelerator",
|
||||
menuItem: application.NewMenuItem("Item 1").SetAccelerator("Ctrl+A"),
|
||||
expectedAcc: "ctrl+a",
|
||||
},
|
||||
{
|
||||
name: "Get non-existing accelerator",
|
||||
menuItem: application.NewMenuItem("Item 2"),
|
||||
expectedAcc: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
acc := test.menuItem.GetAccelerator()
|
||||
if acc != test.expectedAcc {
|
||||
t.Errorf("Expected accelerator to be %v, but got %v", test.expectedAcc, acc)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMenuItem_RemoveAccelerator(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
menuItem *application.MenuItem
|
||||
}{
|
||||
{
|
||||
name: "Remove existing accelerator",
|
||||
menuItem: application.NewMenuItem("Item 1").SetAccelerator("Ctrl+A"),
|
||||
},
|
||||
{
|
||||
name: "Remove non-existing accelerator",
|
||||
menuItem: application.NewMenuItem("Item 2"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
test.menuItem.RemoveAccelerator()
|
||||
acc := test.menuItem.GetAccelerator()
|
||||
if acc != "" {
|
||||
t.Errorf("Expected accelerator to be removed, but got %v", acc)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -191,7 +191,7 @@ func newDeleteMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newQuitMenuItem() *MenuItem {
|
||||
return newMenuItem("Quit").
|
||||
return NewMenuItem("Quit").
|
||||
OnClick(func(ctx *Context) {
|
||||
globalApplication.Quit()
|
||||
})
|
||||
@ -203,14 +203,14 @@ func newSelectAllMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newAboutMenuItem() *MenuItem {
|
||||
return newMenuItem("About " + globalApplication.options.Name).
|
||||
return NewMenuItem("About " + globalApplication.options.Name).
|
||||
OnClick(func(ctx *Context) {
|
||||
globalApplication.ShowAboutDialog()
|
||||
})
|
||||
}
|
||||
|
||||
func newCloseMenuItem() *MenuItem {
|
||||
return newMenuItem("Close").
|
||||
return NewMenuItem("Close").
|
||||
SetAccelerator("CmdOrCtrl+w").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -220,7 +220,7 @@ func newCloseMenuItem() *MenuItem {
|
||||
})
|
||||
}
|
||||
func newReloadMenuItem() *MenuItem {
|
||||
return newMenuItem("Reload").
|
||||
return NewMenuItem("Reload").
|
||||
SetAccelerator("CmdOrCtrl+r").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -231,7 +231,7 @@ func newReloadMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newForceReloadMenuItem() *MenuItem {
|
||||
return newMenuItem("Force Reload").
|
||||
return NewMenuItem("Force Reload").
|
||||
SetAccelerator("CmdOrCtrl+Shift+r").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -242,7 +242,7 @@ func newForceReloadMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newToggleFullscreenMenuItem() *MenuItem {
|
||||
result := newMenuItem("Toggle Full Screen").
|
||||
result := NewMenuItem("Toggle Full Screen").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
if currentWindow != nil {
|
||||
@ -259,7 +259,7 @@ func newToggleFullscreenMenuItem() *MenuItem {
|
||||
|
||||
func newZoomResetMenuItem() *MenuItem {
|
||||
// reset zoom menu item
|
||||
return newMenuItem("Actual Size").
|
||||
return NewMenuItem("Actual Size").
|
||||
SetAccelerator("CmdOrCtrl+0").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -270,7 +270,7 @@ func newZoomResetMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newZoomInMenuItem() *MenuItem {
|
||||
return newMenuItem("Zoom In").
|
||||
return NewMenuItem("Zoom In").
|
||||
SetAccelerator("CmdOrCtrl+plus").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -281,7 +281,7 @@ func newZoomInMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newZoomOutMenuItem() *MenuItem {
|
||||
return newMenuItem("Zoom Out").
|
||||
return NewMenuItem("Zoom Out").
|
||||
SetAccelerator("CmdOrCtrl+-").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -292,7 +292,7 @@ func newZoomOutMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newFullScreenMenuItem() *MenuItem {
|
||||
return newMenuItem("Fullscreen").
|
||||
return NewMenuItem("Fullscreen").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
if currentWindow != nil {
|
||||
@ -302,7 +302,7 @@ func newFullScreenMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newMinimizeMenuItem() *MenuItem {
|
||||
return newMenuItem("Minimize").
|
||||
return NewMenuItem("Minimize").
|
||||
SetAccelerator("CmdOrCtrl+M").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
@ -313,7 +313,7 @@ func newMinimizeMenuItem() *MenuItem {
|
||||
}
|
||||
|
||||
func newZoomMenuItem() *MenuItem {
|
||||
return newMenuItem("Zoom").
|
||||
return NewMenuItem("Zoom").
|
||||
OnClick(func(ctx *Context) {
|
||||
currentWindow := globalApplication.CurrentWindow()
|
||||
if currentWindow != nil {
|
||||
|
@ -67,7 +67,7 @@ func newFileMenu() *MenuItem {
|
||||
} else {
|
||||
fileMenu.AddRole(Quit)
|
||||
}
|
||||
subMenu := newSubMenuItem("File")
|
||||
subMenu := NewSubMenuItem("File")
|
||||
subMenu.submenu = fileMenu
|
||||
return subMenu
|
||||
}
|
||||
@ -83,7 +83,7 @@ func newViewMenu() *MenuItem {
|
||||
viewMenu.AddRole(ZoomOut)
|
||||
viewMenu.AddSeparator()
|
||||
viewMenu.AddRole(ToggleFullscreen)
|
||||
subMenu := newSubMenuItem("View")
|
||||
subMenu := NewSubMenuItem("View")
|
||||
subMenu.submenu = viewMenu
|
||||
return subMenu
|
||||
}
|
||||
@ -102,7 +102,7 @@ func newAppMenu() *MenuItem {
|
||||
appMenu.AddRole(UnHide)
|
||||
appMenu.AddSeparator()
|
||||
appMenu.AddRole(Quit)
|
||||
subMenu := newSubMenuItem(globalApplication.options.Name)
|
||||
subMenu := NewSubMenuItem(globalApplication.options.Name)
|
||||
subMenu.submenu = appMenu
|
||||
return subMenu
|
||||
}
|
||||
@ -127,7 +127,7 @@ func newEditMenu() *MenuItem {
|
||||
editMenu.AddSeparator()
|
||||
editMenu.AddRole(SelectAll)
|
||||
}
|
||||
subMenu := newSubMenuItem("Edit")
|
||||
subMenu := NewSubMenuItem("Edit")
|
||||
subMenu.submenu = editMenu
|
||||
return subMenu
|
||||
}
|
||||
@ -142,7 +142,7 @@ func newWindowMenu() *MenuItem {
|
||||
} else {
|
||||
menu.AddRole(Close)
|
||||
}
|
||||
subMenu := newSubMenuItem("Window")
|
||||
subMenu := NewSubMenuItem("Window")
|
||||
subMenu.submenu = menu
|
||||
return subMenu
|
||||
}
|
||||
@ -152,7 +152,7 @@ func newHelpMenu() *MenuItem {
|
||||
menu.Add("Learn More").OnClick(func(ctx *Context) {
|
||||
globalApplication.CurrentWindow().SetURL("https://wails.io")
|
||||
})
|
||||
subMenu := newSubMenuItem("Help")
|
||||
subMenu := NewSubMenuItem("Help")
|
||||
subMenu.submenu = menu
|
||||
return subMenu
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ func (w *linuxWebviewWindow) run() {
|
||||
|
||||
var menu = w.menu
|
||||
if menu == nil && globalApplication.ApplicationMenu != nil {
|
||||
menu = globalApplication.ApplicationMenu.clone()
|
||||
menu = globalApplication.ApplicationMenu.Clone()
|
||||
}
|
||||
if menu != nil {
|
||||
InvokeSync(func() {
|
||||
|
Loading…
Reference in New Issue
Block a user