Skip to content

Add collapsible session list sidebar#764

Open
ggfevans wants to merge 6 commits into
insidegui:masterfrom
ggfevans:collapsible-sidebar
Open

Add collapsible session list sidebar#764
ggfevans wants to merge 6 commits into
insidegui:masterfrom
ggfevans:collapsible-sidebar

Conversation

@ggfevans

Copy link
Copy Markdown

Summary

Makes the session list sidebar collapsible in the Videos and Schedule tabs.
Previously the list was always visible, which in windowed mode kept the
video player narrower than the window allowed. You can now hide the list to
give the video the full width of the window, and show it again when you need
to pick another session.

The sidebar can be toggled three ways, all routed through AppKit's standard
toggleSidebar action: a button at the leading edge of the title bar, a Hide
Sidebar item in the View menu, and the Control-Command-S shortcut. The
collapsed state stays consistent between the Videos and Schedule tabs during
a session and is not persisted, so the app always starts with the sidebar
visible. Dragging the divider past its minimum width also collapses it.

Closes #763.

Testing

Built with the WWDC scheme. Verified toggling from the title bar button, the
View menu, and the keyboard shortcut on both the Videos and Schedule tabs,
drag to collapse, cross tab consistency, the button disabling on the Explore
tab which has no sidebar, and the sidebar reopening expanded after relaunch.

AI assistance

Parts of this change were written with AI assistance. All code was reviewed
and tested before submission, in line with the contribution guidelines.

ggfevans and others added 6 commits June 9, 2026 02:24
Make the left session-list panel collapsible on the Schedule and Videos
tabs with a native toggle: a leading titlebar button, a View-menu "Hide
Sidebar" item, and the standard ⌃⌘S shortcut, all routed through AppKit's
toggleSidebar: responder action.

- SessionsSplitViewController: enable canCollapse; sync collapse state
  across both tabs (mirroring the existing width-sync) and guard the
  width-persistence path against the collapsed ~0pt width.
- TitleBarViewController: add the leading sidebar-toggle button.
- AppCoordinator: disable the button on the Explore tab (no sidebar).
- MainWindowController: session-only shared collapsed-state flag so a
  lazily-loaded tab adopts the current state.

Collapsed state is session-only (reopens expanded on next launch).
Also gitignore CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ate into struct

Part A: Guard the receiver path of syncSplitView(notification:) so a trailing
width-sync notification (throttled 250 ms) cannot call setPosition and re-expand
THIS tab's sidebar after it was already collapsed.

Part B: Merge the two loose shared-state fields (sidebarInitWidth, sidebarCollapsed)
on MainWindowController into a single nested SidebarState struct. Updates all call
sites in SessionsSplitViewController accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Position sidebarToggleButton dynamically by measuring the zoom button's
  frame in viewWillLayout(), replacing the static trafficLightInset fallback
  with a live maxX + trafficLightGap constant once the window is available.

Refinements (R2):
- Efficiency: guard constraint assignment behind an abs() > 0.5 epsilon check
  so repeated identical layout passes don't dirty the layout engine during
  live window resize.
- Robustness: extract symbol creation into a private static makeToggleSymbol()
  helper that assertionFailure()s in debug builds if the system symbol is
  missing, rather than silently falling back to a blank NSImage().

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The isEnabled state of the titlebar sidebar-toggle button was previously
computed inside the CombineLatest3 sink whose primary purpose is session-
selection routing. This caused the button state to be recomputed on every
session selection change, not just on tab switches. Extract it into its own
tabController.$activeTabVar subscription so it fires only when the active
tab changes, at the correct altitude.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- makeToggleSymbol() no longer returns a blank NSImage on failure: it logs the
  missing system symbol via OSLog and returns a visible text-glyph fallback so
  the toggle button always renders. assertionFailure retained for development.
- Rename .sidebarCollapseSyncNotification -> .sideBarCollapseSyncNotification to
  match the existing .sideBarSizeSyncNotification camelCase. Identifier-only
  rename; the underlying notification string value is unchanged (no behaviour
  change).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
targetSubviewIndex varies by Xcode/macOS (0, 2, or 3). Both the sender and
receiver branches indexed subviews[targetSubviewIndex] guarded only by
count > 0, which is insufficient for index 2/3 and could trap out-of-range on
layouts with fewer subviews. Replace with an indices.contains bounds check and
guard the sender-branch read as well.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

Collapsible sidebar to give the video more space in windowed mode

1 participant