Skip to content

Move sidebar kind selection to titlebar menu - #5044

Merged
azooz2003-bit merged 1 commit into
mainfrom
feat-sidebar-kind-menu
May 31, 2026
Merged

azooz2003-bit merged 1 commit into
mainfrom
feat-sidebar-kind-menu

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented May 31, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Add a right-click menu to the titlebar sidebar toggle for choosing the default workspace sidebar or extension-based sidebars.
  • Keep left-click on the titlebar sidebar toggle as the normal show/hide sidebar action.
  • Change the bottom sidebar puzzle button to open the Sidebar Extensions browser pane directly.

Verification

  • ./scripts/reload.sh --tag sbkind --swift-frontend-workaround --launch

Dogfood Checks

  • Left-click the sidebar button next to the traffic lights. It should still toggle the sidebar open and closed.
  • Right-click the same sidebar button. It should show only the sidebar type choices: default workspace sidebar and extension-based sidebars.
  • Click the puzzle button near the bottom Help button. It should open the Sidebar Extensions browser pane directly, not the sidebar type chooser.

Summary by CodeRabbit

  • UI Improvements
    • Sidebar extension picker now displays visual icons for better identification.
    • Added right-click context menu support to the sidebar toggle button for quick access to extensions.
    • Enhanced sidebar footer interaction for accessing the extensions browser.

@vercel

vercel Bot commented May 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment May 31, 2026 6:09am
cmux-staging Ready Ready Preview, Comment May 31, 2026 6:09am

@coderabbitai

coderabbitai Bot commented May 31, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The sidebar extension menu now displays SF Symbol images. The sidebar footer button is refactored to open a browser action instead of displaying a menu. Right-click menu presentation is integrated into the titlebar toggle button and minimal-mode sidebar controls, with context menu support enabled for the toggle-sidebar action slot.

Changes

Sidebar Menu and Right-Click Controls

Layer / File(s) Summary
Extension Menu Visual Enhancement
Sources/ContentView.swift
Menu items display SF Symbol images from descriptor.systemImageName. The unused @objc func manageExtensions(_:) handler is removed from CmuxExtensionSidebarMenuTarget.
Sidebar Footer Browser Action
Sources/ContentView.swift
Footer button now calls AppDelegate.shared?.openSidebarExtensionBrowser(from:title:) with an extensionBrowserAnchorView anchor instead of showing a menu. Accessibility/help text and anchor wiring are updated.
Right-Click Menu Presentation Wiring
Sources/Update/MinimalModeSidebarControls.swift, Sources/Update/UpdateTitlebarAccessory.swift, Sources/WindowDragHandleView.swift
Toggle-sidebar right-click invokes CmuxExtensionSidebarSelection.showMenu(anchorView:event:) in titlebar and minimal-mode controls. Context menu support is enabled for .toggleSidebar in the control action slot.

Possibly Related PRs

  • manaflow-ai/cmux#5038: Introduces the openSidebarExtensionBrowser pane-tab routing that this PR now calls from the sidebar footer button.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 With symbols bright and menus keen,
The sidebar's now a sight to see!
Right-click to browse, the footer sings,
Extension management takes wings! 🪶


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (2 errors, 1 warning)

