Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More control over menus #4031

Open
wants to merge 12 commits into
base: v3-alpha
Choose a base branch
from
Open

More control over menus #4031

wants to merge 12 commits into from

Conversation

FalcoG
Copy link

@FalcoG FalcoG commented Jan 23, 2025

Description

Allows a menu to be cleared and in addition to Menu.Append, you can also now use Menu.Prepend to insert items before an existing menu.

My app has dynamic menu items that are at the top of a menu, which requires more control over the menu than previously possible. More detail and motivation is seen in the linked issue.

Fixes #4030

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?

I've linked up wails (go work use ../../wails/v3) and tried the following: https://gist.github.com/FalcoG/b38517339969008195df7e51346db6be

  • Windows
  • macOS
  • Linux

Test Configuration

# System
┌─────────────────────────────────────────────────┐
| Name          | MacOS                           |
| Version       | 15.1.1                          |
| ID            | 24B91                           |
| Branding      | MacOS 15.1.1                    |
| Platform      | darwin                          |
| Architecture  | arm64                           |
| Apple Silicon | true                            |
| CPU           | Apple M1                        |
| CPU 1         | Apple M1                        |
| CPU 2         | Apple M1                        |
| GPU           | 8 cores, Metal Support: Metal 3 |
| Memory        | 16 GB                           |
└─────────────────────────────────────────────────┘

# Build Environment
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
| Wails CLI      | v3.0.0-alpha.8.3                                                                                                          |
| Go Version     | go1.23.4                                                                                                                  |
| -buildmode     | exe                                                                                                                       |
| -compiler      | gc                                                                                                                        |
| CGO_CFLAGS     |                                                                                                                           |
| CGO_CPPFLAGS   |                                                                                                                           |
| CGO_CXXFLAGS   |                                                                                                                           |
| CGO_ENABLED    | 1                                                                                                                         |
| CGO_LDFLAGS    |                                                                                                                           |
| DefaultGODEBUG | asynctimerchan=1,gotypesalias=0,httpservecontentkeepheaders=1,tls3des=1,tlskyber=0,x509keypairleaf=0,x509negativeserial=1 |
| GOARCH         | arm64                                                                                                                     |
| GOARM64        | v8.0                                                                                                                      |
| GOOS           | darwin                                                                                                                    |
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

# Dependencies
┌────────────────────────────────────────────────────────────────────────┐
| npm             | 10.9.2                                               |
| *NSIS           | Not Installed. Install with `brew install makensis`. |
| Xcode cli tools | 2409                                                 |
└─────────────────────── * - Optional Dependency ────────────────────────┘

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

  • New Features

    • Added methods to enhance menu management:
      • Clear all menu items
      • Append menu items to an existing menu
      • Prepend menu items to an existing menu
    • Introduced support for aarch64 AppImage builds and a diagnostics section for wails doctor.
    • Added application.NewServiceWithOptions for service initialization with extra configuration.
  • Bug Fixes

    • Resolved issues with the Windows and Linux Edit Menu and dependency cycles in the binding generator output.
    • Addressed the nil menu issue when calling RegisterContextMenu.
  • Documentation

    • Updated changelog to reflect new features and fixes.
    • Added sections on "Combining menus" and "Clearing a menu" in the documentation.

Copy link
Contributor

coderabbitai bot commented Jan 23, 2025

Walkthrough

The pull request introduces several new methods to the Menu struct in the v3/pkg/application/menu.go file, enhancing its functionality for managing menu items. Key additions include the Clear() method for resetting the menu items, the Destroy() method for cleaning up resources, and the Append() and Prepend() methods for adding items from one menu to another. Documentation updates reflect these changes, including new sections on menu management and enhancements to the service API.

Changes

File Change Summary
v3/pkg/application/menu.go Added methods: Clear(), Destroy(), Append(in *Menu), and Prepend(in *Menu) to the Menu struct.
docs/src/content/docs/changelog.mdx Updated changelog with new methods Menu.Clear, Menu.Prepend, and application.NewServiceWithOptions, along with other enhancements and fixes.
docs/src/content/docs/guides/menus.mdx Added sections on "Combining menus" and "Clearing a menu" with code examples.
v3/pkg/application/menuitem.go Added method Destroy() to MenuItem struct for resource cleanup. Updated menuItemImpl interface to include destroy().
v3/pkg/application/linux_cgo.go Added function menuItemDestroy(widget pointer) for GTK widget destruction.
v3/pkg/application/menuitem_darwin.go Added method destroy() to macosMenuItem struct and function destroyMenuItem(void* nsMenuItem).
v3/pkg/application/menuitem_linux.go Added method destroy() to linuxMenuItem struct for controlled destruction.
v3/pkg/application/menuitem_windows.go Added method destroy() to windowsMenuItem struct for menu item removal.
v3/pkg/application/systemtray_linux.go Added empty destroy() method to systrayMenuItem struct.

