Skip to content

Support vertical display traversal on repeated half actions - #1952

Merged
rxhanson merged 4 commits into
rxhanson:mainfrom
yannickgloster:vertical-half-display-traversal
Nov 3, 2026
Merged

rxhanson merged 4 commits into
rxhanson:mainfrom
yannickgloster:vertical-half-display-traversal

Conversation

@yannickgloster

@yannickgloster yannickgloster commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Adds support for up/down window moving, just like existing left/right window moving. Useful for vertical monitor setups.

Changes

  • With an across-display mode on (subsequentExecutionMode 1 or 3), repeating Top Half or Bottom Half moves the window to the nearest display above or below and lands on its facing half (Top Half → the bottom half of the display above). The next press is a fresh Top Half on that display, so repeats keep climbing the stack.
  • A vertical neighbor has to overlap the current display horizontally, so side-by-side and corner-only displays are skipped. The nearest display wins, and horizontal overlap breaks ties.
  • In mode 1 the top and bottom of a stack wrap to its opposite end, like left/right cycling. Mode 3 cycles sizes at the boundary instead, matching its horizontal behavior.
  • Switch sides (mode 6) and the new traversal share one facingVerticalHalf helper, so the Top/Bottom Half switch-sides branches are now one line each. Left/Right Half and Next/Previous Display are unchanged.
  • The two Repeated commands labels that said "left or right" now say "move to adjacent display on side actions" and "move to adjacent display on side actions and cycle size at final edge", as suggested in review since the side ratio isn't always a half. The translations are updated for all 32 languages. French and Spanish have been reviewed; the others are marked Needs Review, since I don't speak the language. README and TerminalCommands.md describe the new behavior.

Tests

Added VerticalDisplayTraversalTests (12 tests): stacked and offset displays, side-by-side and corner-only displays, repeat detection and moved windows, nearest-display and overlap tie-breaking, wrapping at both ends of a three-display stack, mode 3's boundary resize, modes that don't traverse, and two full cycles in each direction across three displays. Full suite: 725 passed, 0 failed (Xcode 27.2, macOS 27.0.1).

Repeated Top Half from a MacBook to an external display above has been checked by hand; wraparound hasn't been checked on hardware yet.

@yannickgloster
yannickgloster force-pushed the vertical-half-display-traversal branch from 3858bad to f9601b0 Compare November 2, 2026 16:19
With a display stacked above another, repeating Top Half could not move
a window up: only Left and Right Half traverse displays. When an
across-display mode is enabled, a repeated Top or Bottom Half now moves
the window to the nearest display above or below and lands on its
facing half.

A vertical neighbor must overlap the current display horizontally, so
side-by-side and corner-only displays are skipped. The nearest display
wins, with horizontal overlap breaking ties. In the traverse-only mode
the top and bottom of a stack wrap to its opposite end; the combined
traverse-and-resize mode cycles sizes at the boundary instead, matching
the horizontal behavior.

Switch sides and vertical traversal share facingVerticalHalf, which
reports the facing half as the resulting action so the next press is a
fresh execution. Left/Right Half and Next/Previous Display are
unchanged.

Renames the two Repeated commands labels that said left/right and
carries every existing localization over to the new wording. French and
Spanish are reviewed; the rest are marked for review. Updates README and
TerminalCommands.md. Tests cover stacked and offset displays, repeat
detection, boundaries, mode selection, and two full cycles in each
direction across three displays.
@yannickgloster
yannickgloster force-pushed the vertical-half-display-traversal branch from f9601b0 to 58fa35c Compare November 2, 2026 16:26
@yannickgloster
yannickgloster marked this pull request as ready for review November 2, 2026 16:28
Resolves the zh-Hant entries of the renamed Repeated commands labels with
the half-actions wording from the Traditional Chinese localization, keeps
both sides' appended test classes, and updates the label name in the new
thirds-and-fourths TerminalCommands.md section.
Keeps both sides' appended test classes in RectangleTests.swift.
@yannickgloster

Copy link
Copy Markdown
Contributor Author

@rxhanson any chance this could also get looked at? Would love this merged upstream into rectangle pro

@rxhanson rxhanson left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, there are just a couple of wording adjustments to make. I'll let you adjust those since the localizations will also need to be adjusted. Thanks!

I'm getting ready to merge a lot of Rectangle changes into Rectangle Pro, and I'll see if I can get this one in an earlier batch.

Comment thread Rectangle/SubsequentExecutionMode.swift Outdated
switch self {
case .resize: return String(localized: "cycle sizes on side actions")
case .acrossMonitor: return String(localized: "move to adjacent display on left or right")
case .acrossMonitor: return String(localized: "move to adjacent display on half actions")

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's change this to "move to adjacent display on side actions". Rectangle now allows for the side ratio to be adjusted, so it's not necessarily a half.

Comment thread Rectangle/SubsequentExecutionMode.swift Outdated
case .acrossMonitor: return String(localized: "move to adjacent display on half actions")
case .none: return String(localized: "do nothing")
case .acrossAndResize: return String(localized: "move to adjacent on left/right, or cycle size on side")
case .acrossAndResize: return String(localized: "move to adjacent on halves, or cycle size on side")

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's change this to "move to adjacent display on side actions and cycle size at final edge".

The side ratio is adjustable, so the across-display options are named
after side actions rather than halves: "move to adjacent display on side
actions" and "move to adjacent display on side actions and cycle size at
final edge". Updates the localizations, README and TerminalCommands.md to
match; French and Spanish are reviewed, the rest are marked for review.
@yannickgloster
yannickgloster force-pushed the vertical-half-display-traversal branch from ee33590 to 06f9b90 Compare November 3, 2026 21:46
@rxhanson
rxhanson merged commit 0698b04 into rxhanson:main Nov 3, 2026
1 check passed
@rxhanson

rxhanson commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Thanks!

@yannickgloster

yannickgloster commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks!

cheers thank you, looking forward to the rectangle pro update

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