add new window actions: tile a display in rows or columns - #1850
add new window actions: tile a display in rows or columns#1850dank-openai wants to merge 6 commits into
Conversation
Expose separate on-demand shortcuts in More Shortcuts and arrange ordinary windows from the current Space into pixel-aligned bands on the focused display. Respect configured screen-edge gaps and window size limits while leaving other displays in place. Include the Todo sidebar transition, icons, localization, documentation, and focused layout regression tests.
|
Thanks for contributing! At the moment, new window actions are being placed in the popover at the Extras button in the General tab until I rearrange things in this release. Would you mind moving these there? |
Rows and Columns retain their independent saved action keys, localized labels, icons, and shortcut recording. Remove their old storyboard rows and obsolete extracted strings.
Sure, I moved the Rows and Columns shortcut fields to General > Extras. FYI, I'm planning a follow-up PR to cycle through different splits. With six windows, for example, it could cycle from six columns with one window each, to three columns with two windows stacked in each (a 50% split), to two columns with three windows stacked in each (splits at 33% and 66%). |
Tile All, Rows, and Columns select the ordinary focused window's display, falling back to the mouse display when no ordinary window has focus. Keep focus optional through band placement and leave an empty target unchanged. Exercise focus priority, pointer fallback, current-Space selection, and empty displays with synthetic windows. The pointer regression detects a deliberate restoration of the missing-fallback behavior. The existing ID-less frame-rounding test still has two assertions that fail at the original PR head as well.
|
Great, thanks for moving those settings. In looking through the code changes, I'm a little confused as to why the |
|
Also, the follow-on idea sounds good to me. |
Compare each frame component within the existing tolerance so ID-less windows keep valid current-Space evidence when position and size both round. Preserve raw-ID reservation and ambiguity handling. Cover both axes and reject components beyond the tolerance.
I checked both. The Keeping Todo pinned, as Tile All does, would let us remove the TodoManager changes; Rows/Columns would then exclude Todo. For the current behavior, I recommend keeping these rules in the shared helpers. |
|
Thanks for following up! The premise of Todo mode is that the todo window is ignored by all other window commands performed by Rectangle, and I think the use-case for Todo mode users is that they would disable Todo mode if they desired to tile the todo window with these. My preference is to not adjust TodoManager for these actions, to keep them more consistent with the Todo functionality in the rest of the app. For ScreenDetection, primarily combined display mode: From what I can tell, the majority of people that disable "Displays have separate spaces" are doing this to treat two identical displays as one; to allow windows to span across the displays. In that sense, if I had that setup then my expectation would be that the tiling simply spans all of these displays as though they were one. As such, my thought here is also to not bother with forcing the single display. If there is compelling reason to limit the tiling to the focused display, then this might be more elegantly done within the window actions themselves instead of modifying the ScreenDetection file. My intent isn't to nitpick, but simply to keep the app features cohesive and reduce risk on changing commonly hit code paths. |
Keep Todo outside Rows/Columns and tile within the existing sidebar reservation. Use the shared usable-frame calculation and include current-Space windows across displays when combined-display mode is active. Display selection still prefers the focused window's display, with the display under the pointer as the fallback. Apply focus recovery before candidate filtering so it cannot reintroduce a focused Todo window. ScreenDetection and TodoManager need no feature-specific changes. Focused tests cover Todo exclusion, reserved work area, combined-display placement, current-Space filtering, and ordinary display isolation. In-memory window fixtures exercise compiled application code without moving live windows.
|
One more thing I forgot to mention: rather than adding these into the menu by default, let's leverage |
Thanks, that makes sense. Rows/Columns now follow the existing Todo exclusion and honor combined-display mode. I removed the PR's changes to TodoManager and ScreenDetection. |
Group the two actions under Tiling and use Show additional sizes in menu to control its visibility. Keep shortcut registration independent of the menu and preserve the existing show-all-actions override. Exercise the real menu builder with explicit options so tests do not change saved preferences.
Done - Rows and Columns are grouped under Tiling, shown when Show additional sizes in menu is enabled. Their keyboard shortcuts remain available independently of menu visibility. |
Summary
Why This Change
Tile All makes a grid. Rows and Columns provide full-width top-to-bottom or full-height left-to-right layouts without continuous reflow. Neither action has a default shortcut, so existing bindings are preserved. Window order follows their upper-left positions before any moves. An empty target does nothing.
With separate display areas, for example, no focused window and the pointer on the right monitor makes tiling arrange that monitor's windows. Focusing a window on the left monitor makes that monitor the target even if the pointer remains on the right.
If three windows share 901 backing pixels of available height after configured edge gaps, Rows assigns 301, 300, and 300 pixels. The bands meet without an internal gap, while the reserved screen edges remain clear. With a work area 1000 pixels wide before a 200-pixel Todo sidebar reservation, the other windows tile within 800 pixels and Todo stays in place.
Limits and validation
If an app refuses a requested size, Rectangle attempts to rebalance the bands; an impossible layout may still leave a gap or overlap. A window without an accessible ID may be left untiled when on-screen evidence cannot distinguish it from a window in another Space. When matching windows to determine their Space, position and size are compared separately using the same backing-pixel tolerance, so independent rounding does not exclude an otherwise matching window.
All 24 tiling tests pass against compiled application code with synthetic windows. Coverage includes focused-display priority, pointer fallback on either monitor, non-window focus, current-Space selection, empty targets, independent frame rounding, Todo exclusion even when focused, and tiling across combined display bounds. Restoring physical-display filtering or bypassing Todo exclusion makes the corresponding regressions fail.
A nonlaunching
xcodebuild build-for-testingsucceeded. On earlier feature builds, the author manually tested Rows and Columns with focused windows and confirmed that windows on other monitors stayed in place. The author also confirmed pointer fallback in a separate installed local build that contains additional grid features and shares this PR's display-selection logic. Combined-display mode, Todo, and nonzero edge gaps have not been tested in the running app on this PR branch.