Skip to content

feat(menu): support declarative hierarchical tree menu via JSON - #151

Merged
wflixu merged 2 commits into
wflixu:devfrom
Juns-g:feature/hierarchical-tree-menu
Sep 13, 2026
Merged

feat(menu): support declarative hierarchical tree menu via JSON#151
wflixu merged 2 commits into
wflixu:devfrom
Juns-g:feature/hierarchical-tree-menu

Conversation

@Juns-g

@Juns-g Juns-g commented Sep 12, 2026

Copy link
Copy Markdown

Summary

Currently, RClick's context menu collapse behavior is an all-or-nothing boolean switch (actionsCollapsed, appsCollapsed, newFilesCollapsed). This makes it difficult for users to keep their most-used apps/actions at the top level while grouping secondary utilities into categorized submenus.

This PR introduces a declarative hierarchical menu schema driven by a shared JSON configuration (custom_menu.json), enabling:

  1. Mixed Top-Level & Nested Items: Directly pin high-frequency apps/actions at the root level while organizing other items into arbitrary-depth submenus.
  2. Declarative Tree Model: Supports item, submenu (recursive), and separator nodes with human-friendly references (app path, file extension, action ID).
  3. 100% Backward Compatible: If no custom_menu.json exists or if parsing fails, it gracefully falls back to the original default categorized menu.
  4. Bug Fixes:
    • Fixed template ID and path loss across save/reload in ConfigService.
    • Added robust candidate URLs with fallback for opening macOS Accessibility system settings on macOS 15+.

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 📝 Documentation update
  • 🧪 Test addition/update

Screenshots

Top-Level Items + Submenu Multi-level Nested Submenu (iWork) Actions Submenu

Testing

Manual Testing

  • App launches and appears in menu bar
  • Right-click menu works correctly in Finder with top-level and nested items
  • Dark mode looks correct with native SF Symbols and App icons
  • Settings persist across restarts
  • FinderSync extension loads properly
  • Deleting custom_menu.json seamlessly restores default menu

Build Verification

xcodebuild -project RClick.xcodeproj -scheme RClick -destination 'platform=macOS'
xcodebuild test -project RClick.xcodeproj -scheme RClick -destination 'platform=macOS'

All unit tests in CustomMenuTests and ActionServiceTests pass.

Checklist

  • My code follows the project's Swift 6.2 conventions (see CONTRIBUTING.md)
  • All UI is SwiftUI (no AppKit UI components)
  • I have tested on macOS 15.6+
  • I have tested with both light and dark mode
  • I have updated documentation if needed
  • My branch is up-to-date with dev

- Introduce Shared/CustomMenu.swift with declarative tree node schema (item, submenu, separator)
- Enable mixed top-level items and nested submenus with recursive NSMenu builder in FinderSyncExt
- Support human-friendly references (app paths, extensions, action IDs)
- Graceful fallback to default categorized menu if custom_menu.json is absent or invalid
- Fix template ID and custom path loss across save/reload in ConfigService
- Add robust fallback for opening accessibility system settings on macOS 15+
- Add comprehensive test suite in CustomMenuTests (three-level nesting, leaf dispatch, invalid layouts)
…and AI tip

- Add 'Advanced Menu Layout' section in GeneralSettingsTabView with 'Open Config' and 'Reveal in Finder' buttons
- Automatically generate initial custom_menu.json based on active apps/actions if missing, without overwriting existing files
- Add friendly footer tip guiding users to leverage AI assistants (ChatGPT/Claude) for easy menu customization
- Complete multilingual localizations in English, Chinese, French, Spanish, and Japanese
- Add unit tests in CustomMenuTests covering safe initialization and non-overwrite semantics
@wflixu
wflixu merged commit aafec3b into wflixu:dev Sep 13, 2026
1 check passed
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