Skip to content

fix(v3/linux): Fix menu update by clearing menu#4875

Merged
leaanthony merged 4 commits into
wailsapp:v3-alphafrom
popaprozac:fix/linux-contextmenu-update
Jan 13, 2026
Merged

fix(v3/linux): Fix menu update by clearing menu#4875
leaanthony merged 4 commits into
wailsapp:v3-alphafrom
popaprozac:fix/linux-contextmenu-update

Conversation

@popaprozac

@popaprozac popaprozac commented Jan 12, 2026

Copy link
Copy Markdown
Contributor

Description

Added menuClear that gets called when processMenu runs to clear menu children if a menu already exists.

Fixes # (issue)

Type of change

Please select the option that is relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration using wails doctor.

  • Windows
  • macOS
  • Linux

If you checked Linux, please specify the distro and version.

Test Configuration

 Wails (v3.0.0-dev)  Wails Doctor

# System

┌────────────────────────────────────────────────────────────────────────────┐
| Name                | Debian GNU/Linux                                     |
| Version             | 13                                                   |
| ID                  | debian                                               |
| Branding            | 13 (trixie)                                          |
| Platform            | linux                                                |
| Architecture        | arm64                                                |
| Desktop Environment | KDE                                                  |
| NVIDIA Driver       | N/A                                                  |
| XDG_SESSION_TYPE    | wayland                                              |
| CPU                 |                                                      |
| GPU 1               | Virtio 1.0 GPU (Red Hat, Inc.) - Driver: virtio-pci  |
| Memory              | 4GB                                                  |
└────────────────────────────────────────────────────────────────────────────┘

# Build Environment

┌─────────────────────────────────────────────────────────┐
| Wails CLI    | v3.0.0-dev                               |
| Go Version   | go1.25.5                                 |
| Revision     | 9db2f74c443016aa31c2c25ff326f7e28a81dbc7 |
| Modified     | true                                     |
| -buildmode   | exe                                      |
| -compiler    | gc                                       |
| CGO_CFLAGS   |                                          |
| CGO_CPPFLAGS |                                          |
| CGO_CXXFLAGS |                                          |
| CGO_ENABLED  | 1                                        |
| CGO_LDFLAGS  |                                          |
| GOARCH       | arm64                                    |
| GOARM64      | v8.0                                     |
| GOOS         | linux                                    |
| vcs          | git                                      |
| vcs.modified | true                                     |
| vcs.revision | 9db2f74c443016aa31c2c25ff326f7e28a81dbc7 |
| vcs.time     | 2026-01-11T02:54:04Z                     |
└─────────────────────────────────────────────────────────┘

# Dependencies

┌────────────────────────────────────────────────────────────────┐
| gcc        | 12.12                                             |
| gtk3       | 3.24.49-3                                         |
| npm        | 9.2.0                                             |
| pkg-config | 1.8.1-4                                           |
| webkit2gtk | 2.50.4-1~deb13u1                                  |
| docker     | *Not installed (optional - for cross-compilation) |
|                                                                |
└─────────────────── * - Optional Dependency ────────────────────┘

# Checking for issues

 SUCCESS  No issues found

# Diagnosis

 SUCCESS  Your system is ready for Wails development!

Checklist:

  • I have updated website/src/pages/changelog.mdx with details of this PR
  • My code follows the general coding style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

  • Bug Fixes

    • Menus now clear existing items when updated, preventing duplicate or stale entries.
  • Documentation

    • Unreleased changelog updated to record the menu-clearing fix.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 12, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds platform-specific menuClear() implementations (CGO and purego) and invokes menuClear() from processMenu() to remove existing GTK menu children before rebuilding, plus a changelog entry noting the bug fix.

Changes

Cohort / File(s) Summary
Changelog
v3/UNRELEASED_CHANGELOG.md
Added Fixed entry: "Fix menu not clearing children on menu.Update()"
Linux CGO implementation
v3/pkg/application/linux_cgo.go
Added menuClear(menu *Menu) which retrieves GtkMenuShell children, removes each child, and frees the children list
Linux purego implementation
v3/pkg/application/linux_purego.go
Added gtkContainerGetChildren, gtkContainerRemove, gListFree bindings and implemented menuClear() using them to remove and free children
Menu processing logic
v3/pkg/application/menu_linux.go
Call menuClear() in processMenu() before rebuilding an existing menu to ensure prior items are removed