Assessment against linked issues

Objective Addressed Explanation
Clear menu items
Prepend menu items
Update menu dynamically

Possibly related PRs

  • New ContextMenu API + example #4013: The changes in the main PR introduce new methods to the Menu struct, which are directly related to the context menu functionality introduced in the retrieved PR, specifically the ContextMenu type that embeds Menu and the methods Clear() and Prepend() that enhance menu management.

Poem

🐰 A rabbit's menu dance, so neat and light,
Clearing, appending with pure delight!
Prepend or add, the menu's now free,
Hopping through items with glee! 🥕
Code magic sprinkled, just right! 🍃

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@FalcoG FalcoG changed the title V3 alpha More control over menus Jan 23, 2025
@FalcoG FalcoG changed the base branch from master to v3-alpha January 23, 2025 10:34
@leaanthony
Copy link
Member

leaanthony commented Jan 23, 2025

Thanks 🙏 Please could you add an entry to the changelog located at docs/src/content/docs/changelog.mdx? Thanks!
We also need to change the menu documentation too in docs/src/content/docs/guides/menus.mdx

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 631c8a1 and 7f5ae65.

📒 Files selected for processing (1)
  • v3/pkg/application/menu.go (2 hunks)
🔇 Additional comments (1)
v3/pkg/application/menu.go (1)

Line range hint 72-202: Add tests and update documentation for new menu methods.

As requested in the PR comments, please:

  1. Add an entry to the changelog in docs/src/content/docs/changelog.mdx
  2. Update the menu documentation in docs/src/content/docs/guides/menus.mdx

Additionally, consider adding test cases for:

  • Clear method with nested submenus
  • Append/Prepend with nil input
  • Append/Prepend with empty menus
  • Append/Prepend maintaining proper menu state
✅ Verification successful

Review comment is accurate - documentation and tests are missing

The verification confirms that:

  • No tests exist for the new Clear, Append, and Prepend methods
  • Documentation updates are missing in both:
    • docs/src/content/docs/changelog.mdx
    • docs/src/content/docs/guides/menus.mdx
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for existing tests of the new methods
rg -l "TestMenu.*(?:Clear|Append|Prepend)" --type go

Length of output: 54


Script:

#!/bin/bash
# Find all test files and menu-related tests
echo "=== All test files ==="
fd "_test\.go$"

echo -e "\n=== Menu-related test content ==="
rg "func Test.*Menu" --type go

echo -e "\n=== Check documentation files ==="
ls docs/src/content/docs/changelog.mdx docs/src/content/docs/guides/menus.mdx 2>/dev/null || echo "Documentation files not found"

Length of output: 3727


Script:

#!/bin/bash
# Check documentation content for mentions of new methods
echo "=== Changelog content ==="
rg -A 5 "Clear|Append|Prepend" docs/src/content/docs/changelog.mdx || echo "No mentions in changelog"

echo -e "\n=== Menu documentation content ==="
rg -A 5 "Clear|Append|Prepend" docs/src/content/docs/guides/menus.mdx || echo "No mentions in menu guide"

Length of output: 406

v3/pkg/application/menu.go Outdated Show resolved Hide resolved
v3/pkg/application/menu.go Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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)
docs/src/content/docs/guides/menus.mdx (1)

59-76: LGTM! Consider adding error handling details.

The "Combining menus" section is well-documented with clear examples. The code demonstrates both Append and Prepend operations effectively.

Consider adding information about:

  • Return values of these methods
  • Error handling scenarios
  • Thread safety considerations when modifying menus
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f5ae65 and a66e1f0.

📒 Files selected for processing (2)
  • docs/src/content/docs/changelog.mdx (1 hunks)
  • docs/src/content/docs/guides/menus.mdx (1 hunks)
🔇 Additional comments (2)
docs/src/content/docs/guides/menus.mdx (1)

78-91: LGTM! The example effectively demonstrates menu clearing.

The "Clearing a menu" section provides a clear explanation and practical example of using the Clear method.

