CSI 18t "Report Size In Characters" not working. #18402

Closed
opened 2026-01-31 06:12:49 +00:00 by claunia · 14 comments
Owner

Originally created by @PitWD on GitHub (Sep 8, 2022).

Windows Terminal version

1.15.2282.0

Windows build number

10.0.19044.1889

Other Software

Own project.

Steps to reproduce

Start CMD or PS within Terminal.
Run app which activates VT-Modes for IN and OUT.
Send CSI 18 t to stdout.
Read (wait for) response on stdin.

Expected Behavior

A response from the Terminal a la:
CSI 'Decimal-Rows' ; 'Decimal-Columns' t

Actual Behavior

No response from the Terminal.
But i.e. sending CSI 6 n (Report Actual Cursor Position) results as expected in a response a la:
CSI 'Decimal-Row' ; 'Decimal-Column' R

Originally created by @PitWD on GitHub (Sep 8, 2022). ### Windows Terminal version 1.15.2282.0 ### Windows build number 10.0.19044.1889 ### Other Software Own project. ### Steps to reproduce Start CMD or PS within Terminal. Run app which activates VT-Modes for IN and OUT. Send **CSI 18 t** to stdout. Read (wait for) response on stdin. ### Expected Behavior A response from the Terminal a la: **CSI** 'Decimal-Rows' **;** 'Decimal-Columns' **t** ### Actual Behavior No response from the Terminal. But i.e. sending **CSI 6 n** (Report Actual Cursor Position) results as expected in a response a la: **CSI** 'Decimal-Row' **;** 'Decimal-Column' **R**
Author
Owner

@j4james commented on GitHub (Sep 8, 2022):

We just don't support any of the CSI t queries. I actually thought we already had an open issue for this, but I can't find it right now.

I should also say I'd recommend against relying on CSI t for querying the terminal dimensions if you're expecting your application to be widely used. There are quite a few terminals that don't support it, and DSR-CPR can serve the same purpose more reliably.

@j4james commented on GitHub (Sep 8, 2022): We just don't support any of the `CSI t` queries. I actually thought we already had an open issue for this, but I can't find it right now. I should also say I'd recommend against relying on `CSI t` for querying the terminal dimensions if you're expecting your application to be widely used. There are quite a few terminals that don't support it, and `DSR-CPR` can serve the same purpose more reliably.
Author
Owner

@PitWD commented on GitHub (Sep 8, 2022):

So, you mean that way:

  1. Save Actual CursorPos
  2. Place Cursor Outside Limits
  3. Read Resulted CursorPos ( CSI 6 n )
  4. Place Cursor Back To 1.

??

I couldn't find a Linux Terminal not supporting CSI t. On Monterey-Mac I only tested the "on board" terminal - working fine too.
Yes, the 4-steps method seems actually more cross-compatible - but just because of the MS-Terminal refuses CSI t - not because of one of the 10 most used Linix-Terminals or the OnBoard Mac-Terminal would struggle with CSI t.

@PitWD commented on GitHub (Sep 8, 2022): So, you mean that way: 1. Save Actual CursorPos 2. Place Cursor Outside Limits 3. Read Resulted CursorPos ( `CSI 6 n` ) 4. Place Cursor Back To 1. ?? I couldn't find a Linux Terminal not supporting `CSI t`. On Monterey-Mac I only tested the "on board" terminal - working fine too. Yes, the 4-steps method seems actually more cross-compatible - but just because of the MS-Terminal refuses `CSI t` - not because of one of the 10 most used Linix-Terminals or the OnBoard Mac-Terminal would struggle with `CSI t`.
Author
Owner

@j4james commented on GitHub (Sep 8, 2022):

So, you mean that way:

1. Save Actual CursorPos

2. Place Cursor Outside Limits

3. Read Resulted CursorPos ( `CSI 6 n` )

4. Place Cursor Back To 1.

