Skip to content

Fix stale native menu hover highlight geometry#2035

Merged
steipete merged 5 commits into
steipete:mainfrom
Zihao-Qi:codex/fix-native-menu-hover-highlight
Jul 10, 2026
Merged

Fix stale native menu hover highlight geometry#2035
steipete merged 5 commits into
steipete:mainfrom
Zihao-Qi:codex/fix-native-menu-hover-highlight

Conversation

@Zihao-Qi

@Zihao-Qi Zihao-Qi commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Defer geometry-changing root and hosted-submenu rebuilds while AppKit is highlighting a native row.
  • Preserve the exact provider request and sticky readiness-baseline resync across scheduler replacement, native-highlight deferral, and an open hosted child.
  • Keep that saved explicit provider authoritative when a dirty parent resumes after its hosted child closes.
  • Resume one coalesced rebuild when the pointer leaves native rows; discard it cleanly when tracking closes.
  • Add focused lifecycle, coalescing, fresh-menu, and hosted Status Page regressions.

Problem

When usage or status content refreshed while hovering native rows such as Plan Usage, Cost, or Open Status Page, AppKit could keep drawing the selection background using the old row geometry while the menu was rebuilt underneath it. This occasionally left the blue hover highlight over a different part of the menu.

Fix

Track the complete deferred rebuild request per open menu. Rebuild requests keep fetching and updating provider state, but any geometry-changing root or hosted-submenu mutation waits while a native item is highlighted. Coalesced requests retain readiness-baseline resync intent, and lifecycle cleanup removes deferred work when the menu closes.

Impact

Only visible menu layout mutation is briefly deferred while the pointer remains over a native row. Provider fetching, status items, widgets, and background updates continue normally.

Verification

Exact candidate: 94ccb89a96f426444e76d79d790c674ea1a9df7b

  • Focused menu/lifecycle coverage: 187/187 tests across 3 suites passed, including both hosted-child close orders and the dirty-parent provider-precedence race.
  • make check: passed.
  • make test: 598/598 selections, 50/50 groups, zero failures, retries, or timeouts.
  • Full-branch review plus final two-file autoreview: clean.
  • Current main integration: clean merge tree after Default Agent Sessions to off #2039.
  • Hosted CI/security: exact-head run 29115867481 passed changes, lint, Linux arm64/x64, both macOS shards, aggregate, and GitGuardian checks.

Package verification used a Developer ID-signed normal exact-commit bundle. The controlled UI mutation used a separate strict-valid exact debug bundle with debug-only get-task-allow. Runtime used isolated home/config state, denied network and provider subprocess execution, and enabled both Keychain gates. A file-gated in-memory fixture recorded the real AppKit highlight state before mutation:

  • Root: Plan Usage was a native highlighted row; root rebuild count stayed flat while highlighted, then increased exactly once after the pointer left. The menu stayed open with stable row geometry.
  • Hosted Status Page submenu: Open Status Page was a native highlighted row; the API-only submenu remained unchanged while highlighted, then rebuilt exactly once after pointer exit and showed the added Dashboard row.
  • Close while deferred: no late rebuild fired; reopening populated the new layout through the normal open path.
  • Hosted-child provider race: the child closed with the dirty parent still natively highlighted and an explicit Claude rebuild saved. The callback re-deferred Claude while highlighted; after pointer exit exactly one rebuild ran, cleared the deferred state, marked the parent fresh, and visibly replaced the Codex placeholder with Claude actions. The generic Codex request never ran.

Local screenshots were retained as QA artifacts and were not uploaded.

Screenshot before

Screenshot 2026-07-09 at 22 44 33

@Zihao-Qi Zihao-Qi force-pushed the codex/fix-native-menu-hover-highlight branch from 9349281 to f3dbee5 Compare July 10, 2026 13:47
@Zihao-Qi Zihao-Qi marked this pull request as ready for review July 10, 2026 13:50

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f3dbee5bad

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/StatusItemController+MenuTracking.swift Outdated
@steipete steipete force-pushed the codex/fix-native-menu-hover-highlight branch from e2d2293 to 44e4f90 Compare July 10, 2026 17:45

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 44e4f90bd2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/CodexBar/StatusItemController+MenuTracking.swift
Co-authored-by: Trim <womayeyonggugele@gmail.com>
@steipete

Copy link
Copy Markdown
Owner

Maintainer proof for exact head 94ccb89a96f426444e76d79d790c674ea1a9df7b:

  • Repair: preserves the exact deferred provider request plus sticky readiness-baseline resync through request coalescing, native highlights, and open hosted children. After a hosted child closes, the saved explicit request also remains authoritative over a generic dirty-parent refresh.
  • Focused verification: 187/187 tests across 3 menu/lifecycle suites passed, including both child-close orders and the dirty/highlight-through-close provider race.
  • Full local gates: make check passed; make test passed 598/598 selections and 50/50 groups with zero failures, retries, or timeouts; full-branch review and final two-file autoreview clean.
  • Package proof: the exact normal debug bundle is Developer ID signed, strict-valid, and Gatekeeper accepted; the separate exact LLDB bundle is strict-valid with debug-only get-task-allow.
  • Exact packaged UI: under isolated home/config state, both Keychain gates, and network/provider-process denial, a hosted child closed while its dirty parent remained natively highlighted with an explicit Claude request saved. The first callback retained Claude and safely re-deferred; pointer exit produced the second and only actual rebuild, cleared the deferred state, marked the parent fresh, and visibly replaced the Codex placeholder with Claude actions. The generic Codex request never ran.
  • Source-blind packaged behavior validation: 5/5 clauses passed, including exact metadata/signatures, sandbox controls, chronological capture/hash checks, callback count, and the visible before/after state.
  • Current-main integration: conflict-free three-way merge with 8489002e (Default Agent Sessions to off #2039); this exact-head PR run was triggered after that base landed.
  • Hosted CI: exact-head run 29115867481 passed changes, lint, Linux arm64/x64, both macOS shards, aggregate, and GitGuardian checks.
  • Review: both reported P2s are fixed, replied to, and resolved; no unresolved review threads. Public Model Identifier Gate: PASS. Dependency freshness: N/A.

Local QA screenshots were retained but not uploaded. No real provider, credential, browser-cookie, or Keychain probe was used. Thanks @Zihao-Qi!

@steipete steipete merged commit e0ee6a0 into steipete:main Jul 10, 2026
8 checks passed
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