[PR #3160] [MERGED] Improve the DECSC/DECRC implementation #25260

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

📋 Pull Request Information

Original PR: https://github.com/microsoft/terminal/pull/3160
Author: @j4james
Created: 10/11/2019
Status: Merged
Merged: 11/5/2019
Merged by: @DHowett-MSFT

Base: masterHead: fix-decsc


📝 Commits (8)

  • 0355353 Add private APIs for getting and setting the full attributes of the active screen buffer.
  • d8cbb39 Extend the DECSC/DECRC commands so they also save and restore the current text attributes and active character set.
  • 3cc198f Track the saved cursor state for the alt buffer separately from the main buffer, and save or restore the state when switching buffers.
  • 95596f9 Make sure the restored cursor position is within the bounds of the scrolling region if the origin mode is relative.
  • ca99f94 Add screen buffer tests to verify the cursor save/restore behaviour.
  • eae841d Forgot to initialize the usingAltBuffer property.
  • 522b60e Rename the save/restore dispatch methods to better represent their new behaviour.
  • 5bc16a2 Improve comments.

📊 Changes

11 files changed (+258 additions, -39 deletions)

View changed files

📝 src/host/outputStream.cpp (+25 -0)
📝 src/host/outputStream.hpp (+2 -0)
📝 src/host/ut_host/ScreenBufferTests.cpp (+121 -1)
📝 src/terminal/adapter/ITermDispatch.hpp (+2 -2)
📝 src/terminal/adapter/adaptDispatch.cpp (+64 -21)
📝 src/terminal/adapter/adaptDispatch.hpp (+18 -4)
📝 src/terminal/adapter/conGetSet.hpp (+3 -0)
📝 src/terminal/adapter/termDispatch.hpp (+2 -2)
📝 src/terminal/adapter/ut_adapter/adapterTest.cpp (+15 -3)
📝 src/terminal/parser/OutputStateMachineEngine.cpp (+4 -4)
📝 src/terminal/parser/ut_parser/OutputEngineTest.cpp (+2 -2)

📄 Description

Summary of the Pull Request

The current DECSC implementation only saves the cursor position and origin mode. This PR improves that functionality with additional support for saving the SGR attributes, as well as the active character set.

It also fixes the way the saved state interacts with the alt buffer (private mode 1049), triggering a save when switching to the alt buffer, and a restore when switching back, and tracking the alt buffer state independently from the main state.

PR Checklist

  • Closes Inconsistent Color in Bash on Ubuntu on Windows (#148)
  • CLA signed. If not, go over here and sign the CLA
  • Tests added/passed
  • Requires documentation to be updated
  • I've not discussed this with core contributors already. I'm ready to accept this work might be rejected in favor of a different grand plan.

Detailed Description of the Pull Request / Additional comments

In order to properly save and restore the SGR attributes, we first needed to add a pair of APIs in the ConGetSet interface which could round-trip the attributes with full 32-bit colors (the existing methods only work with legacy attributes).

I then added a struct in the AdaptDispatch implementation to make it easier to manage all of the parameters that needed to be saved. This includes the cursor position and origin mode that we were already tracking, and now also the SGR text attributes and the active character set (via the TermOutput class).

Two instances of this structure are required, since changes made to the saved state in the alt buffer need to be tracked separately from changes in the main buffer. I've added a boolean property that specifies whether we're in the alt buffer or not, and use that to decide which of the two instances we're working with.

I also needed to explicitly trigger a save when switching to the alt buffer, and a restore when switching back, since we weren't already doing that (the existing implementation gave the impression that the state was saved, because each buffer has its own cursor position, but that doesn't properly match the XTerm behaviour).

For the state tracking itself, we've now got two additional properties - the SGR attributes, which we obtain via the new private API, and the active character set, which we get from a local AdaptDispatch field. I'm saving the whole TermOutput class for the character set, since I'm hoping that will make it automatically supports future enhancements.

When restoring the cursor position, there is also now a fix to handle the relative origin mode correctly. If the margins are changed between the position being saved and restored, it's possible for the cursor to end up outside of the new margins, which would be illegal. So there is now an additional step that clamps the Y coordinate within the margin boundaries if the origin mode is relative.

Validation Steps Performed

I've added a couple of screen buffer tests which check that the various parameters are saved and restored as expected, as well as checking that the Y coordinate is clamped appropriately when the relative origin mode is set.

I've also tested manually with Vttest and confirmed that the SAVE/RESTORE CURSOR test (the last page of the Test of screen features)) is now working a lot better than it used to.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/microsoft/terminal/pull/3160 **Author:** [@j4james](https://github.com/j4james) **Created:** 10/11/2019 **Status:** ✅ Merged **Merged:** 11/5/2019 **Merged by:** [@DHowett-MSFT](https://github.com/DHowett-MSFT) **Base:** `master` ← **Head:** `fix-decsc` --- ### 📝 Commits (8) - [`0355353`](https://github.com/microsoft/terminal/commit/035535331b27d9821623b0fb7900afa015e11b4c) Add private APIs for getting and setting the full attributes of the active screen buffer. - [`d8cbb39`](https://github.com/microsoft/terminal/commit/d8cbb39c504c8bb88aed481e3cda7e486e0b698a) Extend the DECSC/DECRC commands so they also save and restore the current text attributes and active character set. - [`3cc198f`](https://github.com/microsoft/terminal/commit/3cc198f706f6acd1ca459713f3b2326793fb3a00) Track the saved cursor state for the alt buffer separately from the main buffer, and save or restore the state when switching buffers. - [`95596f9`](https://github.com/microsoft/terminal/commit/95596f95d149cd732bebe59f46b5f07662f00d5e) Make sure the restored cursor position is within the bounds of the scrolling region if the origin mode is relative. - [`ca99f94`](https://github.com/microsoft/terminal/commit/ca99f9409d835613d4c1121c697796ced8b065ec) Add screen buffer tests to verify the cursor save/restore behaviour. - [`eae841d`](https://github.com/microsoft/terminal/commit/eae841dc9f5da19bc6232dfea02dcd070e0fb9a1) Forgot to initialize the usingAltBuffer property. - [`522b60e`](https://github.com/microsoft/terminal/commit/522b60e3427909959da255b0d0a5ebc7b53851c7) Rename the save/restore dispatch methods to better represent their new behaviour. - [`5bc16a2`](https://github.com/microsoft/terminal/commit/5bc16a28623e08fe8d43a051efc27c29182cdf10) Improve comments. ### 📊 Changes **11 files changed** (+258 additions, -39 deletions) <details> <summary>View changed files</summary> 📝 `src/host/outputStream.cpp` (+25 -0) 📝 `src/host/outputStream.hpp` (+2 -0) 📝 `src/host/ut_host/ScreenBufferTests.cpp` (+121 -1) 📝 `src/terminal/adapter/ITermDispatch.hpp` (+2 -2) 📝 `src/terminal/adapter/adaptDispatch.cpp` (+64 -21) 📝 `src/terminal/adapter/adaptDispatch.hpp` (+18 -4) 📝 `src/terminal/adapter/conGetSet.hpp` (+3 -0) 📝 `src/terminal/adapter/termDispatch.hpp` (+2 -2) 📝 `src/terminal/adapter/ut_adapter/adapterTest.cpp` (+15 -3) 📝 `src/terminal/parser/OutputStateMachineEngine.cpp` (+4 -4) 📝 `src/terminal/parser/ut_parser/OutputEngineTest.cpp` (+2 -2) </details> ### 📄 Description ## Summary of the Pull Request The current [DECSC](https://www.vt100.net/docs/vt510-rm/DECSC.html) implementation only saves the cursor position and origin mode. This PR improves that functionality with additional support for saving the SGR attributes, as well as the active character set. It also fixes the way the saved state interacts with the alt buffer (private mode 1049), triggering a save when switching to the alt buffer, and a restore when switching back, and tracking the alt buffer state independently from the main state. ## PR Checklist * [x] Closes #148 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] Tests added/passed * [ ] Requires documentation to be updated * [ ] I've not discussed this with core contributors already. I'm ready to accept this work might be rejected in favor of a different grand plan. ## Detailed Description of the Pull Request / Additional comments In order to properly save and restore the SGR attributes, we first needed to add a pair of APIs in the `ConGetSet` interface which could round-trip the attributes with full 32-bit colors (the existing methods only work with legacy attributes). I then added a struct in the `AdaptDispatch` implementation to make it easier to manage all of the parameters that needed to be saved. This includes the cursor position and origin mode that we were already tracking, and now also the SGR text attributes and the active character set (via the `TermOutput` class). Two instances of this structure are required, since changes made to the saved state in the alt buffer need to be tracked separately from changes in the main buffer. I've added a boolean property that specifies whether we're in the alt buffer or not, and use that to decide which of the two instances we're working with. I also needed to explicitly trigger a save when switching to the alt buffer, and a restore when switching back, since we weren't already doing that (the existing implementation gave the impression that the state was saved, because each buffer has its own cursor position, but that doesn't properly match the XTerm behaviour). For the state tracking itself, we've now got two additional properties - the SGR attributes, which we obtain via the new private API, and the active character set, which we get from a local `AdaptDispatch` field. I'm saving the whole `TermOutput` class for the character set, since I'm hoping that will make it automatically supports future enhancements. When restoring the cursor position, there is also now a fix to handle the relative origin mode correctly. If the margins are changed between the position being saved and restored, it's possible for the cursor to end up outside of the new margins, which would be illegal. So there is now an additional step that clamps the Y coordinate within the margin boundaries if the origin mode is relative. ## Validation Steps Performed I've added a couple of screen buffer tests which check that the various parameters are saved and restored as expected, as well as checking that the Y coordinate is clamped appropriately when the relative origin mode is set. I've also tested manually with [Vttest](https://invisible-island.net/vttest/) and confirmed that the _SAVE/RESTORE CURSOR_ test (the last page of the _Test of screen features_)) is now working a lot better than it used to. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-31 09:08:22 +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#25260