Sequence Diagram(s)

(No sequence diagrams generated — changes are focused and do not introduce a multi-component new control flow warranting a diagram.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

Bug, Linux, v3-alpha

Suggested reviewers

  • leaanthony

Poem

🐇 I hopped through GTK branches, found crumbs in the lair,
I cleared every submenu with meticulous care.
CGO or purego, I pulled out each thread,
Fresh menus now sprout — no leftovers spread. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: fixing menu updates on Linux by implementing a menuClear function to clear menu children when menus are rebuilt.
Description check ✅ Passed The description covers the core change and includes testing details, but omits the issue number reference despite the template requiring it via 'Fixes # (issue)'.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @v3/pkg/application/linux_purego.go:
- Around line 528-545: The GList returned by gtkContainerGetChildren in
menuClear is not freed (the `_ = originalList` no-op and comment are wrong); add
a g_list_free binding (e.g., gListFree) in init() alongside the other GTK
bindings and then call gListFree(originalList) at the end of menuClear after
removing children (remove the incorrect comment and the `_ = originalList`
line); reference the CGO implementation pattern used in linux_cgo.go for the
correct g_list_free usage and ensure the binding name matches the one you call
from menuClear.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9db2f74 and d03dd00.

📒 Files selected for processing (4)
  • v3/UNRELEASED_CHANGELOG.md
  • v3/pkg/application/linux_cgo.go
  • v3/pkg/application/linux_purego.go
  • v3/pkg/application/menu_linux.go
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: leaanthony
Repo: wailsapp/wails PR: 4031
File: v3/pkg/application/menu.go:199-202
Timestamp: 2025-01-24T22:41:18.566Z
Learning: In the Wails menu system (v3/pkg/application/menu.go), shared state between menus is intentionally designed and desirable. Methods like `Append()` and `Prepend()` should maintain shared references to menu items rather than creating deep copies.
📚 Learning: 2025-01-24T22:41:18.566Z
Learnt from: leaanthony
Repo: wailsapp/wails PR: 4031
File: v3/pkg/application/menu.go:199-202
Timestamp: 2025-01-24T22:41:18.566Z
Learning: In the Wails menu system (v3/pkg/application/menu.go), shared state between menus is intentionally designed and desirable. Methods like `Append()` and `Prepend()` should maintain shared references to menu items rather than creating deep copies.

Applied to files:

  • v3/pkg/application/linux_cgo.go
  • v3/pkg/application/menu_linux.go
  • v3/pkg/application/linux_purego.go
📚 Learning: 2026-01-04T08:01:00.038Z
Learnt from: symball
Repo: wailsapp/wails PR: 4853
File: v2/internal/system/system.go:128-152
Timestamp: 2026-01-04T08:01:00.038Z
Learning: In v2/internal/system/system.go, shared functions like checkLibrary are defined without build tags but are only invoked from platform-specific files (system_linux.go, system_windows.go, system_darwin.go) that have build constraints. Reviewers should ensure there are no runtime OS checks in system.go and that platform-specific behavior is controlled via build tags. If runtime switches exist, remove them in favor of compile-time platform constraints to reduce overhead and improve correctness.

Applied to files:

  • v3/pkg/application/linux_cgo.go
  • v3/pkg/application/menu_linux.go
  • v3/pkg/application/linux_purego.go
📚 Learning: 2025-10-17T23:16:11.570Z
Learnt from: Sammy-T
Repo: wailsapp/wails PR: 4570
File: v2/internal/frontend/desktop/linux/window_webkit6.go:97-108
Timestamp: 2025-10-17T23:16:11.570Z
Learning: For webkit_6/GTK4 builds in v2/internal/frontend/desktop/linux/window_webkit6.go, GTK widget creation should not be wrapped in invokeOnMainThread. The activation mechanism (activateWg + onActivate export) already handles thread safety, and additional wrapping would cause issues.

Applied to files:

  • v3/pkg/application/linux_purego.go
🧬 Code graph analysis (2)
v3/pkg/application/linux_cgo.go (1)
v3/pkg/application/menu.go (1)
  • Menu (30-35)
v3/pkg/application/linux_purego.go (1)
v3/pkg/application/menu.go (1)
  • Menu (30-35)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run Go Tests v3 (ubuntu-latest, 1.24)
  • GitHub Check: Run Go Tests v3 (windows-latest, 1.24)
  • GitHub Check: Run Go Tests v3 (macos-latest, 1.24)
  • GitHub Check: validate-changelog
🔇 Additional comments (4)
v3/UNRELEASED_CHANGELOG.md (1)

26-26: LGTM!

The changelog entry accurately describes the fix and follows the project's formatting guidelines.

v3/pkg/application/linux_purego.go (1)

142-143: LGTM!

The GTK container function declarations follow the established pattern in this file and correctly match the GTK3 API signatures.

v3/pkg/application/menu_linux.go (1)

32-35: LGTM!

The logic correctly clears existing menu items before rebuilding when updating an existing menu. The comment clearly explains the intent.

v3/pkg/application/linux_cgo.go (1)

734-750: LGTM!

The CGO implementation correctly handles memory management by freeing the GList after iterating through and removing children. This is the proper pattern for using gtk_container_get_children.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @v3/pkg/application/linux_purego.go:
- Around line 527-543: The call to gListFree in menuClear is missing a native
function declaration and init registration, causing a compile error; add a var
declaration for gListFree (matching the pattern used for gFree) after the
existing gFree var and then register it in init() (after the gFree registration)
so gListFree is available to menuClear and other callers.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d03dd00 and 019df8e.

📒 Files selected for processing (1)
  • v3/pkg/application/linux_purego.go
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: leaanthony
Repo: wailsapp/wails PR: 4031
File: v3/pkg/application/menu.go:199-202
Timestamp: 2025-01-24T22:41:18.566Z
Learning: In the Wails menu system (v3/pkg/application/menu.go), shared state between menus is intentionally designed and desirable. Methods like `Append()` and `Prepend()` should maintain shared references to menu items rather than creating deep copies.
📚 Learning: 2025-10-17T23:16:11.570Z
Learnt from: Sammy-T
Repo: wailsapp/wails PR: 4570
File: v2/internal/frontend/desktop/linux/window_webkit6.go:97-108
Timestamp: 2025-10-17T23:16:11.570Z
Learning: For webkit_6/GTK4 builds in v2/internal/frontend/desktop/linux/window_webkit6.go, GTK widget creation should not be wrapped in invokeOnMainThread. The activation mechanism (activateWg + onActivate export) already handles thread safety, and additional wrapping would cause issues.

Applied to files:

  • v3/pkg/application/linux_purego.go
📚 Learning: 2025-01-24T22:41:18.566Z
Learnt from: leaanthony
Repo: wailsapp/wails PR: 4031
File: v3/pkg/application/menu.go:199-202
Timestamp: 2025-01-24T22:41:18.566Z
Learning: In the Wails menu system (v3/pkg/application/menu.go), shared state between menus is intentionally designed and desirable. Methods like `Append()` and `Prepend()` should maintain shared references to menu items rather than creating deep copies.

Applied to files:

  • v3/pkg/application/linux_purego.go
📚 Learning: 2026-01-04T08:01:00.038Z
Learnt from: symball
Repo: wailsapp/wails PR: 4853
File: v2/internal/system/system.go:128-152
Timestamp: 2026-01-04T08:01:00.038Z
Learning: In v2/internal/system/system.go, shared functions like checkLibrary are defined without build tags but are only invoked from platform-specific files (system_linux.go, system_windows.go, system_darwin.go) that have build constraints. Reviewers should ensure there are no runtime OS checks in system.go and that platform-specific behavior is controlled via build tags. If runtime switches exist, remove them in favor of compile-time platform constraints to reduce overhead and improve correctness.

Applied to files:

  • v3/pkg/application/linux_purego.go
🧬 Code graph analysis (1)
v3/pkg/application/linux_purego.go (1)
v3/pkg/application/menu.go (1)
  • Menu (30-35)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Run Go Tests v3 (macos-latest, 1.24)
  • GitHub Check: Run Go Tests v3 (windows-latest, 1.24)
  • GitHub Check: Run Go Tests v3 (ubuntu-latest, 1.24)
🔇 Additional comments (2)
v3/pkg/application/linux_purego.go (2)

141-142: LGTM!

The function pointer declarations correctly match the GTK3 API signatures for gtk_container_get_children and gtk_container_remove.


298-299: LGTM!

Function registrations follow the existing pattern and use correct GTK3 symbol names.

Comment thread v3/pkg/application/linux_purego.go
@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
v3/pkg/application/linux_purego.go (1)

529-545: Implementation looks correct; consider adding a nil guard for robustness.

The GList iteration pattern is well-implemented: saving the original pointer before iteration and freeing it afterward. The GTK semantics are correctly handled—gtk_container_remove manages widget reference counts, and g_list_free frees the list structure.

However, there's no nil check on the menu parameter or its impl field. If called with a nil menu or uninitialized impl, this will panic on the type assertion at line 530. While this follows the same pattern as other menu functions in this file, a defensive check could prevent runtime panics from propagating.

🔧 Optional: Add defensive nil check
 func menuClear(menu *Menu) {
+	if menu == nil || menu.impl == nil {
+		return
+	}
 	menuShell := pointer((menu.impl).(*linuxMenu).native)
 	children := gtkContainerGetChildren(menuShell)
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 019df8e and 768efe6.

📒 Files selected for processing (1)
  • v3/pkg/application/linux_purego.go
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-10-17T23:16:11.570Z
Learnt from: Sammy-T
Repo: wailsapp/wails PR: 4570
File: v2/internal/frontend/desktop/linux/window_webkit6.go:97-108
Timestamp: 2025-10-17T23:16:11.570Z
Learning: For webkit_6/GTK4 builds in v2/internal/frontend/desktop/linux/window_webkit6.go, GTK widget creation should not be wrapped in invokeOnMainThread. The activation mechanism (activateWg + onActivate export) already handles thread safety, and additional wrapping would cause issues.

Applied to files:

  • v3/pkg/application/linux_purego.go
📚 Learning: 2025-01-24T22:41:18.566Z
Learnt from: leaanthony
Repo: wailsapp/wails PR: 4031
File: v3/pkg/application/menu.go:199-202
Timestamp: 2025-01-24T22:41:18.566Z
Learning: In the Wails menu system (v3/pkg/application/menu.go), shared state between menus is intentionally designed and desirable. Methods like `Append()` and `Prepend()` should maintain shared references to menu items rather than creating deep copies.

Applied to files:

  • v3/pkg/application/linux_purego.go
📚 Learning: 2026-01-04T08:01:00.038Z
Learnt from: symball
Repo: wailsapp/wails PR: 4853
File: v2/internal/system/system.go:128-152
Timestamp: 2026-01-04T08:01:00.038Z
Learning: In v2/internal/system/system.go, shared functions like checkLibrary are defined without build tags but are only invoked from platform-specific files (system_linux.go, system_windows.go, system_darwin.go) that have build constraints. Reviewers should ensure there are no runtime OS checks in system.go and that platform-specific behavior is controlled via build tags. If runtime switches exist, remove them in favor of compile-time platform constraints to reduce overhead and improve correctness.

Applied to files:

  • v3/pkg/application/linux_purego.go
🧬 Code graph analysis (1)
v3/pkg/application/linux_purego.go (1)
v3/pkg/application/menu.go (1)
  • Menu (30-35)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Cleanup build artifacts
  • GitHub Check: Run Go Tests v3 (macos-latest, 1.24)
  • GitHub Check: Run Go Tests v3 (windows-latest, 1.24)
  • GitHub Check: Run Go Tests v3 (ubuntu-latest, 1.24)
🔇 Additional comments (2)
v3/pkg/application/linux_purego.go (2)

108-108: LGTM!

The GTK/GLib function declarations follow the correct signatures for g_list_free, gtk_container_get_children, and gtk_container_remove.

Also applies to: 142-143


266-266: LGTM!

The function registrations follow the established pattern and use the correct GTK symbol names.

Also applies to: 300-301

@leaanthony leaanthony merged commit 37fb9b9 into wailsapp:v3-alpha Jan 13, 2026
90 checks passed
Grantmartin2002 pushed a commit to Grantmartin2002/wails that referenced this pull request Apr 29, 2026
* clear menu

* update changelog

* free list

* register glistfree
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants