Skip to content

Resize adjacent snapped windows with a draggable divider - #1907

Draft
kiteretsu903 wants to merge 7 commits into
rxhanson:mainfrom
kiteretsu903:fix/review-window-dividers
Draft

kiteretsu903 wants to merge 7 commits into
rxhanson:mainfrom
kiteretsu903:fix/review-window-dividers

Conversation

@kiteretsu903

@kiteretsu903 kiteretsu903 commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Draft pending #1904 and the independent placement coordinator included in #1903. This branch includes those prerequisites, without the Fit feature. It is rebased onto current main and no longer depends on closed #1902.

Adds the off-by-default “Drag dividers to resize adjacent windows” option under Adjacent Windows. Eligible side-by-side or top/bottom windows placed by Rectangle expose a handle near their shared boundary. Dragging previews a new split; releasing applies the pair placement. Double-clicking requests an equal split.

Behavior and boundaries

  • A pair is checked against its current geometry and visibility. Temporary occlusion or an AX timeout hides the handle and retains the pair for a later verified hover. Confirmed geometry changes invalidate it. Entry cleanup uses existence across Spaces, so hidden and minimized windows are not treated as closed.
  • Each drag starts from current reported AX constraints and a fresh placement attempt. A verified clamp can adjust the two windows during that attempt, but is not retained for later drags or written to a size-limit store. A later drag can retry a smaller size.
  • Escape before release cancels the preview; during committed placement it requests rollback while ownership remains valid. Unrelated clicks allow settlement to finish. A new Rectangle command, a member-window grab, or a Space change relinquishes ownership without issuing rollback writes over the newer action. Local and global events are handled.
  • Responsive rounded sizes adjust the neighboring edge with bounded retries, preserving accepted cross-axis rounding. Incompatible constraints still roll back. Screenshot-overlay hit testing uses application-scoped AX timeouts.
  • The handle and extending divider lines support standard blur and Glass with the shared appearance setting.

Optional enhanced transitions

“Enhanced transitions” captures the background once per drag on macOS 14 or later with Screen Recording permission. The guide and moving outlines render separately. Capture failure, missing permission, or a late result falls back to the basic guide. Basic divider use requires no capture permission.

Implementation and dependencies

Pair discovery, drag geometry, verified pair placement, and optional capture live within the divider feature. The change reuses the shared placement coordinator and Glass support. It contains no learned-size store, management UI, or preview-only size tracking. It does not depend on Layout Helper; when both are present, a small interaction hook coordinates their sessions.

Validation

The shared Glass geometry tests also passed after correcting an assertion that mixed a new material’s model frame with its parent’s previous rendered frame. Model and presentation geometry are now checked separately, with a bounded requirement for rendered samples. This follow-up changes tests only.

The current branch passed a signed Debug build and all 622 XCTest tests, including rounded-size settlement, fixed-axis/wholly-ignored resize handling, off-screen entry retention, click-through event targeting, cross-axis pair eligibility, reported-minimum warnings, and Escape rollback after the first write. Native acceptance on macOS 27.2 / Apple silicon passed first/repeated drags and equal reset on both axes, changed native reported minimums on the same pair, odd-point gaps, cancellation before release, moved/disabled-pair invalidation, and real enhanced background capture followed by cancellation, and recovery after temporary covering-window removal. The 7-method native suite additionally routes a synthetic unrelated left-click through SnappingManager during real AX/WindowServer settlement and verifies both windows finish. This checks manager integration; it does not claim a physical mouse reproduction of every WindowServer event field. An earlier native interaction run used the secondary display because a Notification Center surface obscured the primary divider. The current regression run used the primary display after a Notification Center surface covered the secondary test area; the obstructed runs correctly hid the handle and are retained in the local test logs.

An earlier run exposed a stale AX preparation snapshot: lowering the app-reported minimum still constrained the next drag to the old value. Hover preparation now refreshes the snapshot on its existing background worker. The native regression reproduces the old failure on both axes and passes after the fix. No learned or persisted size limit is reintroduced.

The basic native drag also passed with enhanced transitions enabled and a test-only unavailable-permission result; system TCC settings were unchanged. The automated native suite uses an isolated AppKit fixture and actual AX/WindowServer writes; test-only input seams route through the native panel callbacks. Installed application and preference state were restored and verified. The demo below predates the standalone rebase.

An earlier physical-input acceptance run used global macOS mouse and keyboard events with the test pointer overrides disabled. Native hover, first and repeated drags, and double-click equal-split reset passed for both side-by-side and top/bottom pairs. Escape during an active divider drag passed on the second connected display, leaving both windows unchanged. The installed binary, saved preferences, and pointer position were restored afterward.

This replaces the corresponding part of #1890.

Demo

10-window-dividers.mp4

Window animation is disabled. Recorded with the combined build and only this feature and its required visual options enabled.

Settings

Resize adjacent snapped windows with a draggable divider settings

@kiteretsu903
kiteretsu903 force-pushed the fix/review-window-dividers branch 2 times, most recently from b9773fb to 706710b Compare October 10, 2026 02:51
@kiteretsu903
kiteretsu903 force-pushed the fix/review-window-dividers branch from 706710b to 0ba8225 Compare October 14, 2026 01:46
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