Skip to content

Add ninths (3x3) twelfths (3x4) and sixteenths (4x4) grid positions, with cycling mode#1720

Merged
rxhanson merged 11 commits intorxhanson:mainfrom
MyronKoch:feature/twelfths-sixteenths
Mar 20, 2026
Merged

Add ninths (3x3) twelfths (3x4) and sixteenths (4x4) grid positions, with cycling mode#1720
rxhanson merged 11 commits intorxhanson:mainfrom
MyronKoch:feature/twelfths-sixteenths

Conversation

@MyronKoch
Copy link
Contributor

@MyronKoch MyronKoch commented Mar 13, 2026

Summary

  • Adds 12 twelfths (3 columns x 4 rows) and 16 sixteenths (4 columns x 4 rows) window positions
  • Each position includes a calculation class with OrientationAware support and position cycling via TwelfthsRepeated/SixteenthsRepeated protocols
  • Includes pixel-accurate 30x20px template image assets matching the existing icon style
  • Adds .twelfths and .sixteenths categories to WindowActionCategory

Motivation

These finer grid positions are especially useful for users with large or ultra-high-resolution displays - 50" 4K TVs used as monitors, ultrawide displays, or multi-monitor arrays - where halves, thirds, and quarters leave too much unused screen real estate. A 4x4 grid on a 50" 4K display gives each tile roughly the usable area of a 720p laptop screen, which is ideal for tiling many windows simultaneously.

Changes

  • WindowAction.swift - 28 new enum cases (raw values 80-119), with name, displayName, image, category, gapsApplicable, alternateDefault, SubWindowAction, and gapSharedEdge entries
  • WindowActionCategory.swift - .twelfths and .sixteenths cases
  • WindowCalculation.swift - 28 factory instances and calculationsByAction entries
  • 28 new *Calculation.swift files (one per position)
  • TwelfthsRepeated.swift and SixteenthsRepeated.swift - cycling protocols
  • 28 image assets in Assets.xcassets/WindowPositions/
  • PrefsViewController.swift - shortcut views for twelfths and sixteenths categories
  • project.pbxproj - build file references for all new files

Test plan

  • Build succeeds with no warnings in the new files
  • Each twelfth position tiles correctly on a standard display
  • Each sixteenth position tiles correctly on a standard display
  • Cycling through all positions works via repeated shortcut presses
  • Gap settings apply correctly to all new positions (shared edges respected)
  • OrientationAware behavior swaps correctly in portrait mode
  • Menu items appear under new Twelfths and Sixteenths submenus
  • Template images render correctly in light and dark mode

🤖 Generated with Claude Code

Move thirds (First Third through Last Two Thirds) and size actions
(Almost Maximize, Maximize Height, Larger, Smaller) into their own
submenus in the menu bar dropdown, matching the existing pattern used
by fourths, sixths, eighths, and move actions.

Also removes the conditional hiding of the eighths submenu, making it
always visible like all other grid categories.

