Skip to content

Gate switcher shortcut event peek behind session HID counters#1397

Merged
steipete merged 2 commits into
steipete:mainfrom
bcssewl:perf/gate-switcher-shortcut-event-peek
Jun 10, 2026
Merged

Gate switcher shortcut event peek behind session HID counters#1397
steipete merged 2 commits into
steipete:mainfrom
bcssewl:perf/gate-switcher-shortcut-event-peek

Conversation

@bcssewl

@bcssewl bcssewl commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Refs #1321, #1325, #1308 (merged-menu interaction lag family).

Summary

ProviderSwitcherShortcutEventMonitor's CFRunLoopObserver fires on .beforeSources of every pass of the menu-tracking run loop, and every firing called NSApp.nextEvent(matching:until:inMode:dequeue:false) to peek the queue for switcher shortcuts and clicks. Menu tracking spins once per mouse move, so hover-heavy interaction paid that AppKit peek continuously.

This PR adds a tiny gate in front of the peek: read the session-wide HID event counters (CGEventSource.counterForEventType(.combinedSessionState, ...)) for the monitored kinds (keyDown, leftMouseDown, leftMouseUp) and skip the peek when none advanced since the previous pass. Mouse moves never advance those counters, so the common hover pass reduces to three cheap counter reads; actual key presses and clicks open the gate on the same pass they occur, so shortcut behavior is unchanged with zero added latency.

Evidence

A 60-second sample of a packaged build during ordinary merged-menu interaction (Apple Silicon, real multi-provider config) attributes 1,348 main-thread samples to this peek path — CFRunLoopObserver thunk → ProviderSwitcherShortcutEventMonitor closure → NSApp.nextEvent (StatusItemController+ProviderSwitcher.swift:24-25) — nearly as much as the entire open-menu rebuild subtree in the same trace (1,565). It's pure overhead on passes with no pending key/click, which is almost all of them while the cursor is moving.

Validation

  • 3 focused tests for the gate (first check peeks; unchanged counters skip; any advanced counter re-enables) via an injected counter provider
  • swift test full suite: green except the known rotating locale/load flakes (MiniMaxMenuCardModelTests, HistoricalUsagePaceOwnershipTests, OpenAIDashboardWebViewCacheTests) which reproduce identically on clean main and pass in isolation
  • make check: 0 violations
  • Commands run: swift build, swift test, make check

Independent of #1394 (no shared files); the two compose.

steipete and others added 2 commits June 10, 2026 23:50
@steipete steipete force-pushed the perf/gate-switcher-shortcut-event-peek branch from d053d90 to 96d5848 Compare June 10, 2026 22:59
@steipete steipete merged commit eda747b into steipete:main Jun 10, 2026
4 checks passed
@steipete

Copy link
Copy Markdown
Owner

Landed in eda747ba6d4293a831398b8dadd2e2189793a7f6.

Verification:

  • swift test --filter ProviderSwitcherEventPeekGateTests — 7 tests passed
  • make check — formatting current; SwiftLint found 0 violations across 1,038 files
  • swift test — 3,527 tests in 402 suites passed
  • Final autoreview: /Users/steipete/Projects/agent-skills/skills/autoreview/scripts/autoreview --mode branch --base origin/main --stream-engine-output — clean; no accepted/actionable findings
  • Packaged-app Peekaboo QA: Right switched Claude → Overview, Right switched Overview → Codex, Left returned to Overview while the menu remained open
  • Stress QA: 8 open/right/left/close cycles; all events delivered; opens completed in 0.17–0.23s
  • Exact-head CI on 96d584863c78ad670bc9efe8637a5088d9c79eca: GitGuardian, macOS lint/build/full tests, Linux x64 CLI, and Linux arm64 CLI all passed

Caveat: the installed gh has no image uploader, so screenshots could not be attached; local proofs: /tmp/pr1397-right1.png, /tmp/pr1397-right2.png, /tmp/pr1397-left1.png.

Thanks @bcssewl!

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