docs/src/content/docs/changelog.mdx (1)

43-43: LGTM! Changelog entry is accurate and well-formatted.

The entry correctly documents the addition of Menu.Clear and Menu.Prepend methods, with proper attribution and PR reference.

@FalcoG
Copy link
Author

FalcoG commented Jan 23, 2025

Done! Added it to the changelog & have written in the docs on how to use the new functions. Might also write some tray docs soon but that's out of scope for this change.

Add notes to documentation.
@leaanthony
Copy link
Member

@FalcoG - I've added some docs and a Destroy method for those who want to release the memory of menus. LMK what you think 👍

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89ea21a and e521102.

📒 Files selected for processing (7)
  • docs/src/content/docs/guides/menus.mdx (1 hunks)
  • v3/pkg/application/linux_cgo.go (1 hunks)
  • v3/pkg/application/menu.go (2 hunks)
  • v3/pkg/application/menuitem.go (2 hunks)
  • v3/pkg/application/menuitem_darwin.go (2 hunks)
  • v3/pkg/application/menuitem_linux.go (1 hunks)
  • v3/pkg/application/menuitem_windows.go (1 hunks)
🧰 Additional context used
📓 Learnings (1)
v3/pkg/application/menu.go (1)
Learnt from: leaanthony
PR: wailsapp/wails#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.
🔇 Additional comments (10)
v3/pkg/application/menuitem_windows.go (1)

99-101: LGTM! Clean implementation of menu item destruction.

The implementation correctly uses the Windows API to remove the menu item using its handle and identifier.

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

44-44: LGTM! Interface update for resource cleanup.

The addition of destroy() to the menuItemImpl interface ensures consistent cleanup across all platform implementations.

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

24-30: LGTM! Thread-safe implementation with proper signal handling.

The implementation correctly:

  • Uses InvokeSync for thread safety
  • Handles signal blocking/unblocking
  • Follows the established pattern in the file
v3/pkg/application/menuitem_darwin.go (1)

352-354: LGTM! Simple and effective Go wrapper.

The Go implementation correctly wraps the C function for cleanup.

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

590-592: LGTM! Clean implementation of widget destruction.

The function correctly uses gtk_widget_destroy to clean up GTK widgets, which is essential for proper resource management.

v3/pkg/application/menu.go (4)

72-75: LGTM! Simple and effective menu clearing.

The implementation efficiently clears menu items by setting the slice to nil, allowing Go's garbage collector to handle cleanup.


77-82: LGTM! Thorough cleanup in Destroy method.

The implementation properly calls Destroy() on each item before clearing the slice, ensuring complete resource cleanup.


201-204: LGTM! Maintains intended shared state.

The implementation correctly maintains shared menu item references as intended by the design.


206-209: LGTM! Maintains intended shared state.

The implementation correctly maintains shared menu item references as intended by the design.

docs/src/content/docs/guides/menus.mdx (1)

59-117: LGTM! Comprehensive and well-structured documentation.

The documentation effectively:

  • Explains the new menu manipulation features
  • Provides clear code examples
  • Includes important notes about state sharing and memory management
  • Maintains consistency with the implementation

Comment on lines 430 to 451
func (m *MenuItem) Destroy() {
// Clean up resources
if m.impl != nil {
m.impl.destroy()
}
if m.submenu != nil {
m.submenu.Destroy()
m.submenu = nil
}

if m.contextMenuData != nil {
m.contextMenuData = nil
}

if m.accelerator != nil {
m.accelerator = nil
}

m.callback = nil
m.radioGroupMembers = nil

}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add cleanup of menuItemMap in Destroy().

The implementation thoroughly cleans up resources but should also remove the menu item from the global menuItemMap to prevent memory leaks.

