Skip to content

Lay out Bento again when the work area changes back before settling - #167

Merged
LMC-Karma merged 1 commit into
mainfrom
fix/work-area-change-back
Oct 15, 2026
Merged

LMC-Karma merged 1 commit into
mainfrom
fix/work-area-change-back

Conversation

@LMC-Karma

@LMC-Karma LMC-Karma commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Problem

When a display's work area changes, Bento lays the windows out for the new
area but records that area only after the windows settle. If the area changed
back before then, Bento compared it with the old recorded area, saw no change,
and left the windows sized for the area in between. Only Repair Bento fixed it.

The window is a fraction of a second. A display change that is undone, a Dock
size change, or Leave space for Dock (#168) turned on and off quickly can hit it
when the windows settle slowly.

Change

A session keeps the work area of a written but unconfirmed layout in
pendingWorkArea. A change from either the confirmed or the pending area lays
the windows out again. A failed settlement still leaves the change to retry on
a later sweep. Confirming any work area, including through Repair, clears the
pending one. The field is runtime-only.

Evidence

  • Before: the new Core test aWorkAreaThatChangesBackBeforeSettlingIsAppliedAgain
    fails on main. The change back returns no layout. The same stuck layout
    appeared once in an app-model test on the Dock branch under full-suite load:
    windows stayed at height 720 after the area returned to 800.
  • After: the test passes. swift test passes (all three test targets),
    including the existing settlement and retry tests. The Debug xcodebuild
    with CODE_SIGNING_ALLOWED=NO succeeds on this branch.
  • Live regression check, using a local build of this change together with
    Add Leave space for Dock and stop following the auto-hidden Dock #168, on a 1210×812 display with three windows in Bento:
    • Leave space for Dock on, then off, at human speed: 749, then 812.
    • On, then off, 0 to 0.4 seconds apart (14 runs): every run ended at 812.
    • Dock shown, then hidden, then Repair: stayed at 812.
    • No further layout writes for 3 to 4 seconds afterward, with the setting
      on or off.

Limits

  • Checks not run and why: the race itself could not be staged live.
    Responsive windows settle in about 80 ms, which is less than the 120 ms
    display-refresh delay. The same rapid toggles on a build without this fix
    never got stuck either. The Core test is the reproduction.
  • Remaining uncertainty: none known.

Safety

None. Core layout policy only. No permissions, private APIs, or stored data.

🤖 Generated with Claude Code

A work-area change waits for its settlement before Bento records the new
area. If the area changed back before that, Bento compared it with the old
recorded area, saw no change, and left the windows sized for the area in
between. Repair was the only way out.

Keep the area of a written but unconfirmed layout in pendingWorkArea. A
change from either the confirmed or the pending area now lays the windows
out again. A failed settlement still leaves the change to retry, and
confirming any work area clears the pending one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@claude

claude Bot commented Oct 15, 2026

Copy link
Copy Markdown

Review summary

Traced the fix end to end: AmbientLayoutReconciler.transition now checks both lastWorkArea (confirmed) and the new pendingWorkArea (written but unsettled) when deciding workAreaChanged, and LayoutSessions.swift clears pendingWorkArea via didSet whenever lastWorkArea is confirmed.

Checked the affected paths and their reverse transitions:

  • Shrink then settle: pendingWorkArea is set to the new area, lastWorkArea stays at the old (confirmed) value until settlement succeeds — matches the doc comment on applyLayout.
  • Shrink then change back before settling (the bug): the next sweep compares against both lastWorkArea and pendingWorkArea, so the reversal is detected and a new layout is proposed, covered by the new aWorkAreaThatChangesBackBeforeSettlingIsAppliedAgain test.
  • Settlement success (BetterTileModel.scheduleAuthoritativePlacementSettlement, .applied case): sets lastWorkArea = workArea, which clears pendingWorkArea via didSet.
  • Settlement failure: leaves lastWorkArea/pendingWorkArea untouched, so the discrepancy is retried on the next sweep, matching the PR's "Limits" claim.
  • Repair and other synchronous Bento commits (repairAllWindows, repairSingleWindow, Layout Wheel/shortcut commits) already set lastWorkArea directly outside this diff; the new didSet makes these also clear a stale pendingWorkArea for free, matching "Confirming any work area, including through Repair, clears the pending one."

Checked repository rules: the diff touches only BetterTileCore (no AppKit/Accessibility imports added), LayoutSession is not Codable/persisted so the new runtime-only field has no migration impact, and no window mutation, networking, permission, or private-API surface is touched — consistent with the stated "Safety: None."

No confirmed code faults found, so no inline comments were posted.

Not a code fault, flagging for completeness: the PR's evidence section only states swift test passed; it doesn't mention the xcodebuild Debug build that AGENTS.md's "Build and test" section also asks for before opening a ready PR. Worth confirming that ran (or noting it was skipped and why) before merge.

I could not execute swift test myself in this review environment (no approved toolchain access), so the "after" claim in the PR body is accepted on the strength of the added test's logic, not independently re-run.

@LMC-Karma
LMC-Karma merged commit 4180d27 into main Oct 15, 2026
4 checks passed
@LMC-Karma
LMC-Karma deleted the fix/work-area-change-back branch October 15, 2026 23:20
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.

1 participant