Skip to content

fix(menubar): suppress clicks when fullscreen menu bar items rest above the screen#626

Closed
devesh-aggarwal wants to merge 1 commit into
stonerl:developmentfrom
devesh-aggarwal:disable-fullscreen-clicks
Closed

fix(menubar): suppress clicks when fullscreen menu bar items rest above the screen#626
devesh-aggarwal wants to merge 1 commit into
stonerl:developmentfrom
devesh-aggarwal:disable-fullscreen-clicks

Conversation

@devesh-aggarwal
Copy link
Copy Markdown

@devesh-aggarwal devesh-aggarwal commented May 27, 2026

What does this PR do?

Tightens NSScreen.isSystemMenuBarVisible() so it returns false not just when the Window Server reports zero on-screen menu bar items, but also when those items are flagged on-screen yet positioned above the screen's top edge (the auto-hide resting position used inside a fullscreen space). All three call sites — HIDEventManager.handleShowOnClick, HIDEventManager.handleSecondaryContextMenu, and ControlItem.performAction — pick up the stricter check automatically.

PR Type

  • Bugfix
  • CI/CD related changes
  • Code style update (formatting, renaming)
  • Documentation
  • Feature
  • Refactor
  • Performance improvement
  • Test addition or update
  • Other (please describe):

Does this PR introduce a breaking change?

  • Yes
  • No

If yes, please describe the impact and migration path:

N/A

What is the current behavior?

While another app is in fullscreen with the system menu bar auto-hidden, clicking near the top of that app's window (e.g. the top edge of a Chrome tab) makes Thaw treat the click as a menu bar click and reveal the hidden section. The existing guard added in #574 only filters by the Window Server's kCGWindowIsOnscreen flag, but macOS keeps NSStatusItem windows flagged as on-screen even while they sit at the auto-hide resting position above the visible screen — so the guard lets the phantom click through.

Issue Number: N/A

What is the new behavior?

isSystemMenuBarVisible() now additionally requires at least one item's reported bounds (Bridging.getWindowBounds) to intersect this NSScreen's frame. While the menu bar is auto-hidden in fullscreen all items sit above the screen and the function returns false, so show-on-click, show-on-double-click, the secondary context menu, and ControlItem.performAction all stay quiet. Once the user hovers to reveal the menu bar the items slide into the screen frame and every existing behaviour resumes unchanged. The same bounds-vs-screen filter already lives in MenuBarItemImageCache for the exact same macOS quirk, so this stays consistent with established patterns in the codebase.

PR Checklist

  • I've built and run the app locally
  • I've checked for console errors or crashes
  • I've run relevant tests and they pass
  • I've added or updated tests (if applicable)
  • I've updated documentation as needed

Other information

Test plan (manual, since the affected paths depend on the live Window Server and aren't covered by ThawTests):

  1. Enable Show on click in Settings → General and ensure a hidden section is populated.
  2. Open Chrome (or any app), enter fullscreen via the green button or Ctrl+Cmd+F, and do not hover at the top edge.
  3. Click a tab at the very top of the Chrome window — Thaw must not reveal the hidden section. The diagnostic log shows handleShowOnClick: suppressing, no menu bar items on-screen for active space.
  4. Hover the top edge until the menu bar fully reveals, then click empty space in the revealed menu bar — show-on-click works as before.
  5. Exit fullscreen and confirm show-on-click in the regular menu bar is unchanged.

Notes for reviewers

  • Single change in Thaw/Utilities/Extensions.swift. The function signature is unchanged; only the body is stricter, so existing callers don't need updates.
  • The frame.intersects(bounds) check mirrors MenuBarItemImageCache.swift (the comment there explicitly calls out the macOS bug where hidden items are reported as on-screen), so the coordinate-space approximation is the established pattern in this codebase rather than a new one.
  • This is layered on top of fix(menubar): ignore clicks while the system menu bar is auto-hidden offscreen #574, not a replacement — the on-screen filter still does the cheap first pass; the bounds check only matters when the Window Server lies about visibility.

Summary by CodeRabbit

  • Bug Fixes
    • Improved system menu bar visibility detection accuracy to better reflect the actual state of the menu bar on screen.

Review Change Stack

Copilot AI review requested due to automatic review settings May 27, 2026 01:49
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 895f0ce8-650e-4646-aae9-66a10b5d1e31

📥 Commits

Reviewing files that changed from the base of the PR and between c0eb525 and ecb8737.

📒 Files selected for processing (1)
  • Thaw/Utilities/Extensions.swift

📝 Walkthrough

Walkthrough

The NSScreen.isSystemMenuBarVisible() method now validates menu bar visibility by checking if at least one window's bounds intersects the current screen frame, rather than merely checking for window list presence.

Changes

Menu bar visibility detection

Layer / File(s) Summary
Menu bar bounds intersection check
Thaw/Utilities/Extensions.swift
isSystemMenuBarVisible() replaces list-based presence check with bounds intersection logic: iterates menu bar window IDs, retrieves bounds for each window, and returns true only if at least one window bounds intersects the screen frame.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • stonerl/Thaw#574: Adds and uses NSScreen.isSystemMenuBarVisible() for suppressing menu-bar click handlers; this PR refines the visibility detection logic in that same method.
  • stonerl/Thaw#614: Also adjusts menu-bar/status-item visibility logic to tolerate bounds extending past expected frames by switching from frame containment to intersection-based checks.

Suggested labels

enhancement

Suggested reviewers

  • stonerl
  • diazdesandi

Poem

A menu bar hides and shows its face,
No longer trusting list-based grace.
Now bounds must kiss the screen just so,
To prove the menu bar's aglow. 🍎

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main bugfix: suppressing clicks when fullscreen menu bar items rest above the screen, which directly addresses the core change in NSScreen.isSystemMenuBarVisible().
Description check ✅ Passed The PR description comprehensively covers all required template sections including what the PR does, PR type (bugfix), breaking changes, current/new behavior, issue context, test plan, and reviewer notes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates NSScreen.isSystemMenuBarVisible() to better match perceived menu bar visibility in fullscreen/auto-hide scenarios by requiring at least one status item window to intersect the screen’s vertical bounds (not just be flagged .onScreen).

Changes:

  • Expanded documentation explaining why .onScreen is insufficient in fullscreen auto-hide states
  • Updated visibility logic to check each menu bar item window’s bounds against the current screen frame

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +771 to +778
let windowIDs = Bridging.getMenuBarWindowList(option: [.onScreen, .activeSpace, .itemsOnly])
let screenFrame = frame
return windowIDs.contains { windowID in
guard let bounds = Bridging.getWindowBounds(for: windowID) else {
return false
}
return bounds.intersects(screenFrame)
}
Comment on lines +771 to +778
let windowIDs = Bridging.getMenuBarWindowList(option: [.onScreen, .activeSpace, .itemsOnly])
let screenFrame = frame
return windowIDs.contains { windowID in
guard let bounds = Bridging.getWindowBounds(for: windowID) else {
return false
}
return bounds.intersects(screenFrame)
}
@nightah
Copy link
Copy Markdown
Collaborator

nightah commented May 27, 2026

Can you please detail the reproduction steps for this on the existing development branch?
I tested this quite rigorously and also confirmed with the respective users that the issue was resolved.

Having a video of you reproducing the suspected issue would also help me understand whether what you're experiencing is "as expected" or actually a bug.

@devesh-aggarwal
Copy link
Copy Markdown
Author

This seems to have been fixed in the latest beta release

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.

3 participants