Skip to content

Add focus and Recently Closed history - #4160

Merged
lawrencecchen merged 125 commits into
mainfrom
feature-workspace-window-history
May 26, 2026
Merged

lawrencecchen merged 125 commits into
mainfrom
feature-workspace-window-history

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented May 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • add focus history navigation with sidebar/header controls, History menu entries, editable Cmd+[ and Cmd+] shortcuts, and command-hold shortcut hints
  • launch the closed-history feature as Recently Closed: one closed-item history for tabs, workspaces, and windows
  • keep Cmd+Shift+T as Reopen Last Closed, restoring one closed action at a time
  • make History > Recently Focused and History > Recently Closed show the first 10 rows inline with subtitles
  • keep Show Full entries and Open Full History for the full searchable History pane
  • make Full History a Bonsplit pane with search, day grouping, close/focus timestamps, hover states, and Clear Closed
  • preserve stable row IDs so restoring an older row restores only that row, and failed restores keep the row queued
  • keep internal cleanup closes out of Recently Closed
  • use shared header chrome metrics, compact 10x10 right-sidebar header icons, a 5px higher titlebar shortcut hint placement, and matching header color/regular weight for right-sidebar pill buttons

This PR targets main directly and supersedes #4098.

Verification

  • xcodebuild -project cmux.xcodeproj -scheme cmux-unit -configuration Debug -destination 'platform=macOS,arch=arm64' -derivedDataPath /tmp/cmux-header-chrome-match-tests -resultBundlePath /tmp/cmux-header-chrome-match-tests.xcresult -only-testing:cmuxTests/AppDelegateShortcutRoutingTests/testRightSidebarHeaderChromeUsesSharedButtonsWithCompactIcons -only-testing:cmuxTests/AppDelegateShortcutRoutingTests/testRightSidebarPillChromeUsesHeaderIconColorAndWeight test
  • git diff --check
  • ./scripts/reload.sh --tag histplus
  • runtime geometry capture confirmed right sidebar open/close icons stayed 10x10 in 20x20 buttons and mode buttons stayed 20px high
  • previous focused suite: 73 tests passed in /tmp/cmux-histstack
  • previous broader targeted suite: 56 tests passed in /tmp/cmux-histpane-final6

Demo

  • cloud Mac run: https://github.com/manaflow-ai/cmux-loader/actions/runs/26012511895
  • searchable, day-grouped History pane screenshot: /tmp/cloud-histpane-after-reopen-history/screenshot.png
  • filtered History pane video: /tmp/cloud-mac-histpane-history-alpha-filter-menu-demo/recording.mov
  • History menu video: /tmp/cloud-mac-histpane-history-menu-open-demo/recording.mov
  • Cmd+Shift+T restore video: /tmp/cloud-mac-histpane-history-search-demo/recording.mov

Summary by CodeRabbit

  • New Features

    • Searchable, day‑grouped History pane and Right Sidebar “History” with Recently Closed/Recently Focused, reopen/restore, Clear Closed, and “Open History as Pane”.
    • New shortcuts: Focus Back / Focus Forward and a shortcut to switch the right sidebar to History.
  • Improvements

    • Persistent sidebar width, refined titlebar/right‑sidebar chrome and controls, unified attention/flash visuals, and a Titlebar Layout Debug UI.
  • Tests

    • Expanded unit, integration, and UI tests covering history, shortcuts, titlebar, sidebar, and restore flows.
  • Localization

    • Menu wording updated to “History > Restore Previous App Launch” and Japanese terminology adjusted to “History.”

Review Change Stack


Note

Medium Risk
Touches window close/restore, session snapshots, and focus routing across TabManager and AppDelegate; regressions could affect layout restore or accidental history entries, but changes are largely user-facing navigation with explicit suppression for internal closes.

Overview
Adds focus history (back/forward via shortcuts, titlebar controls, and History menus) and a unified Recently Closed stack for closed tabs, workspaces, and windows, with Cmd+Shift+T reopening the latest closed item and per-row restore from the full History right-sidebar pane (search, day groups, clear closed).

