Skip to content

fix: re-capture display properties after settling to fix stale working area#1346

Draft
lohrm-spf wants to merge 1 commit into
glzr-io:mainfrom
michidk:fix/macos-outer-gap-working-area
Draft

fix: re-capture display properties after settling to fix stale working area#1346
lohrm-spf wants to merge 1 commit into
glzr-io:mainfrom
michidk:fix/macos-outer-gap-working-area

Conversation

@lohrm-spf

Copy link
Copy Markdown
Contributor

Summary

  • Schedule a follow-up display change event 500ms after each reconfiguration to re-capture NSScreen.visibleFrame once macOS has settled
  • Also fire one at startup to correct any transient values from the initial capture
  • Fixes an intermittent gap between the top bar and tiled windows on the primary monitor

Problem

With menu bar auto-hide enabled, macOS may briefly show the menu bar during display reconfiguration (monitor connect/disconnect) or at launch. NSScreen.visibleFrame captured at that moment includes the menu bar offset (~25-37px), but macOS does not fire another NSApplicationDidChangeScreenParametersNotification once the menu bar re-hides. The stale working_area offset is then added to the user's outer_gap, creating an unexpected gap on the primary monitor.

The issue is intermittent because it depends on whether the menu bar happens to be visible at capture time. It only affects the primary monitor (secondary monitors have no menu bar). Windows is unaffected because the taskbar working area is stable.

Solution

Re-use the existing delayed-event pattern (already used for wake coalescing) to schedule a follow-up DisplaySettingsChanged event 500ms after:

  1. Each display reconfiguration — by the time the follow-up fires, the menu bar auto-hide animation (~300ms) has completed and visibleFrame reflects the true usable area
  2. Startup — corrects any transient values from the initial populate() capture

The handler (handle_display_settings_changed) already handles redundant events gracefully — if the re-captured properties match the stored ones, the redraw is effectively a no-op.

Research

  • yabai avoids NSScreen entirely, using private SkyLight/CG APIs for menu bar geometry
  • Amethyst uses NSApplicationDidChangeScreenParametersNotification (same as GlazeWM) but subscribes to additional menu bar change notifications
  • AeroSpace lazily re-reads NSScreen on every refresh session
  • Apple docs confirm the menu bar auto-hide state is not part of the screen parameters notification cycle

… working area

With menu bar auto-hide enabled, macOS may briefly show the menu bar
during display reconfiguration or at launch. NSScreen.visibleFrame
captured at that moment includes the menu bar offset, but macOS does
not fire another notification once the menu bar re-hides. This causes
an unexpected gap between the top bar and tiled windows on the primary
monitor.

Schedule a follow-up display change event 500ms after each
reconfiguration to re-capture display properties once macOS has
settled. Also fire one at startup to correct any transient values
from the initial capture.
@github-project-automation github-project-automation Bot moved this to 📬 Needs triage in glazewm Apr 1, 2026
// reconfiguration and does not fire another notification
// once it re-hides (~300-500ms later).
let tx = event_tx.clone();
std::thread::spawn(move || {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hmm is there a difference between this and just extending the coalesce duration 500ms..? 👀

@lohrm-spf lohrm-spf changed the title fix(macos): re-capture display properties after settling to fix stale working area fix: re-capture display properties after settling to fix stale working area Apr 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 📬 Needs triage

Development

Successfully merging this pull request may close these issues.

3 participants