Apply this diff to add the cleanup:

 func (m *MenuItem) Destroy() {
+    menuItemMapLock.Lock()
+    delete(menuItemMap, m.id)
+    menuItemMapLock.Unlock()
+
     // Clean up resources
     if m.impl != nil {
         m.impl.destroy()
     }

Committable suggestion skipped: line range outside the PR's diff.

v3/pkg/application/menuitem_darwin.go Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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/menuitem.go (1)

436-460: Add documentation for the Destroy method.

Please add documentation that explains:

  • The purpose and cleanup process
  • Whether it's safe to call multiple times
  • Any side effects users should be aware of

Example documentation:

+// Destroy releases all resources associated with the MenuItem.
+// This includes cleaning up platform-specific implementations,
+// removing it from the global menuItemMap, and recursively
+// destroying any submenu. It's safe to call this method
+// multiple times on the same MenuItem.
 func (m *MenuItem) Destroy() {
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e521102 and b8d6062.

📒 Files selected for processing (1)
  • v3/pkg/application/menuitem.go (3 hunks)
🔇 Additional comments (2)
v3/pkg/application/menuitem.go (2)

36-40: LGTM! Thread-safe implementation of map cleanup.

The function is well-implemented with proper synchronization using mutex lock/unlock and follows Go best practices.


436-460: LGTM! Thorough cleanup implementation.

The implementation thoroughly handles resource cleanup by:

  • Removing the item from the global map
  • Cleaning up platform-specific resources
  • Recursively destroying submenus
  • Clearing all references to prevent memory leaks

@FalcoG
Copy link
Author

FalcoG commented Jan 26, 2025

@FalcoG - I've added some docs and a Destroy method for those who want to release the memory of menus. LMK what you think 👍

Great addition! That's a convenient way to remove it completely. Also didn't know about the submenu memory thing, good catch.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b8d6062 and 5e44c51.

📒 Files selected for processing (1)
  • v3/pkg/application/menu.go (2 hunks)
🧰 Additional context used
📓 Learnings (1)
v3/pkg/application/menu.go (1)
Learnt from: leaanthony
PR: wailsapp/wails#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.
🔇 Additional comments (2)
v3/pkg/application/menu.go (2)

80-85: LGTM! Thorough cleanup implementation.

The Destroy method properly cleans up resources by destroying each item and clearing the items slice.


72-78: 🛠️ Refactor suggestion

Consider UI consistency in Clear method.

The Clear method should trigger a UI update after clearing items to ensure the menu's visual state remains consistent.

 // Clear all menu items
 func (m *Menu) Clear() {
 	for _, item := range m.items {
 		removeMenuItemByID(item.id)
 	}
 	m.items = nil
+	m.Update()
 }

Likely invalid or redundant comment.

v3/pkg/application/menu.go Outdated Show resolved Hide resolved
v3/pkg/application/menu.go Outdated Show resolved Hide resolved
leaanthony and others added 2 commits January 28, 2025 20:26
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
v3/pkg/application/menu.go (3)

80-85: Enhance documentation for Destroy method.

The implementation looks good, but consider adding documentation to clarify the purpose and when to use Destroy() vs Clear().

+// Destroy releases all resources associated with the menu and its items.
+// Use this method when you want to completely clean up the menu and its resources.
 func (m *Menu) Destroy() {

204-211: Enhance documentation for Append method.

The implementation correctly maintains shared state and includes proper checks. Consider improving the documentation to better describe the behavior.

-// Insert menu after an existing menu
+// Append adds all items from the input menu to the end of this menu.
+// The items maintain shared state with the input menu.
 func (m *Menu) Append(in *Menu) {

Line range hint 72-215: Consider adding method chaining for better fluent interface.

The new methods enhance menu control as intended. Consider returning the menu instance from these methods to enable method chaining, which would align with the fluent interface pattern used elsewhere in the codebase.

Example implementation:

-func (m *Menu) Clear() {
+func (m *Menu) Clear() *Menu {
     // ... existing implementation ...
+    return m
 }

-func (m *Menu) Append(in *Menu) {
+func (m *Menu) Append(in *Menu) *Menu {
     // ... existing implementation ...
+    return m
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5e44c51 and d0bd216.

📒 Files selected for processing (1)
  • v3/pkg/application/menu.go (2 hunks)
🧰 Additional context used
📓 Learnings (1)
v3/pkg/application/menu.go (1)
Learnt from: leaanthony
PR: wailsapp/wails#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.
🔇 Additional comments (1)
v3/pkg/application/menu.go (1)

213-215: 🛠️ Refactor suggestion

Add safety check and UI update to Prepend method.

The Prepend method should include the same safety features as Append while maintaining shared state.

-// Insert menu before an existing menu
+// Prepend adds all items from the input menu to the beginning of this menu.
+// The items maintain shared state with the input menu.
 func (m *Menu) Prepend(in *Menu) {
+    if in == nil {
+        return
+    }
 	m.items = append(in.items, m.items...)
+	m.Update()
 }

Likely invalid or redundant comment.

v3/pkg/application/menu.go Show resolved Hide resolved
@leaanthony leaanthony enabled auto-merge (squash) January 28, 2025 10:14
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0bd216 and d68e21b.

📒 Files selected for processing (3)
  • docs/src/content/docs/changelog.mdx (1 hunks)
  • v3/pkg/application/menu.go (2 hunks)
  • v3/pkg/application/systemtray_linux.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/src/content/docs/changelog.mdx
🧰 Additional context used
📓 Learnings (1)
v3/pkg/application/menu.go (1)
Learnt from: leaanthony
PR: wailsapp/wails#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.
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Run Go Tests (ubuntu-latest, 1.23)
  • GitHub Check: Run Go Tests (macos-latest, 1.23)
  • GitHub Check: Run Go Tests (windows-latest, 1.23)
🔇 Additional comments (3)
v3/pkg/application/menu.go (3)

80-85: LGTM! Clean implementation of resource cleanup.

The Destroy() method properly cleans up resources by destroying each menu item and clearing the items slice.


72-78: 🛠️ Refactor suggestion

Add UI update and submenu cleanup.

The Clear() method should:

  1. Clean up submenu resources
  2. Call Update() to ensure UI consistency
 // Clear all menu items
 func (m *Menu) Clear() {
 	for _, item := range m.items {
+		if item.submenu != nil {
+			item.submenu.Clear()
+		}
 		removeMenuItemByID(item.id)
 	}
 	m.items = nil
+	m.Update()
 }

Likely invalid or redundant comment.


212-215: 🛠️ Refactor suggestion

Add safety check, UI update, and improve comment.

The implementation should include nil check and UI update while maintaining shared state.

-// Prepend menu before an existing menu
+// Prepend items from the input menu to the beginning of this menu
 func (m *Menu) Prepend(in *Menu) {
+	if in == nil {
+		return
+	}
 	m.items = append(in.items, m.items...)
+	m.Update()
 }

Likely invalid or redundant comment.

Comment on lines +89 to +90
func (s *systrayMenuItem) destroy() {}

Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

🛠️ Refactor suggestion

Empty destroy() method needs DBus cleanup implementation

The empty implementation is inconsistent with other platform implementations that properly clean up their resources. Based on the codebase patterns:

  • Remove DBus menu item registration and clean up associated DBus resources
  • Clear references to parent system tray and MenuItem
  • Consider implementing signal blocking during cleanup, similar to linuxMenuItem.destroy()
🔗 Analysis chain

Implement cleanup logic in the destroy() method.

The empty implementation might lead to resource leaks. Consider cleaning up the DBus resources and references held by the systrayMenuItem.

Let's check how other implementations handle cleanup:

Consider implementing the following cleanup tasks:

  1. Remove DBus menu item registration
  2. Clear references to parent system tray
  3. Clean up any DBus-specific resources
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other destroy method implementations
rg -A 5 "func.*destroy\(\)" --type go

Length of output: 6427

Comment on lines +204 to 210
// Append menu to an existing menu
func (m *Menu) Append(in *Menu) {
if in == nil {
return
}
m.items = append(m.items, in.items...)
}
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 28, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add UI update after appending items.

The implementation correctly maintains shared state, but should call Update() to refresh the UI.

 // Append menu to an existing menu
 func (m *Menu) Append(in *Menu) {
 	if in == nil {
 		return
 	}
 	m.items = append(m.items, in.items...)
+	m.Update()
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Append menu to an existing menu
func (m *Menu) Append(in *Menu) {
if in == nil {
return
}
m.items = append(m.items, in.items...)
}
// Append menu to an existing menu
func (m *Menu) Append(in *Menu) {
if in == nil {
return
}
m.items = append(m.items, in.items...)
m.Update()
}

Copy link
Member

Choose a reason for hiding this comment

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

Update is meant to be called manually

Copy link
Contributor

Choose a reason for hiding this comment

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

@leaanthony Understood, I'll retract that suggestion. The manual Update() pattern gives users more control over UI refresh timing.

(`ω´)


✏️ Learnings added
Learnt from: leaanthony
PR: wailsapp/wails#4031
File: v3/pkg/application/menu.go:204-210
Timestamp: 2025-01-28T20:27:39.389Z
Learning: In the Wails menu system, Update() is meant to be called manually by users to refresh the UI. Methods like Append(), Clone() etc. should not automatically call Update() as this control is intentionally left to the user.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

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.

[v3] More update control over existing menus
2 participants