Window and workspace teardown now records closed-window snapshots unless history is suppressed (session restore, moves, failed restores re-queue entries). Restore Previous App Launch replaces “Reopen Previous Session” in menus and the palette. Right sidebar gains a History mode; chrome tweaks include configurable sidebar minimum width, titlebar layout debug strings, richer config context-menu icons, and shared right-sidebar control metrics.

CI tests job timeout increases from 45 to 75 minutes.

Reviewed by Cursor Bugbot for commit e6dce82. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented May 14, 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 26, 2026 4:37am
cmux-staging Building Building Preview, Comment May 26, 2026 4:37am

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented May 14, 2026 •

Copy link
Copy Markdown

Caution

Review failed

Failed to post review comments

📝 Walkthrough

Walkthrough

Adds a focus and recently-closed history subsystem, History pane/menu UI, TabManager/AppDelegate recording and restore wiring, titlebar/shortcut/hint refactors and debug tooling, sidebar minimum-width persistence, icon/context-menu image normalization, extensive tests, and localization updates.

Changes

History & Titlebar Integration

Layer / File(s) Summary
History model and store
Sources/ClosedItemHistory.swift
Adds closed-item types, menu formatting, and ClosedItemHistoryStore with push/restore/remap/remove APIs.
TabManager & Workspace history
Sources/TabManager.swift, Sources/Workspace.swift
Implements focus-history ring, closed-panel/workspace recording, restore remapping, session snapshot id helpers, and close flows honoring recordHistory flags.
AppDelegate closed-window & restore wiring
Sources/AppDelegate.swift, Sources/AppDelegate+ClosedItemHistory.swift, Sources/AppDelegate+HistoryPane.swift, Sources/AppDelegate+FocusHistoryContextMenu.swift
Adds closed-window suppression, recordClosedWindowHistoryIfNeeded, reopen/restore flows, history pane opener, and focus-history context menu.
Right-sidebar History UI
Sources/RightSidebarPanelView.swift, Sources/RightSidebarToolPanel.swift, Sources/HistoryPanelView.swift, Sources/FocusHistory.swift
Adds .history mode, HistoryPanelView UI, focus-host bridge, menu snapshots/formatters, and wiring to reopen/clear actions.
Titlebar controls, hints & debug
Sources/Update/UpdateTitlebarAccessory.swift, Sources/Update/TitlebarChromeGeometryReporting.swift, Sources/TitlebarLayoutDebugWindow.swift
Refactors titlebar accessory sizing, shortcut-hint planner, geometry recording, and adds Titlebar Layout Debug window.
Sidebar width & session persistence
Sources/SessionPersistence.swift, Sources/ContentView.swift
Adds persisted sidebarMinimumWidth, sanitization, dynamic clamping, and ContentView/AppStorage plumbing.
Shortcuts and routing
Sources/KeyboardShortcutSettings.swift, Sources/KeyboardShortcutSettingsLookup.swift, Sources/KeyboardShortcutContext.swift, Sources/ContentView+RightSidebarCommandPalette.swift
Adds focus-history and switch-to-history actions, default shortcuts, lookup remapping to avoid conflicts, and command-palette routing.
Icon rendering & UI tweaks
Sources/CmuxConfigUI.swift, Sources/CmuxConfig.swift, Sources/RightSidebarChromeStyle.swift, Sources/WorkspaceAttentionFlashRingView.swift
Adds Bonsplit import, context-menu icon normalization/emoji rendering, RightSidebar chrome styles, and unified flash-ring view.
Tests, localizations & project
cmuxTests/*, cmuxUITests/*, Resources/Localizable.xcstrings, web/*, cmux.xcodeproj, .github/workflows/ci.yml
Extensive unit/UI tests added/updated, many localization keys/values added/changed, web schema & shortcuts updated, Xcode project entries added, CI timeout increased.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant HistoryPanel
  participant AppDelegate
  participant ClosedItemHistoryStore
  participant TabManager
  User->>HistoryPanel: open/clear/reopen action
  HistoryPanel->>AppDelegate: request reopen / open pane
  AppDelegate->>ClosedItemHistoryStore: restoreFirstRestorable(...)
  ClosedItemHistoryStore-->>AppDelegate: restored entry / failure
  AppDelegate->>TabManager: restore panel/workspace/window / remap ids
  TabManager-->>AppDelegate: remapped ids / success
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

"A rabbit wrote this patch with a hop and a cheer,
History and layouts now clearer this year.
Panels and panes, shortcuts set free,
Tiny debug sliders, tart and sweet tea.
🐇✨"

✨ 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 feature-workspace-window-history

Comment thread Sources/cmuxApp.swift Outdated
Comment thread Sources/TabManager.swift
@greptile-apps

greptile-apps Bot commented May 14, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a full History experience to cmux: a right-sidebar history mode with a searchable, day-grouped HistoryPanelView, a new History menu with Recently Closed and Recently Focused sections, focus-history back/forward navigation (Cmd+[/]), and Reopen Last Closed (⌘⇧T) that now spans tabs, workspaces, and windows instead of browser panels only.

  • ClosedItemHistoryStore (new ClosedItemHistory.swift) tracks up to 50 closed items with stable record IDs; the .window restore branch now validates content via ClosedWindowRestoreValidation.hasUsableRestoredContent before reporting success, and restoreClosedWorkspace rejects empty-panel results and re-queues on failure.
  • Focus history (FocusHistory.swift, new TabManager methods) records back/forward navigation with a suppression-depth counter to prevent internal closes from polluting history; FocusHistoryMenuInvalidator drives menu invalidation via notification.
  • cmuxApp+HistoryMenu.swift (new) adds the History CommandMenu while the previously-duplicated File menu entries (Reopen Previous Session, Reopen Closed Browser Panel) are removed, resolving the previously-flagged shortcut collision.

Confidence Score: 4/5

Safe to merge with awareness of the known unrestorable-panel-entry edge case in the closed history queue.

The restore logic for workspaces and windows has been substantially hardened with content-validation guards and the previously-reported duplicate-menu and hollow-window-restore issues are addressed. New findings in this review are style-level (file boundary). The focus and closed history flows are complex and touch window/workspace lifecycle, which warrants a careful look at the remaining edge case where closing the last panel in a workspace leaves a panel history entry whose workspace no longer exists — every Cmd+Shift+T press against that entry will silently fail and re-queue, giving the user a beep with no path to recover or dismiss that record.

Sources/TabManager.swift and Sources/Update/UpdateTitlebarAccessory.swift are both significantly over the 800-line threshold and received the largest additions in this PR; the panel-history orphan path is inside TabManager.

Important Files Changed

Filename Overview
Sources/TabManager.swift 675 new lines add focus-history recording, suppression-depth counter, closed-panel/workspace restore, and panel-ID remapping to an already 10K-line file; restoreClosedWorkspace now guards against empty-panel cycling; file-boundary concern flagged.
Sources/Update/UpdateTitlebarAccessory.swift 794 new lines of titlebar metrics, shortcut hint slots, focus-history availability, and notification geometry helpers added to an already 2,691-line file; file-boundary concern flagged.
Sources/ClosedItemHistory.swift New 439-line store and entry-type model for closed-item history; uses ObservableObject/@published (flagged in previous threads); core restore/sorting/remapping logic is sound.
Sources/AppDelegate+ClosedItemHistory.swift New 171-line restore orchestrator; .window branch now validates content via ClosedWindowRestoreValidation before reporting success; addresses previously-flagged hollow-restore concern.
Sources/cmuxApp+HistoryMenu.swift New 164-line History CommandMenu extension; old duplicate File menu items removed from cmuxApp.swift, eliminating the previously-flagged shortcut collision.
Sources/HistoryPanelView.swift New 385-line history pane view; uses @ObservedObject on ClosedItemHistoryStore.shared (same ObservableObject singleton pattern flagged in previous threads); groupedRows computed inline in body is cheap at 50-entry capacity.
Sources/AppDelegate.swift Adds closedWindowHistorySuppressedWindowIds Set for opt-out history recording; shouldClose callback correctly reverses suppression if window cancels close.
Sources/FocusHistory.swift New 129-line pure-value model for focus history entries, menu snapshots, and formatting; cleanly separated from UI concerns.
Sources/FocusHistoryMenuInvalidator.swift New lightweight ObservableObject that bumps a revision counter on focus-history changes and window-key notifications to drive menu invalidation.

Sequence Diagram

sequenceDiagram
    participant User
    participant AppDelegate
    participant Store as ClosedItemHistoryStore
    participant TM as TabManager

    User->>AppDelegate: Cmd+Shift+T
    AppDelegate->>Store: restoreFirstRestorable(newerThan:excluding:)
    Store-->>AppDelegate: candidate entry

    alt panel entry
        AppDelegate->>TM: restoreClosedPanel(entry)
        TM-->>AppDelegate: true or false
        alt success
            AppDelegate->>Store: remove record
        else workspace gone
            AppDelegate->>Store: onFailure — record stays queued
        end
    else workspace entry
        AppDelegate->>TM: restoreClosedWorkspace(entry)
        TM-->>AppDelegate: true or false
        alt panels restored
            AppDelegate->>Store: remove record
        else no panels after restore
            TM->>TM: closeWorkspace(recordHistory:false)
            AppDelegate->>Store: onFailure — record stays queued
        end
    else window entry
        AppDelegate->>AppDelegate: createMainWindow
        AppDelegate->>AppDelegate: ClosedWindowRestoreValidation.hasUsableRestoredContent
        alt valid content
            AppDelegate->>Store: remove record
        else hollow restore
            AppDelegate->>AppDelegate: discardMainWindowWithoutClosedHistory
            AppDelegate->>Store: onFailure — record stays queued
        end
    end
Loading

Reviews (72): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

@lawrencecchen
lawrencecchen force-pushed the feature-workspace-window-history branch from cd42e62 to 663835c Compare May 14, 2026 12:43
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/TabManager.swift
Comment thread Sources/TabManager.swift Outdated
@lawrencecchen
lawrencecchen force-pushed the feature-focus-workspace-history branch from d154d9c to 91814b0 Compare May 15, 2026 13:08
@lawrencecchen
lawrencecchen force-pushed the feature-workspace-window-history branch from b178443 to 84700e6 Compare May 15, 2026 13:08
@lawrencecchen
lawrencecchen force-pushed the feature-focus-workspace-history branch from 91814b0 to 0d91098 Compare May 15, 2026 13:10
@lawrencecchen
lawrencecchen force-pushed the feature-workspace-window-history branch from 84700e6 to 0ca81ce Compare May 15, 2026 13:10
@lawrencecchen
lawrencecchen force-pushed the feature-focus-workspace-history branch from 0d91098 to 5c47853 Compare May 15, 2026 13:15
@lawrencecchen
lawrencecchen force-pushed the feature-workspace-window-history branch from 0ca81ce to f5635b2 Compare May 15, 2026 13:15
Comment thread Sources/TabManager.swift Outdated
…dow-history

# Conflicts:
#	cmuxTests/TerminalControllerSocketSecurityTests.swift
Comment thread Sources/AppDelegate+ClosedItemHistory.swift
Comment thread Sources/AppDelegate.swift
Comment thread Sources/AppDelegate.swift
@socket-security

socket-security Bot commented May 23, 2026 •

Copy link
Copy Markdown

No dependency changes detected. Learn more about Socket for GitHub.

👍 No dependency changes detected in pull request

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ae78f6d. Configure here.

Comment thread Sources/ContentView.swift

This branch was successfully deployed

1 active deployment
Preview – cmux — e6dce82b Deployed May 26, 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