Let half actions preserve the window's size on the other axis (opt-in) - #1824
Let half actions preserve the window's size on the other axis (opt-in)#1824X-Wei wants to merge 1 commit into
Conversation
|
Thanks for contributing! Things look good at a quick glance. The list of checkboxes in the General tab is steadily growing and I haven't ironed out my preferred way to prevent it from turning into something unwieldy. Would you mind putting that checkbox at the bottom of the popover displayed from the "Extras" button in the General tab for now? I think I'll end up with another tab for more settings instead of the Extras button, but I haven't decided where everything will go yet. |
Left Half, Right Half, Top Half and Bottom Half always give the window the whole height or width of the screen, so reaching a quarter takes a dedicated corner shortcut. Behind the new halvesPreserveOtherAxisSize default, each of them only changes the axis it belongs to (Left/Right: width, Top/Bottom: height) and keeps the other one, like Win + arrow keys on Windows or keyboard tiling on KDE: Left Half then Top Half lands in the top left quarter, Bottom Half from there expands back to Left Half, Right Half then Left Half fills the screen. The window's state on each axis is recognized purely from its current frame (docked to an edge at the active split ratio or any cycle size, with or without gaps, within a 10 pt tolerance), so nothing new is tracked. The result reports the geometrically equivalent action as resultingAction / subAction so gaps and window history behave as if that action had run; WindowCalculation.calculate now forwards RectResult.resultingAction, which every subclass setting it already handled by overriding calculate. Untiled windows and repeated executions of a plain half fall through to the existing code, so the repeated-command setting keeps working as before. The default is off; with it off nothing changes. - Add HalvesPreserveOtherAxisSize.swift with the per-axis state logic - Consult it first in the left/right, top and bottom half calculations - Add HalvesPreserveOtherAxisSizeTests (32 cases) - Document the default in TerminalCommands.md - Expose it as a "Half actions preserve the window's size on the other axis" checkbox, unchecked by default, at the bottom of the Extras popover in the General settings tab (title and tooltip registered in Main.xcstrings)
7905548 to
0ea5f70
Compare
|
Done — the checkbox now sits at the bottom of the Extras popover, below the side split ratio rows, and the General tab is untouched. Same title, tooltip and default (off); the commit is amended and force-pushed. Happy to move it again once you settle on a tab for these. |
Summary
Adds an opt-in mode in which Left Half, Right Half, Top Half and Bottom Half only change the axis they belong to (Left/Right → width, Top/Bottom → height) and keep the window's size and position on the other axis — the way Win + arrow keys tile windows on Windows, or keyboard tiling works on KDE.
With it, the four half shortcuts are enough to reach every half and quarter: Left Half then Top Half lands in the top left quarter, Bottom Half from there expands back to Left Half, and Right Half then Left Half fills the screen.
Off by default (
halvesPreserveOtherAxisSize); nothing changes unless it is enabled.Related: discussions #665 and #811 (where this was asked for, and you said you would be fine merging a good PR for it configurable via Terminal command), and #144. This is the narrow version discussed there: no separate "Windows mode" and no preset or extra shortcuts — the existing half actions simply take the window's current position into account, the logic lives in one self-contained class, and everything sits behind a single default.
Behavior when enabled
Each half action looks at where the window currently sits along its own axis and leaves the other axis exactly as it is:
Some sequences:
Untiled windows and repeated executions of a plain half deliberately fall through to the existing code, so the feature never changes what the repeated-command setting does.
How it works
HalvesPreserveOtherAxisSize.rect(for:)recognizes the window's state on each axis purely from its current frame: an axis counts as "docked" when the window's origin and extent match (within 10 pt, for apps that resize in character cells) an edge-docked rect that a half action produces on that screen — at the active split ratio or any cycle size, with or without gaps applied. Anything else counts as "whole axis". It returnsnilwhenever the existing logic should run.LeftRightHalfCalculation,TopHalfCalculationandBottomHalfCalculationconsult it first when the default is enabled; otherwise they are untouched..topLeft+.topLeftQuarter,.leftHalf,.maximize, …) asresultingAction/subAction, so gaps and the window history behave exactly as if that action had been executed. For that,WindowCalculation.calculatenow forwardsRectResult.resultingActioninstead of ignoring it — every subclass that sets it already overridescalculate, so this is not a behavior change by itself.Testing
HalvesPreserveOtherAxisSizeTests(32 cases): every state transition, no-ops inside quarters, fallback to the existing logic for untiled windows and repeated plain halves, cycled 2/3 and 1/3 columns/rows, non-50 % split ratios, gaps (including the skip-top-edge option), matching tolerance, and the disabled path.Try it
A notarized Apple-silicon build of this branch (unofficial, signed with my own Developer ID) is attached to https://github.com/maxing-labs/Rectangle/releases/tag/v0.99-halvesPreserveOtherAxis-b108 — install, then tick the checkbox at the bottom of the Extras popover in Settings.
Docs / UI
TerminalCommands.md: new section "Make the half actions tile like Windows or KDE" with thedefaults writecommand.Main.xcstrings. Happy to drop the checkbox and keep this terminal-only if you prefer.