Skip to content

Fix fullscreen detection on notched displays (Sequoia/Tahoe)#31

Open
jeffscottmtl wants to merge 2 commits into
lihaoyun6:mainfrom
jeffscottmtl:fix/fullscreen-detection
Open

Fix fullscreen detection on notched displays (Sequoia/Tahoe)#31
jeffscottmtl wants to merge 2 commits into
lihaoyun6:mainfrom
jeffscottmtl:fix/fullscreen-detection

Conversation

@jeffscottmtl

Copy link
Copy Markdown

Summary

  • On notched MacBooks running Sequoia/Tahoe, native fullscreen renders below the notch, so the fullscreen window is ~safeAreaInsets.top shorter than NSScreen.frame. The strict windowRect.equalTo(screen.frame) check in getFullScreens() always fails on these machines, so the logo never hides in fullscreen even with "Always on Screen" toggled off.
  • Additionally, the original comparison ignored the coordinate-space difference between CGWindowList bounds (top-left origin, Y grows down) and NSScreen.frame (bottom-left origin, Y grows up). It only matched on the primary display because both happen to anchor at (0,0) there.
  • Replaces equalTo with a new isFullScreenWindow(_:on:primaryHeight:) helper that converts to a common coordinate space, accepts either the full screen rect or the screen-minus-notch rect, and tolerates 2 pt of sub-pixel rounding. Non-notched displays are unaffected because safeAreaInsets.top == 0, so cgScreenBelowNotch == cgScreenRect.

Reproducing on my machine, screen.frame reported (0, 0, 1710, 1107) with safeAreaInsets.top == 33, while the fullscreen Safari window's kCGWindowBounds came back as ~(0, 33, 1710, 1074) — i.e. exactly 33 pt shorter. The new check matches that variant.

Closes #29
Closes #30

Test plan

  • Release build on Xcode 26.5 / macOS 26.x
  • M4 MacBook Air, single notched display: enter fullscreen → logo hides; exit → logo returns
  • "Always on Screen" toggle still works (still overrides hiding via existing ContentView logic)
  • Multi-monitor verification with one external display
  • Non-notched Mac (Mac mini / iMac / older MacBook) — expected unchanged

🤖 Generated with Claude Code

The previous getFullScreens() compared a window's CGWindowList bounds
(top-left origin, CG global coords) directly against NSScreen.frame
(bottom-left origin, AppKit coords) using equalTo, and assumed a
fullscreen window's height equals screen.frame.height.

On notched MacBooks running Sequoia/Tahoe, native fullscreen renders
*below* the notch, so the window is ~safeAreaInsets.top shorter than
screen.frame. The strict equality check always fails on these machines,
which is why the logo never disappears in fullscreen even with
"Always on Screen" toggled off (see lihaoyun6#29, lihaoyun6#30).

Replace equalTo with isFullScreenWindow(), which:
  - converts NSScreen.frame to CG coordinates using the primary
    screen's height
  - accepts either the full screen rect or the screen-minus-notch rect
  - tolerates 2pt of sub-pixel rounding

Closes lihaoyun6#29
Closes lihaoyun6#30

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous getFullScreens() accepted a second "screen minus the top
inset" rect (cgScreenBelowNotch) as a full-screen match, on the premise
that notched Macs render native full screen below the notch. Live
instrumentation on macOS 26 (Tahoe, notched, built-in + external display)
disproved that premise: native full screen covers the ENTIRE display
(origin.y == 0, full height), while a merely maximized window sits below
the menu bar at origin.y == menuBarHeight. The below-notch rect is
geometrically identical to a maximized window, so isFullScreenWindow()
returned true for any maximized window. The logo was hidden whenever a
maximized window was on screen, which is why it never came back after
exiting full screen (you exit into a maximized window) until the app was
restarted.

Match only the full-screen rect, keeping the CGWindow<->NSScreen
coordinate conversion and the 2pt tolerance (the genuinely useful parts
of the prior fix, confirmed working for the external display via the Y
origin flip). The top-edge difference (y==0 vs y==menuBarHeight) cleanly
separates true full screen from maximized.

Verified across a full enter/exit cycle on built-in and external
displays: maximized leaves the logo visible, full screen hides it, and
exiting restores it immediately with no restart.

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.

unable to hide the icon under full screen mode No option to disable "Visible in full screen mode"

1 participant