Skip to content

Cooperative Window Resizer Feature#1780

Open
epicdistraction wants to merge 17 commits into
rxhanson:mainfrom
epicdistraction:epicdistraction/autoadjust-pt2
Open

Cooperative Window Resizer Feature#1780
epicdistraction wants to merge 17 commits into
rxhanson:mainfrom
epicdistraction:epicdistraction/autoadjust-pt2

Conversation

@epicdistraction

@epicdistraction epicdistraction commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

https://i.imgur.com/hXlCZfk.mp4

The Cooperative Window Resizer will automatically adjust the windows around it to avoid having to cmd tab and resize.

I ended up cherry picking the commits on a new branch to avoid an annoying rebase.

Summary

  • Adds cooperative resizing for repeated side and corner shortcut cycling.
  • Adds a new opt-in preference: “Resize adjacent windows when cycling side or corner shortcuts”
  • Resizes directly adjacent tiled windows inversely when a repeated side/corner cycle changes the focused window
  • Supports co-occupying windows in the same side/corner position so they follow the focused window’s resize
  • Makes side and corner repeated shortcuts interoperable across compatible cycle lanes
  • Handles clean side-to-corner tiled layouts, including stacked corner neighbors
  • Keeps behavior conservative for ambiguous partial overlaps and unrelated floating windows

Testing

  • Added frame-math tests for vertical/horizontal expansion and shrink
  • Added tests for side actions, corner actions, side/corner interoperability, co-occupying windows, and the 2/3 split-ratio first-cycle regression
  • Added regression coverage for partial same-side occupants in a four-corner 2/3 fixture

@epicdistraction epicdistraction force-pushed the epicdistraction/autoadjust-pt2 branch from deebb4e to 58b489b Compare June 17, 2026 02:23
@epicdistraction

Copy link
Copy Markdown
Contributor Author

Cleaned up this branch, reviewed, and it passes functional testing. Ready for 👀

@rxhanson

Copy link
Copy Markdown
Owner

Great! So far so good. I'll give it a thorough run-through tomorrow.

@rxhanson

Copy link
Copy Markdown
Owner

I have a couple of relatively minor bugs, and if you can't reproduce them then let me know and I can attach logs.

  • Terminal window edges require a bit more tolerance to catch since they're window size is governed by line height rather than pixels.
  • If a window doesn't resize small enough, then it will overlap an adjacent window and won't continue to resize the adjacent window on subsequent cycles. It's not terrible behavior, but it feels incorrect.

I like it a lot, though, and it's great with the vertical corner cycling.

@epicdistraction

Copy link
Copy Markdown
Contributor Author

Good catches! I normally use iTerm and that has a smoother resize behavior. Able to repro with terminal

I also ran into the resize issue last night when using the laptop screen instead of external. That led me down a route to add an extra option for fuzzy matching. That allows programatic switching between mobile screen and tighter matching for higher res in my use-case. I'll narrow down the tolerance to work well in both modes for terminal.

Daniel added 3 commits June 19, 2026 10:48
…e for smaller apps. Allows for gap resize feature
Min width will force the split ratio to be moved to the nearest successful split.
Logic to picking up nearby windows that are cutoff by the side split and wider range capture.
Incorporates gap between windows feature.
@epicdistraction

Copy link
Copy Markdown
Contributor Author

Large commit pushed. Still a WIP.

This resolves the bug whack-a-mole between: nearby tolerances of apps that don't quite fit like terminal, min application heigh and width forcing the grid larger on nearby resize or window resize. It also includes logic to pickup windows that are cutoff by a side split. And allows the gap between windows feature to function with the cooperative window planner.

There is a small bug where the command needs to be cycled multiple to invoke an action when the side split ratio ends up different than the settings entry due to min width. I'll have more time this evening to circle back on that.

@epicdistraction

epicdistraction commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

other minor issues that I'm tracking. If a min size is too large, it will split the difference and pushing the edge of the cooperatively resized window just slightly outside the grid. Doesn't occur when min size restriced window is the invoking window/corner

also sometimes the behavior to move a window to a corner is a bit aggressive towards the invoking window. Solution will look forward to the difference betweeen the whitespace from the current window location to the screen edges to determine if it should move.

edit: and when dragging a window to a snap corner, it should invoke the cooperative window resizer function in the same method as a shortcut.

@rxhanson

Copy link
Copy Markdown
Owner

Sounds good, looking forward to the update. Let me know if you hit any scenarios where it would help to have another set of eyes take a look.

@epicdistraction

epicdistraction commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

I'm happy with the behavior. The above issues were closed out. It looks super pretty with the gap between windows feature enabled.

edit: Its getting close. The window resolver will redraw a 1/3 to a min size instead of going straight to the min size. The MVP functionality is there. Just has a flash of a redraw. Might be work a follow up pr. Since this is fairly sprawling. I'll be able to spend more time tomorrow.

@rxhanson

