Update our DECSC/DECRC implementation to match the latest DEC algorithm #19583

Open
opened 2026-01-31 06:47:57 +00:00 by claunia · 0 comments
Owner

Originally created by @j4james on GitHub (Mar 26, 2023).

Description of the new feature/enhancement

When origin mode (DECOM) is enabled, the cursor is supposed to be constrained within the boundaries of the scrolling margins (DECSTBM). But consider what happens when you save the cursor position (with DECSC), and then update the margins so that saved position would now be out of bounds.

For example, say the top margin is row 1, the cursor position is row 5. After saving the cursor position, we then update the top margin to row 10. On what row would you expect the cursor to restore?

On the early DEC terminals, the cursor would be restored to its original position (row 5), which is now 5 rows above the top margin. This is not a legal position when origin mode is enabled, and if you requested the coordinates with a DSR-CPR query, you'd get a nonsense result with random characters representing the negative coordinates.

Up to now we've avoided this bug by clamping the coordinates within the margin boundaries, but the way DEC ultimately addressed the issue was by using relative coordinates. So in the example above, the start row of 5 is offset 4 from the top margin, and thus the restored row becomes 14 (offset 4 from the new margin of 10).

So I would like to propose we update our implementation to match this later DEC algorithm, since that seems to be the most correct. You can see a demonstration of how this was handled on a range of different DEC terminals in issue https://github.com/microsoft/terminal/issues/14876#issuecomment-1459325217.

Proposed technical implementation details (optional)

This would actually be somewhat simpler than our current implementation. There's an extra step when saving the cursor to subtract the offset of the top margin (assuming the origin mode is set). But then when restoring the cursor, we can just pass the coordinates straight to the CursorPosition method without any additional adjustments (which are required in the current implementation).

Originally created by @j4james on GitHub (Mar 26, 2023). # Description of the new feature/enhancement When origin mode (`DECOM`) is enabled, the cursor is supposed to be constrained within the boundaries of the scrolling margins (`DECSTBM`). But consider what happens when you save the cursor position (with `DECSC`), and then update the margins so that saved position would now be out of bounds. For example, say the top margin is row 1, the cursor position is row 5. After saving the cursor position, we then update the top margin to row 10. On what row would you expect the cursor to restore? On the early DEC terminals, the cursor would be restored to its original position (row 5), which is now 5 rows above the top margin. This is not a legal position when origin mode is enabled, and if you requested the coordinates with a `DSR-CPR` query, you'd get a nonsense result with random characters representing the negative coordinates. Up to now we've avoided this bug by clamping the coordinates within the margin boundaries, but the way DEC ultimately addressed the issue was by using relative coordinates. So in the example above, the start row of 5 is offset 4 from the top margin, and thus the restored row becomes 14 (offset 4 from the new margin of 10). So I would like to propose we update our implementation to match this later DEC algorithm, since that seems to be the most correct. You can see a demonstration of how this was handled on a range of different DEC terminals in issue https://github.com/microsoft/terminal/issues/14876#issuecomment-1459325217. # Proposed technical implementation details (optional) This would actually be somewhat simpler than our current implementation. There's an extra step when saving the cursor to subtract the offset of the top margin (assuming the origin mode is set). But then when restoring the cursor, we can just pass the coordinates straight to the `CursorPosition` method without any additional adjustments (which are required in the current implementation).
claunia added the Product-ConhostIssue-BugIssue-TaskIn-PRArea-VTNeeds-Tag-Fix labels 2026-01-31 06:47:58 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#19583