Support for XTSAVE and XTRESTORE or DECRQM #13863

Open
opened 2026-01-31 03:54:17 +00:00 by claunia · 5 comments
Owner

Originally created by @coezbek on GitHub (May 22, 2021).

Description of the new feature/enhancement

With the introduction of bracketed paste mode it is now possible to handle pasting when announcing support via DECSET 2004 (see https://github.com/microsoft/terminal/issues/395), which is great! As a terminal-based user interface application the question now arises how to know which value to restore at the end of the application. This is usually done by using XTSAVE prior to setting bracketed paste mode and then calling XTRESTORE before closing the application or by querying the state of bracketed paste mode via DECRQM (as far as I understand).

Why is this important? Imagine the following:

  • Initially Bracketed Paste Mode is Off
  • One application is started which supports it and enables it
  • At the end of the application the application does not know if bracketed paste was on or off before the application started, so it opts to leave it enabled.
  • If the user next starts an application does not support bracketed paste, then the user will start seeing escape sequences \x1b[200~ etc when pasting.

Please add support for either method, so we can leave bracketed paste mode in the same state as it was before the application was started.

Proposed technical implementation details (optional)

XTSAVE and XTRESTORE need to keep a stack of values for the given CSI and either push the current value on the stack or restore the value from the stack and pop.

Originally created by @coezbek on GitHub (May 22, 2021). # Description of the new feature/enhancement With the introduction of bracketed paste mode it is now possible to handle pasting when announcing support via DECSET 2004 (see https://github.com/microsoft/terminal/issues/395), which is great! As a terminal-based user interface application the question now arises how to know which value to restore at the end of the application. This is usually done by using XTSAVE prior to setting bracketed paste mode and then calling XTRESTORE before closing the application or by querying the state of bracketed paste mode via DECRQM (as far as I understand). Why is this important? Imagine the following: - Initially Bracketed Paste Mode is Off - One application is started which supports it and enables it - At the end of the application the application does not know if bracketed paste was on or off before the application started, so it opts to leave it enabled. - If the user next starts an application does not support bracketed paste, then the user will start seeing escape sequences `\x1b[200~` etc when pasting. Please add support for either method, so we can leave bracketed paste mode in the same state as it was before the application was started. # Proposed technical implementation details (optional) XTSAVE and XTRESTORE need to keep a stack of values for the given CSI and either push the current value on the stack or restore the value from the stack and pop.
claunia added the Help WantedProduct-ConhostIssue-TaskArea-VTProduct-Terminal labels 2026-01-31 03:54:18 +00:00
Author
Owner

@j4james commented on GitHub (May 22, 2021):

I'd prefer we didn't implement XTSAVE and XTRESTORE, but DECRQM is definitely on my todo list. Ideally I would like us to clean up the various mode methods in the ConGetSet interface first (as I mentioned in #3849). We don't currently have a way to query modes, and I'd prefer that didn't require dozens of additional GetModeXXX methods.

@j4james commented on GitHub (May 22, 2021): I'd prefer we didn't implement `XTSAVE` and `XTRESTORE`, but `DECRQM` is definitely on my todo list. Ideally I would like us to clean up the various mode methods in the `ConGetSet` interface first (as I mentioned in #3849). We don't currently have a way to query modes, and I'd prefer that didn't require dozens of additional `GetModeXXX` methods.
Author
Owner

@DHowett commented on GitHub (May 25, 2021):

So, I'm of two minds on this. It's really useful to generally know the state of the terminal, but it seems like the generally-accepted practice is that an application asserts the states that it needs before it needs them. Shells that support bracketed paste re-emit DECSET 2004 before every prompt, and DECRST before every invocation; applications that want DECCKM likewise turn it on/off when they want it.

This "revert to the default state" behavior generally works, apart from when an application is terminated unceremoniously. Is it more worth it to add a back-and-forth exchange (including over links of unknown latency?) between application and terminal emulator, or to simply allow for some minor breakage¹ when an app or shell doesn't behave as it should?

¹ and of course, in the case of OSS projects, request remediation 😄

@DHowett commented on GitHub (May 25, 2021): So, I'm of two minds on this. It's really useful to generally know the state of the terminal, but it seems like the generally-accepted practice is that an application asserts the states that it needs before it needs them. Shells that support bracketed paste re-emit DECSET 2004 before every prompt, and DECRST before every invocation; applications that want DECCKM likewise turn it on/off when they want it. This "revert to the default state" behavior generally works, apart from when an application is terminated unceremoniously. Is it more worth it to add a back-and-forth exchange (including over links of unknown latency?) between application and terminal emulator, or to simply allow for some minor breakage¹ when an app or shell doesn't behave as it should? ¹ and of course, in the case of OSS projects, request remediation :smile:
Author
Owner

@DHowett commented on GitHub (May 25, 2021):

This is really similar to the discussions around XT{PUSH,POP}SGR: whether an application should be granted the existence of an SGR stack, or whether it is safe to assume that the terminal is left in a reasonable state even if that means sticking our heads in the sand. \_(shrug)_/

@DHowett commented on GitHub (May 25, 2021): This is really similar to the discussions around `XT{PUSH,POP}SGR`: whether an application should be granted the existence of an SGR stack, or whether it is safe to assume that the terminal is left in a reasonable state _even if that means sticking our heads in the sand_. `\_(shrug)_/`
Author
Owner

@coezbek commented on GitHub (May 25, 2021):

This "revert to the default state" behavior generally works,

Yes, if this is really the state of things then this is of course fine. I understand that adding state management is a big drag. I was hoping that it wouldn't be too hard to at least to provide the DECRQM for any command that is supported anyway.

I am just dabbling into VT100 and it is a bit confusing to figure out what is implicit and not in the spec or not implemented. I would have thought that querying capabilities, getting state and set/restore would be features implemented in general.

@coezbek commented on GitHub (May 25, 2021): > This "revert to the default state" behavior generally works, Yes, if this is really the state of things then this is of course fine. I understand that adding state management is a big drag. I was hoping that it wouldn't be too hard to at least to provide the `DECRQM` for any command that is supported anyway. I am just dabbling into VT100 and it is a bit confusing to figure out what is implicit and not in the spec or not implemented. I would have thought that querying capabilities, getting state and set/restore would be features implemented in general.
Author
Owner

@j4james commented on GitHub (May 25, 2021):

This is really similar to the discussions around XT{PUSH,POP}SGR:

Yeah, this is one of the reasons I'm opposed to those sequences. They have all the same flaws. Also the XTRESTORE sequence conflicts with the DECPCTERM sequence, which I would actually like us to support one day.

DECRQM solves the problem of restoring state in a far more sane way in my opinion. And it's also extremely useful for feature detection. For example, if you want to detect if a terminal supports mouse modes, synchronized updates, or even our Win32 input mode, you can query all of those things with DECRQM.

DECRQSS serves a similar purpose. It's a both a better way to restore SGR state than XT{PUSH,POP}SGR, and also provides a way for applications to feature-detect things like cursor styles and all those fancy extended SGR attributes that modern apps want to use.

And with a decent level of support for feature detection, we have a better argument for not reporting version information.

@j4james commented on GitHub (May 25, 2021): > This is really similar to the discussions around `XT{PUSH,POP}SGR`: Yeah, this is one of the reasons I'm opposed to those sequences. They have all the same flaws. Also the `XTRESTORE` sequence conflicts with the `DECPCTERM` sequence, which I would actually like us to support one day. `DECRQM` solves the problem of restoring state in a far more sane way in my opinion. And it's also extremely useful for feature detection. For example, if you want to detect if a terminal supports mouse modes, synchronized updates, or even our Win32 input mode, you can query all of those things with `DECRQM`. `DECRQSS` serves a similar purpose. It's a both a better way to restore `SGR` state than `XT{PUSH,POP}SGR`, and also provides a way for applications to feature-detect things like cursor styles and all those fancy extended `SGR` attributes that modern apps want to use. And with a decent level of support for feature detection, we have a better argument for not reporting version information.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#13863