Copy link
Copy Markdown
Owner

Nice! I'm good with merging when it makes sense and having follow-on adjustments. I'm getting ready to move, so I will most likely wait until early July to push out the next Rectangle release so there's not an immediate rush to get this into a release (although I appreciate the cadence of your work so far).

@epicdistraction

Copy link
Copy Markdown
Contributor Author

Moves are always quite stressful. I'll be hoping it goes smooth for ya.

No worries on it taking a bit to get to a release. Probably best for myself and a few others to really utilize it for a bit to potentially find any corner cases. I was thinking about putting a build on my repo's releases. There is quite a bit of functionality that can be extended in various ways through the other configuration options. So. So, it'd be good to have a few friends that use rectangle try before general release.

There is still that minor adjustment for the window resolver to get a single redraw when moving a non min restricted sized application to a corner that is currently min-restricted. It's the same behavior, just slightly cleaner. But, I needed to take a break from that code for a minute. I'll be able circle back on that during the week. Good to either merge or keep this open for that tweak.

@rxhanson

rxhanson commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Just wanted to check in since I didn't respond immediately after your last update. In looking through some of this change in a little more detail, I was thinking that if possible, it would be nice to split out the changes in WindowManager into a separate file (new class/struct or extension), since it's easy to push a lot of logic directly into that file, but can be difficult to keep it simple. Aside from that it's looking good so far!

@epicdistraction

Copy link
Copy Markdown
Contributor Author

refactored the WindowManager changes into an extension. Have a concrete plan for the refinements after quite a bit of use. Going to experiment with those on Thursday.

Use realized constrained/cyclic corner boundaries for initial placement, avoid cleanup from reduced adjacent corners, and make repeated cycling recognize cooperative gap-adjusted frames.
@epicdistraction

Copy link
Copy Markdown
Contributor Author

I updated cooperative corner resizing so looks forward more towards the current realized layout after cyclic commands were used instead of blindly snapping to saved split ratios.

Main changes:

  • New corner placements now preflight existing windows and start at the observed constrained/cyclic boundary, avoiding the visible “default size then bounce” redraw.
  • When a min-size-constrained window leaves a corner, Rectangle can clean up the layout back toward the intended split, but only if the departing corner was the enlarged constrained one.
  • Cleanup no longer runs when leaving the adjacent reduced corner, so it avoids the redraw/bounce against the still-min-restricted window.
  • Repeated corner cycling now recognizes cooperative/gap-adjusted frames, so cycling doesn’t hit odd in-between states after a constrained move.
  • Added regression tests for the min-size corner, adjacent-corner skip, cyclic reuse, and gap-adjusted cycling cases.

There is one more refinement that I'm playing with locally. Think I figured out the best way to do it without complicating the ui or adding confusion.

@epicdistraction

Copy link
Copy Markdown
Contributor Author

Okay that was an easier refinement to implement and test than I was thinking. Although, I feel it still might be missing a UI piece.

Programmatically, it creates a separate variable for the current layout's state for the split-ratio sizes.

That can be adjusted by using the side ratio shortcuts.

So basically, if your default right-side size is 1/3, but you press the right-side shortcut again and grow it to 2/3, Rectangle treats that 2/3 size as the current layout. Later side and corner shortcuts follow that layout instead of jumping back to the default. It does not change the saved settings

It works really well and I like it. Maybe its intuitive enough in use to not need an explanation or just a "default side split ratio" in the menu title, indicating something else can change it.

@epicdistraction

epicdistraction commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Actually, Reverted that last commit and going back to just the refinements for the draw. The dynamic side split still needs a bit more work. I'll keep that as its own branch.

@rxhanson

rxhanson commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Great! Thanks for the WindowManager extension work.

So basically, if your default right-side size is 1/3, but you press the right-side shortcut again and grow it to 2/3, Rectangle treats that 2/3 size as the current layout. Later side and corner shortcuts follow that layout instead of jumping back to the default. It does not change the saved settings.

I'll have to test this out some more, but at first glance I'm thinking that perhaps this does make sense to simply keep as the default behavior and not add a UI setting for it (it's also hard to communicate this concept concisely in a label). I'll let you know if I hit any snags while testing through it, but if not I think perhaps we're at a place where I should merge the current progress.

@epicdistraction

epicdistraction commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

This is good for review.

There was a small issue with the cleanup refinement to limit the amount of redraw skipped the focused window if it was min restricted in size and moved to an adjacent side. Every other window in the adjacent side would be cleaned up. The focused window would solely use the preflight destination but not apply the resize after it moved a corner out back to default size.

Yeah the dynamic side split does feel like where the feature should land. I've had a few ideas on it, but none great. The best might be a placing an extra shortcut next to the side split ratio selector for resetting the sidesplit ratio and moving everything to the default corners. That would be an indication that things can get out of state, add a bit of sanity, and not clutter it up with too much explanation.

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.

2 participants