[PR #3181] Snap to character grid when resizing window #25266

Open
opened 2026-01-31 09:08:23 +00:00 by claunia · 0 comments
Owner

Original Pull Request: https://github.com/microsoft/terminal/pull/3181

State: closed
Merged: Yes


When user resizes window, snap the size to align with the character grid (like e.g. putty, mintty and most unix terminals). Properly resolves arbitrary pane configuration (even with different font sizes and padding) trying to align each pane as close as possible.

It also fixes terminal minimum size enforcement which was not quite well handled, especially with multiple panes.

This PR does not however try to keep the terminals aligned at other user actions (e.g. font change or pane split). That is to be tracked by some other activity.

term_snapping

References

#3060 introduces some differences in size calculations by moving from separator to borders, but it should be easy to adopt to that.

PR Checklist

  • Closes #2834, Closes make Windows Terminal available to v1809 (#2277)
  • CLA signed. If not, go over here and sign the CLA
  • Tests added/passed - do we have UI tests yet?
  • Requires documentation to be updated
  • I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

Detailed Description of the Pull Request / Additional comments

Snapping is resolved in the pane tree, recursively, so it (hopefully) works for any possible layout.

Along the way I had to clean up some things as so to make the resulting code not so cumbersome:

  1. Pane.cpp: Replaced _firstPercent and _secondPercent with single _desiredSplitPosition to reduce invariants - these had to be kept in sync so their sum always gives 1 (and were not really a percent). The desired part refers to fact that since panes are aligned, there is usually some deviation from that ratio.
  2. Pane.cpp: Fixed _GetMinSize() - it was improperly accounting for split direction
  3. TerminalControl: Made dedicated member for padding instead of reading it from a control itself. This is because the winrt property functions turned out to be slow and this algorithm needs to access it many times. I also cached scrollbar width for the same reason.
  4. AppHost: Moved window to client size resolution to virtual method, where IslandWinow and NonClientIslandWindow have their own implementations (as opposite to pointer casting).

One problem with current implementation is I had to make a long call chain from the window that requests snapping to the (root) pane that implements it:
IslandWindow -> AppHost's callback -> App -> TerminalPage -> Tab -> Pane
Idk if this can be done better.

Validation Steps Performed

Spam split pane buttons, randomly change font sizes with ctrl+mouse wheel and drag the window back and forth.

**Original Pull Request:** https://github.com/microsoft/terminal/pull/3181 **State:** closed **Merged:** Yes --- When user resizes window, snap the size to align with the character grid (like e.g. putty, mintty and most unix terminals). Properly resolves arbitrary pane configuration (even with different font sizes and padding) trying to align each pane as close as possible. It also fixes terminal minimum size enforcement which was not quite well handled, especially with multiple panes. This PR does not however try to keep the terminals aligned at other user actions (e.g. font change or pane split). That is to be tracked by some other activity. ![term_snapping](https://user-images.githubusercontent.com/38111589/66719323-858b2980-edee-11e9-9709-a6e1c5e473d2.gif) ## References #3060 introduces some differences in size calculations by moving from separator to borders, but it should be easy to adopt to that. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [X] Closes #2834, Closes #2277 * [X] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed - do we have UI tests yet? * [ ] Requires documentation to be updated * [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx ## Detailed Description of the Pull Request / Additional comments Snapping is resolved in the pane tree, recursively, so it (hopefully) works for any possible layout. Along the way I had to clean up some things as so to make the resulting code not so cumbersome: 1. `Pane.cpp`: Replaced `_firstPercent` and `_secondPercent` with single `_desiredSplitPosition` to reduce invariants - these had to be kept in sync so their sum always gives 1 (and were not really a percent). The `desired` part refers to fact that since panes are aligned, there is usually some deviation from that ratio. 2. `Pane.cpp`: Fixed `_GetMinSize()` - it was improperly accounting for split direction 3. `TerminalControl`: Made dedicated member for padding instead of reading it from a control itself. This is because the winrt property functions turned out to be slow and this algorithm needs to access it many times. I also cached scrollbar width for the same reason. 4. `AppHost`: Moved window to client size resolution to virtual method, where `IslandWinow` and `NonClientIslandWindow` have their own implementations (as opposite to pointer casting). One problem with current implementation is I had to make a long call chain from the window that requests snapping to the (root) pane that implements it: `IslandWindow` -> `AppHost`'s callback -> `App` -> `TerminalPage` -> `Tab` -> `Pane` Idk if this can be done better. ## Validation Steps Performed Spam split pane buttons, randomly change font sizes with ctrl+mouse wheel and drag the window back and forth.
claunia added the pull-request label 2026-01-31 09:08:23 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#25266