Skip to content

Throttle keyboard pane resize to avoid UI stalls - #20563

Open
zhangxaochen wants to merge 2 commits into
microsoft:mainfrom
zhangxaochen:dev/throttle-keyboard-pane-resize
Open

Throttle keyboard pane resize to avoid UI stalls#20563
zhangxaochen wants to merge 2 commits into
microsoft:mainfrom
zhangxaochen:dev/throttle-keyboard-pane-resize

Conversation

@zhangxaochen

Copy link
Copy Markdown

Summary of the Pull Request

Keyboard resizePane (hold Alt+Shift+Left/Right) no longer queues a XAML + terminal reflow on every auto-repeat tick. The latest split percentage is always accepted; the grid is applied at a rate that tracks recent layout cost, and each apply is capped so a UI stall cannot jump the splitter across the window.

Closes #20562.

References and Relevant Issues

Detailed Description of the Pull Request / Additional comments

Pane::_Resize used to call _CreateRowColDefinitions() on every key-repeat (~30 Hz). That rebuilds the Grid row/column definitions and reflows every terminal under the splitter. With 4 panes the layout cost exceeds one key-repeat period, so the UI thread queues more work than it can finish: hitching, occasional half-window jumps after a stall, and in Debug an ANR.

This change:

  1. Always writes _desiredSplitPosition so a held key still progresses.
  2. Applies the grid at _splitLayoutInterval (starts at 125 ms, then an EMA of 2 × measured layout cost, clamped to 32–250 ms). At most one DispatcherQueueTimer is in flight.
  3. After a real apply, samples cost on a Low-priority dispatcher callback (after this pump / typical XAML layout). No-ops (clamp boundary, unchanged position) do not refresh the cooldown or the cost estimate.
  4. Caps each applied move to ±10% (two 5% key steps) and drops the excess instead of queueing it. Normal 1–2-step applies never hit the cap; a stall can no longer jump half the screen.

Mouse drag / programmatic split size is unchanged — only the keyboard _Resize path is throttled.

I intend to implement this (already validated locally). No settings/schema/docs changes.

Validation Steps Performed

  • Built and registered CascadiaPackage x64 Release (WindowsTerminalDev).
  • 4-pane tab, hold Alt+Shift+Left/Right for several seconds: splitter keeps moving, window stays responsive, no ANR.
  • Same repro on unpatched 1.24.11911.0: visible hitching / occasional large jump (see videos on Holding Alt+Shift+Left/Right to resize panes stalls the UI (4+ panes) #20562).
  • Debug Dev build of the old path could freeze the window; the patched path stays alive even when layout is expensive (interval walks toward 250 ms).
  • Reverse direction after holding against the clamp applies immediately (no-op no longer refreshes the cooldown).

PR Checklist

Key auto-repeat can fire resizePane faster than XAML and every
terminal under the splitter can reflow. Keep accepting the new
split percentage, but apply the grid at an interval that tracks
recent layout cost, and cap per-apply movement so a UI stall
cannot jump the splitter across the window.

Fixes microsoft#20562

Co-authored-by: Cursor <cursoragent@cursor.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Comment thread src/cascadia/TerminalApp/Pane.cpp Fixed
Comment thread src/cascadia/TerminalApp/Pane.cpp Fixed
Comment thread src/cascadia/TerminalApp/Pane.cpp Fixed
Comment thread src/cascadia/TerminalApp/Pane.cpp Fixed
@github-actions

This comment has been minimized.

@zhangxaochen

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Reword "relayout" / "cooldown" so the spelling bot is happy
without adding project dictionary entries for two comments.

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

Holding Alt+Shift+Left/Right to resize panes stalls the UI (4+ panes)

2 participants