This reduces menu clutter for users with many grid sizes enabled,
particularly on large displays and multi-monitor setups.
Add 28 new window positions for fine-grained window management on large
displays. Users with 4K TVs (50"+), ultrawide monitors, or multi-monitor
arrays need more granular positioning than halves, thirds, fourths,
sixths, and eighths provide.

Twelfths divide the screen into a 3-row by 4-column grid (12 positions).
Sixteenths divide the screen into a 4-row by 4-column grid (16 positions).

Each grid size includes:
- Window calculations with orientation-aware layout
- Cycling through positions on repeated shortcut presses
- Drag-to-snap support
- Gap-aware edge positioning
- Template images for menu and settings display
- Settings panel with shortcut configuration for all positions
- Add largerWidth, smallerWidth, largerHeight, smallerHeight to the
  .size category so all size-related actions appear in the Size submenu
- Remove dead eighthsMenuItem property from AppDelegate (no longer
  assigned after removing the conditional hiding logic)
- Remove dead reference in SettingsViewController toggle handler
Portrait mode for twelfths transposes the 4x3 landscape grid to a 3x4
portrait grid using row-major index remapping. The previous code naively
mapped landscape column positions to portrait columns, causing 3 pairs
of overlapping positions and one empty row. Fixed 8 of 12 portraitRect
methods with correct row/column assignments.

Also standardize 4 abbreviated sixteenth display names to use the full
form consistent with all other positions.
@rxhanson
Copy link
Owner

Thanks for looking to contribute to Rectangle.

Rectangle's Shortcuts tab is a bit limited by design, as the intent is to keep the app more approachable. More recently I've designated the "overflow" area for new sizes/positions to the popover shown by the ellipsis button on at the bottom of the General tab. That provides a middle ground where the simple aesthetic is preserved but the community has the ability to add more to the app as desired.

I'm good with merging in more sizes/positions, but when added to the UI it has to still be done in a way that is visually acceptable in the popover. In this case, some options would be adding in more columns or converting the existing settings in that popover into a table view that can scroll.

If that's not desirable, another option is to leave all of the additions out of the UI and keep them as Terminal command configurations only at this time.

Let me know if you have any questions.

@MyronKoch
Copy link
Contributor Author

MyronKoch commented Mar 15, 2026

Thanks for the guidance on the popover pattern! I've moved the twelfths and sixteenths shortcuts into the ellipsis popover on the General tab using a cycling approach: one shortcut per grid size that cycles through all positions on repeated presses (using the existing *Repeated protocols). This adds just 3 compact rows instead of 28 individual ones.

Here's how it looks in the popover - note the "Grid Positions" section at the bottom with the cycling hint:

Screenshot 2026-03-15 at 1 06 38 AM

I'll update the PR branch to reflect this. The ninths (3x3) are also included as a cycling shortcut since they were already fully implemented but only individually configurable.

Let me know if this direction works for the popover UI.

Per maintainer feedback, move twelfths/sixteenths shortcuts from the
Shortcuts tab into the ellipsis popover on the General tab. Instead of
28 individual rows, use one cycling shortcut per grid size that cycles
through all positions on repeated presses via the existing *Repeated
protocols. Restore PrefsViewController to upstream state.
- Add useCyclingShortcuts BoolDefault (default false) to Defaults.swift
- Add 12 individual twelfths rows and 16 individual sixteenths rows to
  the General tab extra settings popover, following the exact eighths pattern
- Add "Use cycling shortcuts" checkbox at top of Grid Positions section
- When cycling mode is on, hide individual rows and show one cycling
  shortcut per category (Eighths, Twelfths, Sixteenths); cycling hint
  text visible only in cycling mode
- When cycling mode is off (default), show all individual position rows
  and hide cycling rows
- Use objc associated objects to wire checkbox to row visibility toggle
@rxhanson
Copy link
Owner

Thanks for the update. I pulled your changes, and now looking at this cohesively as this one pull request I have clarity on criteria for getting this into a mergeable state:

  • We can remove the "use cycling shortcuts" checkbox and simply leave the Ninths, Twelfths, and Sixteenths as the single Shortcut recorder. For these it is less likely that individual shortcut recorders would be beneficial enough to justify adding them in, and then we don't have to worry about showing/hiding in the popover and readjusting it's size accordingly.
  • Instead of the "Show Eighths in Menu" Checkbox, let's have a single checkbox that adds all of the additional menus with submenus (8ths, 12ths, 16ths, and 9ths if desired), and converts the Thirds & Size menu items into submenus as proposed in the other PR.

I think this gives us the benefit of the additional sizes with a reasonable menu, without adding too much complexity to the popover, and it preserves the existing simplicity for users that don't have large screens.

Let me know if anything's unclear here.

…dback

- Replace "Show Eighths in Menu" with "Show additional sizes in menu"
  checkbox that shows 8ths, 9ths, 12ths, 16ths submenus and converts
  Thirds & Size into submenus when enabled
- Remove "Use cycling shortcuts" checkbox and individual twelfths/
  sixteenths rows (-454 lines); keep only cycling shortcut recorders
  for Ninths (3x3), Twelfths (4x3), Sixteenths (4x4)
- Add ninths category to WindowActionCategory for menu grouping
- Remove useCyclingShortcuts preference (no longer needed)
@MyronKoch
Copy link
Contributor Author

Thanks for the clear guidance - this is much cleaner.

Changes made:

Popover (General tab > ellipsis):

  • Removed the "Use cycling shortcuts" checkbox and all 28 individual twelfths/sixteenths rows
  • Now shows just 3 cycling shortcut recorders: Ninths (3x3), Twelfths (4x3), Sixteenths (4x4)
  • Kept the cycling hint text explaining "press repeatedly to cycle"

Menu checkbox:

  • Replaced "Show Eighths in Menu" with "Show additional sizes in menu"
  • When enabled: shows Eighths, Ninths, Twelfths, and Sixteenths submenus, and converts Thirds & Size into submenus
  • When disabled (default): hides those submenus, preserving the existing simple menu

Cleanup:

If this looks right I can close #1721 since its changes are incorporated here.

@rxhanson
Copy link
Owner

Great, I'll test out the updates in the next day or so.

Quarter actions (Top Left, Top Right, Bottom Left, Bottom Right) now
cycle through all four corner positions on repeated presses, matching
the pattern used by sixths, eighths, ninths, twelfths, and sixteenths.

Adds QuartersRepeated protocol following the same design as
SixthsRepeated and other *Repeated protocols.
@MyronKoch
Copy link
Contributor Author

One more small addition while you're testing: quarter-screen actions (Top Left, Top Right, Bottom Left, Bottom Right) now cycle through all four corner positions on repeated presses.

This brings them in line with how sixths, eighths, ninths, twelfths, and sixteenths already work via the *Repeated protocols. Previously quarters only cycled through width fractions (1/2, 1/3, 2/3) but didn't move between corners.

New file: QuartersRepeated.swift - follows the exact same pattern as SixthsRepeated.swift.

@MyronKoch
Copy link
Contributor Author

MyronKoch commented Mar 17, 2026

Cycling Demo

All position-cycling shortcuts in action - quarters, thirds, fourths, sixths, eighths, ninths, and sixteenths:

Cycling Demo

@MyronKoch MyronKoch force-pushed the feature/twelfths-sixteenths branch from cc23cbe to 33ed1e1 Compare March 17, 2026 06:42
@rxhanson
Copy link
Owner

Thanks for the quick turnaround. A few more points:

  • I think it's fair to close Organize thirds and size actions into menu submenus #1721 and move forward with incorporating the changes here. Without that setting enabled, it's still desired to keep the original menu as-is, as mentioned in that PR (not having thirds and sizes in submenus). I realize the menu isn't easily updated on the fly, but I typically prefer avoiding restarting the app for a setting to take effect, and if it's unavoidable then I will at least prompt the user to allow the app to restart itself when a setting is changed.
  • The default for showing eighths in the menu should be automatically converted over to this new setting, so that if anyone enabled eighths then they would still have eighths in the menu (it's fine for those users to also get the new additional sizes in the menu).
  • The quadrant shortcuts need to still respect the cycle sizes setting for the subsequentExecutionMode. A lot of people would be tripped up if this were to change. Perhaps introducing a new subsequentExecutionMode value is the simplest approach to get what you're looking for.

A lot of people have been using Rectangle for years, and we want to favor keeping the existing UI & functionality in place by default.

  • In the general tab ellipsis popover, ninths needs an icon.
  • In the general tab ellipsis popover, let's move all of the eighths into the Grid Positions section, and put the Show additional sizes in menu checkbox at the top of the Grid Positions section.
  • Let's not have a Claude.md checked in, as Rectangle should remain agnostic and not carry anything that could be misconstrued as an endorsement.

…cycling mode

- Keep original menu when "Show additional sizes" is off (Thirds/Size as flat items)
- Live menu rebuild on checkbox toggle (no restart needed)
- Migrate old "showEighthsInMenu" default to new setting
- New subsequentExecutionMode (resizeAndCycleQuadrants) for quarter position cycling
  so existing modes are unchanged for long-time users
- Add ninth (3x3) grid display names, image assets, and icons in popover
- Move eighths into Grid Positions section, checkbox at top
- Order menu submenus numerically: Sixths, Eighths, Ninths, Twelfths, Sixteenths
@MyronKoch MyronKoch force-pushed the feature/twelfths-sixteenths branch from 0dab293 to de2b674 Compare March 18, 2026 16:17
@MyronKoch
Copy link
Contributor Author

All feedback addressed:

Menu behavior:

  • When "Show additional sizes in menu" is OFF, the original menu is preserved (Thirds and Size remain flat items, not submenus)
  • When ON, Thirds and Size convert to submenus and Eighths/Ninths/Twelfths/Sixteenths become visible
  • Menu rebuilds live on toggle - no restart needed
  • Old showEighthsInMenu default is automatically migrated to the new setting

Quarter cycling:

  • Added new subsequentExecutionMode value: "resize and cycle quadrant positions" (available in the Repeated commands dropdown)
  • Existing modes are completely unchanged - quarters still cycle sizes in mode 0, do nothing in mode 2, etc.
  • Position cycling only activates when the user explicitly selects the new mode

Popover (General tab ellipsis):

  • Eighths moved into the Grid Positions section
  • "Show additional sizes in menu" checkbox at top of Grid Positions section
  • Ninths has an icon (topLeftNinthTemplate asset)
  • All ninth display names added for menu visibility

Other:

@MyronKoch MyronKoch changed the title Add twelfths (3x4) and sixteenths (4x4) grid positions Add ninths (3x3) twelfths (3x4) and sixteenths (4x4) grid positions, with cycling mode Mar 18, 2026
@rxhanson
Copy link
Owner

Ok, this is looking great! I'm good with merging at this point, but there are two minor items that I'll do if you don't:

  • In the menu with the additional items enabled, have Thirds come after Move to Edge, before Fourths.
  • Rename the menu item resize and cycle quadrant positions to cycle positions on quadrants, cycle sizes on half

- Sort category submenus by explicit menuOrder so Thirds appears after
  Move to Edge and before Fourths when additional sizes are enabled
- Rename subsequentExecutionMode label from "resize and cycle quadrant
  positions" to "cycle positions on quadrants, cycle sizes on half"
@MyronKoch
Copy link
Contributor Author

Done! Both items addressed:

  • Menu ordering: Thirds now appears after Move to Edge, before Fourths (when additional sizes are enabled). Default menu is unchanged.
  • Renamed: "resize and cycle quadrant positions" is now "cycle positions on quadrants, cycle sizes on half"

Thanks for the thoughtful feedback throughout this PR, Ryan. I run Rectangle all day every day across three 50" 4K TVs used as monitors, and it's genuinely saved me countless hours over the past couple of years. Happy to contribute back to a tool that's become essential to my workflow.

@MyronKoch MyronKoch force-pushed the feature/twelfths-sixteenths branch from 222e109 to 046bfc5 Compare March 20, 2026 01:17
@rxhanson
Copy link
Owner

Awesome, thanks for contributing! I'm certain that a lot of people with large displays will greatly appreciate this. With the ellipsis popover continuing to grow, I might turn it into a new tab in the Settings window so that it isn't quite so hidden. I'll aim to get a release out soon with your change here.

@rxhanson rxhanson merged commit fa2b425 into rxhanson:main Mar 20, 2026
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