Check name Status Explanation Resolution
Cmux Full Internationalization ❌ Error New strings command.switchExtensionSidebar.title and .subtitle in Localizable.xcstrings have only 2 locales (en, ja) instead of the required 19-20. Add complete translations for all 19-20 supported locales to command.switchExtensionSidebar.title and .subtitle in Resources/Localizable.xcstrings.
Cmux Architecture Rethink ❌ Error Removed guard check for anchor view state. New code passes potentially-nil extensionBrowserAnchorView to AppDelegate, relying on layout-callback-driven @State instead of explicit guard checks. Restore guard check before using extensionBrowserAnchorView: guard let extensionBrowserAnchorView else { return }, or ensure AppDelegate method safely handles nil values.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (15 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed showMenu() is @MainActor, NSView types are implicitly MainActor, and WindowMoveSuppressionSequenceState is properly documented @unchecked Sendable. No new actor isolation violations.
Cmux Swift Blocking Runtime ✅ Passed PR introduces no blocking or timing-based synchronization (semaphores, sleep, locks, etc.). Changes are UI event handlers, menu display, and state management only.
Cmux No Hacky Sleeps ✅ Passed All setTimeout usage employs proper cancellation-aware patterns (AbortController/AbortSignal) with bounded deadlines and tests, conforming to allowed timeout logic.
Cmux Algorithmic Complexity ✅ Passed PR's showMenu() call in rightMouseDown loops over a tiny fixed-size descriptors collection (max 2 items), qualifying as acceptable tiny fixed-size collection per the rules.
Cmux Swift Concurrency ✅ Passed PR introduces only synchronous AppKit/SwiftUI boundary code: NSMenu.popUp calls, right-click closures, and UI state management. No new async patterns, Dispatch queues, Combine, or Tasks introduced.
Cmux Swift @Concurrent ✅ Passed PR adds synchronous @MainActor showMenu() function and rightMouseDown handlers for sidebar selection; no async functions, @concurrent misuse, or nonisolated async violations detected.
Cmux Swift File And Package Boundaries ✅ Passed Changes add <250 lines to oversized files (net -14/+2/+2/0 lines). ContentView shrinks. Small UI/AppKit glue appropriate for app-target files per allowed cases.
Cmux Swift Logging ✅ Passed PR adds only one NSLog call in Sources/ContentView.swift, properly guarded with #if DEBUG, which is an allowed debug-only log per swift-logging.md rules. No other logging violations found.
Cmux User-Facing Error Privacy ✅ Passed PR adds only safe, generic sidebar UI labels ("Sidebar Extensions", "Toggle Sidebar") with no vendor names, credentials, flags, or sensitive data.
Cmux Swiftui State Layout ✅ Passed New @State extensionBrowserAnchorView is AppKit bridge view (allowed exception). LazyVStack correctly snapshots before rows. No render-time mutations detected.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR adds NSMenu context menu behavior to existing UI elements, which is explicitly allowed per the rule file as menus are not standalone key windows.
Title check ✅ Passed The title accurately and concisely describes the main change: moving sidebar kind selection from the sidebar footer to the titlebar menu via right-click.
Description check ✅ Passed The description includes a clear summary of changes and detailed verification steps, though it deviates from the template by using 'Verification' and 'Dogfood Checks' instead of 'Testing' and omits the demo video, checklist, and review trigger.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-sidebar-kind-menu

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.

@azooz2003-bit
azooz2003-bit marked this pull request as ready for review May 31, 2026 17:21
@greptile-apps

greptile-apps Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR moves sidebar kind selection (default workspace vs. extension-based sidebar) from the bottom puzzle button to a right-click menu on the titlebar sidebar toggle, and rewires the puzzle button to open the Sidebar Extensions browser pane directly.

  • Titlebar sidebar toggle now responds to right-click in both the full-chrome (TitlebarControlButton) and minimal-mode (MinimalModeSidebarControlActionView) paths, showing only the sidebar kind choices; WindowDragHandleView.acceptsContextMenu is updated in sync.
  • Puzzle button action is changed from CmuxExtensionSidebarSelection.showMenu to AppDelegate.openSidebarExtensionBrowser, with the tooltip and accessibility label updated to match; the extensionMenuAnchorView state is renamed to extensionBrowserAnchorView for clarity.
  • Sidebar kind menu drops the "Manage Sidebar Extensions…" item (now reached via the puzzle button) and gains a system-symbol icon on each kind entry.

Confidence Score: 4/5

Safe to merge; the refactoring is internally consistent across all three sidebar-control surfaces and introduces no new state or concurrency concerns.

The titlebar-toggle right-click wiring is added in both the full-chrome and minimal-mode paths and acceptsContextMenu is kept in sync. The puzzle-button pivot to the Extension Browser is clean. The two flagged items are both non-blocking: the accessibilityDescription nil on new menu icons is a cosmetic accessibility gap, and the Manage Extensions reachability gap in minimal mode is a design trade-off worth confirming intentional.

Sources/Update/MinimalModeSidebarControls.swift — confirm that the Extensions browser is reachable from minimal mode without first opening the sidebar panel.

Important Files Changed

Filename Overview
Sources/ContentView.swift Removes "Manage Sidebar Extensions…" from the right-click menu, adds system-symbol icons to sidebar-kind items, and rewires the puzzle button to open the Extension Browser directly instead of the selector menu. The anchor view rename and @discardableResult silent-discard pattern are correct.
Sources/Update/UpdateTitlebarAccessory.swift Attaches rightClickAction to the titlebar sidebar-toggle button, delegating to CmuxExtensionSidebarSelection.showMenu. The closure is invoked from TitlebarControlRightClickNSView on the main thread; the @mainactor requirement of showMenu is satisfied.
Sources/Update/MinimalModeSidebarControls.swift Adds right-click handling for the .toggleSidebar slot, consistent with the parallel change in UpdateTitlebarAccessory.swift. acceptsContextMenu in WindowDragHandleView.swift is updated in sync.
Sources/WindowDragHandleView.swift Updates acceptsContextMenu to return true for .toggleSidebar, enabling the context-menu hit-test path for the sidebar button in minimal mode. Change is consistent with the new right-click handler.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User: left-click titlebar sidebar button] --> B[Toggle sidebar open/closed]
    C[User: right-click titlebar sidebar button] --> D[CmuxExtensionSidebarSelection.showMenu]
    D --> E[Kind selector menu\nDefault Workspace / Extension-based]
    E --> F[CmuxExtensionSidebarMenuTarget.selectProvider]

    G[User: click puzzle button\nin sidebar footer] --> H[AppDelegate.openSidebarExtensionBrowser]
    H --> I[Sidebar Extensions browser pane]

    subgraph MinimalMode [Minimal Mode]
        C2[right-click toggleSidebar slot] --> D
    end

    subgraph FullChrome [Full Chrome]
        C3[right-click via TitlebarControlRightClickView] --> D
    end