You make it sound like it's a complicated serious of operations, but it's essentially just a longer escape sequence. Something like \e7\e[999;999H\e[6n\e8.

I couldn't find a Linux Terminal not supporting CSI t.

Admittedly I don't always have the latest version of every terminal, and it's been a while since I last tested these sequences, so maybe things have improved a lot since then. At the time I think there were a half dozen or so that didn't support CSI t, or produced invalid results. But if you're happy to rely on CSI t based on your own research, that's fine. I was just offering my opinion.

@j4james commented on GitHub (Sep 8, 2022): > So, you mean that way: > > 1. Save Actual CursorPos > > 2. Place Cursor Outside Limits > > 3. Read Resulted CursorPos ( `CSI 6 n` ) > > 4. Place Cursor Back To 1. You make it sound like it's a complicated serious of operations, but it's essentially just a longer escape sequence. Something like `\e7\e[999;999H\e[6n\e8`. > I couldn't find a Linux Terminal not supporting `CSI t`. Admittedly I don't always have the latest version of every terminal, and it's been a while since I last tested these sequences, so maybe things have improved a lot since then. At the time I think there were a half dozen or so that didn't support `CSI t`, or produced invalid results. But if you're happy to rely on `CSI t` based on your own research, that's fine. I was just offering my opinion.
Author
Owner

@PitWD commented on GitHub (Sep 8, 2022):

Uh, please do not misunderstand me.
I am really thankful for what MS is doing with the Terminal/VS-Code/WSL etc. I'm also impressed getting that fast an answer - and will follow your advice.
I'm on a MicroChip 2560... serial connected to Terminals. The whole TUI-Logic is running on the µC. Terminal is just a screen and a keyboard. In best case I do not even need a binary on the Terminal side to get serial redirected to stdio of a VT-Mode terminal.
So yes, on the µC I'm glad about every byte I can save... in code and on the serial line.
On the other side... there are some more issues where very small OS-specific binaries would make life much easier...

@PitWD commented on GitHub (Sep 8, 2022): Uh, please do not misunderstand me. I am really thankful for what MS is doing with the Terminal/VS-Code/WSL etc. I'm also impressed getting that fast an answer - and will follow your advice. I'm on a MicroChip 2560... serial connected to Terminals. The whole TUI-Logic is running on the µC. Terminal is just a screen and a keyboard. In best case I do not even need a binary on the Terminal side to get serial redirected to stdio of a VT-Mode terminal. So yes, on the µC I'm glad about every byte I can save... in code and on the serial line. On the other side... there are some more issues where very small OS-specific binaries would make life much easier...
Author
Owner

@zadjii-msft commented on GitHub (Sep 8, 2022):

I'll toss this on the backlog. No arguments that we should support it, even if there is a viable (albeit, verbose) alternative.

@zadjii-msft commented on GitHub (Sep 8, 2022): I'll toss this on the backlog. No arguments that we should support it, even if there is a viable (albeit, verbose) alternative.
Author
Owner

@PitWD commented on GitHub (Sep 8, 2022):

No arguments that we should support it

For me it looks much more logical to call a GetScreenSize-Function if I want to know the ScreenSize, than to call some functions to be able to use GetCursorPos as a substitute for GetScreenSize.

I have to set a flag NextCurserPosIsAScreenSize and have to check on each incoming CursorPos if it's not a ScreenSize...

That's in coding really not a thing - but on a 2560 it's 1 byte global RAM, ~8 additional cpu cycles per incoming CursorPos, and ~30 Bytes program memory.
I have to waste resources of the µC - cause 34% of Users want to administrate them with Windows.

CSI t commands do not conflict with anything - I also can't see why it wouldn't make sense to get the MS-Terminal (without cnflicting riscs) again one step closer to Xterm-compatibility...

@PitWD commented on GitHub (Sep 8, 2022): > No arguments that we should support it For me it looks much more logical to call a GetScreenSize-Function if I want to know the ScreenSize, than to call some functions to be able to use GetCursorPos as a substitute for GetScreenSize. I have to set a flag NextCurserPosIsAScreenSize and have to check on each incoming CursorPos if it's not a ScreenSize... That's in coding really not a thing - but on a 2560 it's 1 byte global RAM, ~8 additional cpu cycles per incoming CursorPos, and ~30 Bytes program memory. I have to waste resources of the µC - cause 34% of Users want to administrate them with Windows. `CSI t` commands do not conflict with anything - I also can't see why it wouldn't make sense to get the MS-Terminal (without cnflicting riscs) again one step closer to Xterm-compatibility...
Author
Owner

@zadjii-msft commented on GitHub (Sep 8, 2022):

Note

Walkthrough

Implementation would be fairly trivial.

  • Add a enum value to DispatchTypes::WindowManipulationType for ReportWindowSizeInCharacter
  • Add a handler for ReportWindowSizeInCharacter in AdaptDispatch::WindowManipulation
  • Do a _api.ReturnResponse(...); with a string formatted with the viewport dimensions.

I'll mark this up as a good first issue, cause the implementation should be pretty straightforward.

@zadjii-msft commented on GitHub (Sep 8, 2022): > **Note** > ## Walkthrough Implementation would be fairly trivial. * Add a enum value to `DispatchTypes::WindowManipulationType` for `ReportWindowSizeInCharacter` * Add a handler for `ReportWindowSizeInCharacter` in [`AdaptDispatch::WindowManipulation`](https://github.com/microsoft/terminal/blob/main/src/terminal/adapter/adaptDispatch.cpp#L2323) * Do a `_api.ReturnResponse(...);` with a string formatted with the viewport dimensions. I'll mark this up as a good first issue, cause the implementation should be pretty straightforward.
Author
Owner

@michalnpl commented on GitHub (Apr 28, 2023):

@zadjii-msft, @PitWD, @j4james I have a branch to support this ready for PR, but I am unsure about interoperability. My apprehension is about microsoft/terminal rendering escape characters when not read, which differs from Ubuntu (bash, xterm-256color). What's more, is that PowerShell and cmd.exe do render CSI 18t differently when not read (PowerShell does not render \033 while cmd.exe does render \033[8). Kindly please advise if this is the desired behavior.

For test code:

#include <stdio.h>

int main() {
    printf("\033[18t");
    return 0;
}

Ubuntu:
image

Terminal (both PowerShell and Conhost):
image

and for Ubuntu test code:

#include <stdio.h>
#include <unistd.h>
#include <termios.h>

int main() {
    struct termios old_termios, new_termios;
    tcgetattr(STDIN_FILENO, &old_termios);
    new_termios = old_termios;
    new_termios.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &new_termios);
    printf("\033[18t");
    int rows, cols;
    scanf("\033[8;%d;%dt", &rows, &cols);
    tcsetattr(STDIN_FILENO, TCSANOW, &old_termios);
    printf("Terminal size: %d columns x %d rows\n", cols, rows);
    return 0;
}

image

and for microsoft/terminal test code:

#include <stdio.h>
#include <windows.h>

int main() {
    HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
    DWORD prev_mode;
    GetConsoleMode(hConsole, &prev_mode);
    DWORD new_mode = prev_mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
    SetConsoleMode(hConsole, new_mode);
    printf("\033[18t");
    int rows, cols;
    scanf_s("\033[8;%d;%dt", &rows, &cols);
    SetConsoleMode(hConsole, prev_mode);
    printf("Terminal size: %d columns x %d rows\n", cols, rows);
    return 0;
}

image

Kindly please advise if this is the desired behavior.

@michalnpl commented on GitHub (Apr 28, 2023): @zadjii-msft, @PitWD, @j4james I have a branch to support this ready for **PR**, but I am unsure about interoperability. My apprehension is about **microsoft/terminal** rendering escape characters when not read, which differs from **Ubuntu** (bash, xterm-256color). What's more, is that **PowerShell** and **cmd.exe** do render **CSI 18t** differently when not read (PowerShell does not render **\033** while **cmd.exe** does render **\033[8**). Kindly please advise if this is the desired behavior. For test code: ``` #include <stdio.h> int main() { printf("\033[18t"); return 0; } ``` Ubuntu: ![image](https://user-images.githubusercontent.com/25628581/235257392-16f8069d-fe0f-4d8e-8b2c-c4278a8eed32.png) Terminal (both PowerShell and Conhost): ![image](https://user-images.githubusercontent.com/25628581/235257489-a0c99ec8-fb0c-45d3-bdba-ae8b49179e08.png) and for Ubuntu test code: ``` #include <stdio.h> #include <unistd.h> #include <termios.h> int main() { struct termios old_termios, new_termios; tcgetattr(STDIN_FILENO, &old_termios); new_termios = old_termios; new_termios.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &new_termios); printf("\033[18t"); int rows, cols; scanf("\033[8;%d;%dt", &rows, &cols); tcsetattr(STDIN_FILENO, TCSANOW, &old_termios); printf("Terminal size: %d columns x %d rows\n", cols, rows); return 0; } ``` ![image](https://user-images.githubusercontent.com/25628581/235257790-df78f703-4d0a-422d-a1d7-c68913c5d175.png) and for **microsoft/terminal** test code: ``` #include <stdio.h> #include <windows.h> int main() { HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE); DWORD prev_mode; GetConsoleMode(hConsole, &prev_mode); DWORD new_mode = prev_mode & ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); SetConsoleMode(hConsole, new_mode); printf("\033[18t"); int rows, cols; scanf_s("\033[8;%d;%dt", &rows, &cols); SetConsoleMode(hConsole, prev_mode); printf("Terminal size: %d columns x %d rows\n", cols, rows); return 0; } ``` ![image](https://user-images.githubusercontent.com/25628581/235257962-b3e811fb-f4e3-422d-a5f7-3ed12a23b645.png) Kindly please advise if this is the desired behavior.
Author
Owner

@zadjii-msft commented on GitHub (Apr 28, 2023):

Honestly that looks right to me. Every shell is gonna do something different with an escape character they didn't expect to read. I'm under the impression that if you're emitthing the sequence to query the terminal, you're also expected to read the response. There's other issues scattered around where like, vim will ask the terminal for something, then ssh dies, and now the terminal replies to a shell that wasn't expecting it, and you get the same effect.

@zadjii-msft commented on GitHub (Apr 28, 2023): Honestly that looks right to me. Every shell is gonna do something different with an escape character they didn't expect to read. I'm under the impression that if you're emitthing the sequence to query the terminal, you're also expected to read the response. There's other issues scattered around where like, vim will ask the terminal for something, then _ssh dies_, and now the terminal replies to a shell that wasn't expecting it, and you get the same effect.
Author
Owner

@michalnpl commented on GitHub (Apr 28, 2023):

@zadjii-msft cool, is it OK for me to propose PR for this one, then? BTW, should I write a TAEF test for this?

@michalnpl commented on GitHub (Apr 28, 2023): @zadjii-msft cool, is it OK for me to propose PR for this one, then? BTW, should I write a TAEF test for this?
Author
Owner

@zadjii-msft commented on GitHub (Apr 28, 2023):

Please do! I'd file the PR with or without tests (though, tests are always appreciated 😉) ScreenBufferTests.cpp, ConptyRoundtripTests.cpp, maybe adapterTests.cpp are all good places that would likely work for a test

@zadjii-msft commented on GitHub (Apr 28, 2023): Please do! I'd file the PR with or without tests (though, tests are always appreciated 😉) `ScreenBufferTests.cpp`, `ConptyRoundtripTests.cpp`, maybe `adapterTests.cpp` are all good places that would likely work for a test
Author
Owner

@michalnpl commented on GitHub (Apr 28, 2023):

I'll try to figure out the tests before I submit the PR.

@michalnpl commented on GitHub (Apr 28, 2023): I'll try to figure out the tests before I submit the PR.
Author
Owner

@j4james commented on GitHub (Apr 29, 2023):

@michalnpl I just want to note something regarding the dimensions that this sequence should be reporting. @zadjii-msft previously suggested you should be using the viewport dimensions, but I suspect that apps are more likely to expect the dimensions of the addressable cell range, which for us is determined by the buffer width combined with the viewport height. The viewport width can potentially be narrower than the buffer width, but that's a user-configurable UI constraint. The only thing an application should care about is the point at which the text will wrap, which is the buffer width.

@j4james commented on GitHub (Apr 29, 2023): @michalnpl I just want to note something regarding the dimensions that this sequence should be reporting. @zadjii-msft previously suggested you should be using the viewport dimensions, but I suspect that apps are more likely to expect the dimensions of the addressable cell range, which for us is determined by the *buffer* width combined with the *viewport* height. The viewport width can potentially be narrower than the buffer width, but that's a user-configurable UI constraint. The only thing an application should care about is the point at which the text will wrap, which is the buffer width.
Author
Owner

@michalnpl commented on GitHub (May 4, 2023):

@zadjii-msft , @j4james, my best effort

https://github.com/microsoft/terminal/pull/15295

couldn't figure out TAEF tests; if you can add it to PR, I would be in debt.

@michalnpl commented on GitHub (May 4, 2023): @zadjii-msft , @j4james, my best effort https://github.com/microsoft/terminal/pull/15295 couldn't figure out TAEF tests; if you can add it to PR, I would be in debt.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#18402