Hold Cmd to number the notifications popover's rows, and open one with Cmd+digit

Merged
EJ
2d ago
+985-395

Summary

Holding ⌘ in the sidebar numbers the workspaces, and ⌘1 through ⌘9 jump to them. The notifications popover had no equivalent: reaching the fourth notification meant the mouse, and pressing ⌘4 with the popover open switched the workspace behind it instead.

While the popover is open, the workspace digit shortcuts now open its rows, numbered the same way the sidebar numbers workspaces: 1 through 8 in order and 9 for the last row. Holding the modifier shows the number on each row, in the hint pill the sidebar uses and under the same Settings toggle. The pill sits in the row's header right after the time, and the hover-only clear button hides while it shows. A digit with no row behind it is swallowed, so it can't switch workspaces behind the popover. Opening a row works like clicking it: the notification opens and the popover closes.

The popover never takes key, so the keystroke reaches the app's shortcut router as a workspace shortcut. The router checks whether the popover is showing before it selects a workspace. The numbering is a small value type in CmuxNotifications, used by both the router and the rows, so the number on a row is the number that opens it.

The first commit moves NotificationsPopoverView out of UpdateTitlebarAccessory.swift into its own file without changing it; the only edit is dropping private, since the titlebar controller in the old file builds the view. UpdateTitlebarAccessory.swift is over the file-length budget, so the change could not go in where the view was.

Testing

  • NotificationListShortcutDigitTests (CmuxNotifications): digits 1 through 8 select rows in order and 9 selects the last, a digit past the list selects nothing, every row shows the digit that selects it, and rows between the eighth and the last show none. It was committed before the type and fails to compile there; it passes after. swift test --package-path Packages/macOS/CmuxNotifications passes, 143 tests in 13 suites.
  • A tagged Debug build of the app compiles.
  • The app's shortcut routing and notification suites pass locally: 287 XCTest tests (1 skipped) in AppDelegateShortcutRoutingTests, KeyboardShortcutContextTests and the rest, plus 36 swift-testing tests in AppDelegateOptionDigitShortcutRoutingTests, NumberedShortcutSwapTests, NotificationRowSnapshotBoundaryTests and NotificationRequestedEffectsTests.
  • The hint pill doesn't take clicks (.allowsHitTesting(false)), so clicking the number opens the row, the same as clicking anywhere else on it. There's no automated test for that one line: synthetic clicks in the test host never fire the row's button, so a test can't tell the fix from the bug.
  • Not checked by hand in a running app yet.
  • NotificationPopoverRowLayoutTests lays a row out at 320 pt and checks that the hint never meets the timestamp, for ⌘3, ⇧⌘3 and ⌃⌥⇧⌘9. Red at a1bec8f20f8, where the hint sat in the row's trailing overlay and even ⌘3 covered the time; green at 8ad37d97859.
  • The clear button no longer fades with the hint, so it takes clicks exactly while it is visible. There's no automated test for that.

Screenshots

Rows rendered offscreen at 320 pt with ⌘ held, before (hint under the time) and after (hint in the header).

BeforeAfter
Light
Dark

Changelog

Added: While the notifications popover is open, ⌘1–⌘9 open its notifications, and holding ⌘ numbers them


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

While the notifications popover is open, the workspace digit shortcuts open its rows instead: 1 through 8 in order and 9 for the last, numbered the way the sidebar numbers workspaces. Holding Cmd shows each row's digit in a non-interactive hint pill in the row's header, under the same Settings toggle as the sidebar; the hover-only clear button hides while the pill shows, and a digit with no matching row is swallowed so it can't switch workspaces behind the popover.

  • A digit opens the exact row that shows it, resolved against the ids the popover last drew, so a notification arriving mid-press can't shift the selection; VoiceOver reads each row's shortcut as its accessibility value.
  • Digits answer only for the window the popover hangs from (or its own window), resolved the same way as the workspace digit route, so a press in another window still switches that window's workspaces and a press with no window is swallowed.
  • Each popover opening gets its own drawn-rows record so teardown can't clear the current one, the hint setting reads the user's value instead of the default, and holding Cmd doesn't change a row's height.
  • The numbering lives in a new NotificationListShortcutDigit type in CmuxNotifications, shared by the shortcut router and the rows.
  • Moves NotificationsPopoverView out of UpdateTitlebarAccessory.swift into its own file, and adds layout tests proving a row's hint never covers its timestamp or changes the row's height.

Summary by CodeRabbit

  • New Features
    • Added numbered shortcuts for opening notification rows: digits 1–8 select their matching rows, and 9 selects the last row.
    • The notifications popover can be resized, with its size saved between uses. It includes shortcut hints, phone-forwarding access, and distinct empty states.
    • Notification rows support opening, clearing, and changing read status. Marking a pane-scoped notification as read also clears its focused-read indicator.
  • Improvements
    • Numbered workspace shortcuts continue to select workspaces when no notification row matches.
    • Shortcut hints are available to assistive technologies.