diff --git a/mkdocs-website/docs/en/changelog.md b/mkdocs-website/docs/en/changelog.md index ad5d93421..aab683c67 100644 --- a/mkdocs-website/docs/en/changelog.md +++ b/mkdocs-website/docs/en/changelog.md @@ -57,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed `AlwaysOnTop` not working on Mac by [leaanthony](https://github.com/leaanthony) in [#3841](https://github.com/wailsapp/wails/pull/3841) - [darwin] Fixed `application.NewEditMenu` including a duplicate `PasteAndMatchStyle` role in the edit menu on Darwin by [johnmccabe](https://github.com/johnmccabe) in [#3839](https://github.com/wailsapp/wails/pull/3839) - [linux] Fixed aarch64 compilation [#3840](https://github.com/wailsapp/wails/issues/3840) in [#3854](https://github.com/wailsapp/wails/pull/3854) by [kodflow](https://github.com/kodflow) +- [windows] Fixed radio group menu items by [@leaanthony](https://github.com/leaanthony) ## v3.0.0-alpha.7 - 2024-09-18 diff --git a/v3/pkg/application/menu.go b/v3/pkg/application/menu.go index c67951b9d..948c95a9c 100644 --- a/v3/pkg/application/menu.go +++ b/v3/pkg/application/menu.go @@ -62,27 +62,29 @@ func (m *Menu) AddRole(role Role) *Menu { func (m *Menu) processRadioGroups() { var radioGroup []*MenuItem + + closeOutRadioGroups := func() { + if len(radioGroup) > 0 { + for _, item := range radioGroup { + item.radioGroupMembers = radioGroup + } + radioGroup = []*MenuItem{} + } + } + for _, item := range m.items { + if item.itemType != radio { + closeOutRadioGroups() + } if item.itemType == submenu { item.submenu.processRadioGroups() continue } if item.itemType == radio { radioGroup = append(radioGroup, item) - } else { - if len(radioGroup) > 0 { - for _, item := range radioGroup { - item.radioGroupMembers = radioGroup - } - radioGroup = nil - } - } - } - if len(radioGroup) > 0 { - for _, item := range radioGroup { - item.radioGroupMembers = radioGroup } } + closeOutRadioGroups() } func (m *Menu) SetLabel(label string) { diff --git a/v3/pkg/application/menu_windows.go b/v3/pkg/application/menu_windows.go index e0d3d8a0c..04a089982 100644 --- a/v3/pkg/application/menu_windows.go +++ b/v3/pkg/application/menu_windows.go @@ -60,6 +60,9 @@ func (w *windowsMenu) processMenu(parentMenu w32.HMENU, inputMenu *Menu) { if item.IsSeparator() { flags = flags | w32.MF_SEPARATOR } + if item.itemType == radio { + flags = flags | w32.MFT_RADIOCHECK + } if item.submenu != nil { flags = flags | w32.MF_POPUP diff --git a/v3/pkg/application/menuitem_windows.go b/v3/pkg/application/menuitem_windows.go index b776c5e37..b880d54d3 100644 --- a/v3/pkg/application/menuitem_windows.go +++ b/v3/pkg/application/menuitem_windows.go @@ -69,6 +69,10 @@ func (m *windowsMenuItem) IsCheckbox() bool { return m.itemType == checkbox } +func (m *windowsMenuItem) IsRadio() bool { + return m.itemType == radio +} + func (m *windowsMenuItem) Enabled() bool { return !m.disabled } @@ -146,6 +150,9 @@ func (m *windowsMenuItem) getMenuInfo() *w32.MENUITEMINFO { mii.FType = w32.MFT_SEPARATOR } else { mii.FType = w32.MFT_STRING + if m.IsRadio() { + mii.FType |= w32.MFT_RADIOCHECK + } thisText := m.label if m.menuItem.accelerator != nil { thisText += "\t" + m.menuItem.accelerator.String() @@ -160,7 +167,7 @@ func (m *windowsMenuItem) getMenuInfo() *w32.MENUITEMINFO { mii.FState |= w32.MFS_DISABLED } - if m.IsCheckbox() { + if m.IsCheckbox() || m.IsRadio() { mii.FMask |= w32.MIIM_CHECKMARKS } if m.Checked() { diff --git a/v3/pkg/application/popupmenu_windows.go b/v3/pkg/application/popupmenu_windows.go index 11a155b44..29bc9dafb 100644 --- a/v3/pkg/application/popupmenu_windows.go +++ b/v3/pkg/application/popupmenu_windows.go @@ -59,7 +59,7 @@ func (p *Win32Menu) newMenu() w32.HMENU { } func (p *Win32Menu) buildMenu(parentMenu w32.HMENU, inputMenu *Menu) { - var currentRadioGroup RadioGroup + currentRadioGroup := RadioGroup{} for _, item := range inputMenu.items { if item.Hidden() { if item.accelerator != nil { @@ -84,20 +84,22 @@ func (p *Win32Menu) buildMenu(parentMenu w32.HMENU, inputMenu *Menu) { if item.disabled { flags = flags | w32.MF_GRAYED } - if item.checked && item.IsCheckbox() { + if item.checked { flags = flags | w32.MF_CHECKED } if item.IsSeparator() { flags = flags | w32.MF_SEPARATOR } + if item.checked && item.IsRadio() { + flags = flags | w32.MFT_RADIOCHECK + } + if item.IsCheckbox() { p.checkboxItems[item] = append(p.checkboxItems[item], itemID) } if item.IsRadio() { - if currentRadioGroup != nil { - currentRadioGroup.Add(itemID, item) - } + currentRadioGroup.Add(itemID, item) } else { if len(currentRadioGroup) > 0 { for _, radioMember := range currentRadioGroup { @@ -219,6 +221,9 @@ func (p *Win32Menu) ProcessCommand(cmdMsgID int) bool { return false } if item.IsRadio() { + if item.checked { + return true + } item.checked = true p.updateRadioGroup(item) } diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index bb4af8c71..c34c1288f 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -241,6 +241,7 @@ func (w *windowsWebviewWindow) run() { theMenu = w.parent.options.Windows.Menu } if theMenu != nil { + theMenu.Update() w.menu = NewApplicationMenu(w, theMenu) w.menu.parentWindow = w appMenu = w.menu.menu