Loading

Reviews (1): Last reviewed commit: "Move sidebar kind selection to titlebar ..." | Re-trigger Greptile

Comment thread Sources/ContentView.swift
item.representedObject = descriptor.id
item.target = CmuxExtensionSidebarMenuTarget.shared
item.state = selectedProviderId == descriptor.id ? .on : .off
item.image = NSImage(systemSymbolName: descriptor.systemImageName, accessibilityDescription: nil)

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.

P2 Each new system-symbol NSImage is created with accessibilityDescription: nil, which suppresses VoiceOver from reading out the icon for assistive-technology users navigating the menu. Since the menu item already carries a localised title, screen readers will still announce the text, but providing a matching description (or reusing the item title) is the correct pattern for NSMenuItem icons.

Suggested change
item.image = NSImage(systemSymbolName: descriptor.systemImageName, accessibilityDescription: nil)
item.image = NSImage(systemSymbolName: descriptor.systemImageName, accessibilityDescription: localizedTitle(for: descriptor))

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +197 to +198
case .toggleSidebar:
CmuxExtensionSidebarSelection.showMenu(anchorView: self, event: event)

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.

P2 "Manage Sidebar Extensions" inaccessible in minimal mode

After this PR the sidebar kind menu no longer contains a "Manage Extensions" entry, and the replacement path is the puzzle button in SidebarFooterButtons. That button lives inside the main sidebar panel, which is hidden in minimal mode. In minimal mode the right-click on the sidebar toggle only shows the kind selector, leaving no discoverable way to reach the Extensions browser without first switching out of minimal mode.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/ContentView.swift (1)

12998-13014: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add missing i18n entries for sidebar.extensions.browser.title
Sources/Resources/Localizable.xcstrings contains sidebar.extensions.browser.title with translations for ar, bs, da, de, en, es, fr, it, ja, km, ko, nb, pl, pt-BR, ru, th, tr, uk, zh-Hans, zh-Hant. Add the same key to Prototypes/SettingsShellLab/Resources/Localizable.xcstrings and Resources/InfoPlist.xcstrings (currently key MISSING) for every supported locale.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Sources/ContentView.swift` around lines 12998 - 13014, The localized key
sidebar.extensions.browser.title used in ContentView must be added to the other
resource string tables: add the same key and translations that exist in the main
Localizable.xcstrings to both the SettingsShellLab Localizable.xcstrings and the
InfoPlist.xcstrings files, replacing any "key MISSING" placeholders; ensure the
key name exactly matches sidebar.extensions.browser.title and include entries
for every supported locale present in the main file so runtime lookups and
accessibility/safeHelp strings resolve correctly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@Sources/ContentView.swift`:
- Around line 12998-13014: The localized key sidebar.extensions.browser.title
used in ContentView must be added to the other resource string tables: add the
same key and translations that exist in the main Localizable.xcstrings to both
the SettingsShellLab Localizable.xcstrings and the InfoPlist.xcstrings files,
replacing any "key MISSING" placeholders; ensure the key name exactly matches
sidebar.extensions.browser.title and include entries for every supported locale
present in the main file so runtime lookups and accessibility/safeHelp strings
resolve correctly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 56000b93-a70b-4ab0-8a38-63920a944f99

📥 Commits

Reviewing files that changed from the base of the PR and between 40bfb20 and 725efc2.

📒 Files selected for processing (4)
  • Sources/ContentView.swift
  • Sources/Update/MinimalModeSidebarControls.swift
  • Sources/Update/UpdateTitlebarAccessory.swift
  • Sources/WindowDragHandleView.swift

This branch was successfully deployed

1 active deployment
Preview – cmux — 725efc29 Deployed May 31, 2026 by vercel[bot]
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.

1 participant