-
Notifications
You must be signed in to change notification settings - Fork 146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support disabling option "wrap text output on resize" #546
Comments
In recent years, Windows added built-in support for ANSI escape codes. The implementation of ANSI escape code support considers the "terminal display" to be only the part that is visible. I.e. if there's a horizontal scrollbar, then the ANSI escape codes for positioning the cursor are unable to position the cursor past (any of) the edges of the visible area of the terminal display. The OS API Workaround: If you run I'll take a look at detecting when the Window width is different from the Screen Buffer width, and maybe in that case always use only the deprecated console APIs for cursor positioning, instead of ANSI escape codes. P.S. The issue isn't exactly about "Wrap text output on resize". The issue occurs when "Width:" is set differently for "Screen Buffer Size" versus "Window Size". Turning off "Wrap text output on resize" is the easiest way to cause that. But there are other ways as well. For example, the following program code demonstrates another way for the widths to become different from each other. #include <stdio.h>
#include <windows.h>
int _cdecl main(int argc, char const** argv)
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hOut, &csbi);
csbi.srWindow.Right -= 4;
SetConsoleWindowInfo(hOut, true, &csbi.srWindow);
} |
I'm sorry. It's a limitation of how Windows has implemented its terminal support. Workaround:At this time, my best recommendation is that to be able to have a horizontal scrollbar in the terminal, it's necessary to run However, the visible window area is going to jitter around (i.e. the cursor position should always be visible, but position of the horizontal scrollbar will jitter around and may position itself in undesirable ways). Notes:
More Details:The current implementation of ANSI escape code support in Windows makes it essentially impossible for apps to use ANSI escape codes safely/properly if the Window Width is different from the Screen Buffer Width (i.e. when there's a horizontal scrollbar). I can avoid using escape codes for cursor positioning (and shifting characters right/left). But regardless the OS forcibly adjusts the horizontal scrollbar position. And for example, the escape codes to "clear to the end of the line" only clear the part that's visible -- everything to the left or right of the current horizontal scrollbar position does not get cleared (so, scrolling horizontally reveals that there's leftover text in the display; the display is effectively garbled). So it ends up being necessary to avoid any ANSI escape codes other than for colors. And that forces the display to jitter around. In my opinion, the best way to solve this would be for the OS implementation of ANSI escape code support to apply to the combination of the Window Height and the Screen Buffer Width. But they currently apply to the Window Width instead, which ruins the ability for an app to accommodate a horizontal scrollbar in the terminal. I think part of the reason for this oversight is likely that the new Windows Terminal doesn't support a horizontal scrollbar (just like mintty doesn't support a horizontal scrollbar). In the meantime, there's nothing an app can do about it, except to build their own custom terminal emulation layer. But even then the OS automatically adjusts the horizontal scrollbar and there will be a lot of flicker while an app fights with the OS about the Window area and the cursor position. Even when Clink's terminal emulation is enabled, Clink currently does not fight with the OS about the Window area position. At some point in the future, I may look into the possibility of making Clink fight with the OS, but that would create even more jitter. |
(Marked as "external" because there's no way for Clink to properly overcome the OS limitation.) |
I've made changes to hack around the OS limitation. It's jittery, though, as expected. Also, the I'm pretty sure the problems are an oversight in the escape code implementations in the OS, as there's no way to be compatible with Linux programs the way it currently stands, and the main purpose of adding escape code support was to enable Linux compatibility. There's only so much I can do to work around the various problems, but at least it will sort of work in the meantime while waiting for OS fixes. |
See #546. When "Wrap text output on resize" is unchecked (or when Window Width != Screen Buffer Width) then escape codes for cursor positioning and insert/delete characters and clearing text and etc only affect the part of the terminal display that's within the visible area (the CONSOLE_SCREEN_BUFFER_INFO::srWindow area). That results in jitter and some text getting displayed inaccurately. There's only so much Clink can do to compensate for the problem, but this change tries to mitigate it as much as possible. However, the visible area jitters around. There's nothing Clink can do about that; the behavior is built into the OS console APIs.
Unfortunately, the changes I made only work around issues when printing the prompt and printing the input line. But there are many other places in Readline and Clink that also run into problems because escape codes are restricted to only affect the visible window (per horizontal scrollbar position). I'm not interested in investing further on rewriting Readline and Clink display code to work around OS limitations on escape code support (i.e. stop using escape codes). It's a big and costly exercise, with too much risk for breakages, the console APIs are being actively deprecated in favor of using escape codes, and no matter what Clink does it can never solve the jitter problems. And Windows Terminal doesn't support horizontal scrollbars, and is working on deprecating the legacy conhost terminal anyway. I'm sorry. I agree that the situation is unfortunate, but it's an external issue and Clink can't by itself solve the problems. So, the only options are either don't use a horizontal scrollbar, or run |
When v1.6.2 is published it will include the commit that should work around the visible window positioning issues; i.e. it should work, but there will be jitter (and there might be edge cases that turn up and need further tweaks). The good news is, I pm'd with some of the WT team members and they agree that the escape code support should use Screen Buffer Width not Window Width. I'll open an issue in the WT repo (it contains the source code for the escape code support in Windows, even for the legacy conhost terminal window). It looks to me like it probably won't be a simple/quick fix, and I don't know what the priority level will be, so it might take a while but a fix should come. |
I just tested on a different computer with clink v1.6.1 on Windows 11 (10.0.22621.3007). There it seems to work with terminal.emulation set to |
The previous tests with the screenshots was on Windows 10 (10.0.19045.3930) |
@ahauan4 that's interesting follow-up info about Win10 vs Win11, and about native vs emulate on Win11. Over the weekend I had a chance to test the change I made on Win10 with native and emulate, and on Win11 with native and emulate: On Win11 it seems to work properly in both native and emulate, with my changes (which aren't published yet). Except that on Win10 there's noticeable jitter of the visible area. Once the change is published, please let me know if there are still problems. I may not be able to compensate further, but it will be good to have a record of what is/isn't working. Thanks! |
v1.6.2 has been published with the changes to compensate for the escape code limitations in Win10. |
Very big Thanks to you! |
I'm used to have the "wrap text output on resize" option disabled for cmd.exe in Windows 10/11.
If the command line text is shorter than the window width, everything works fine:
But if the window gets resized shorter than the command line and then POS1 and END is pressed, the cursor does not jump to the end of the line (and the scrollbar not to the right) but instead the cursor jumps to the end of the visible line:
If I then try to add some new text to the end, the resulting command line text gets messed up.
Here how it looks like after making the window wide enough and pressing END:
With "wrap text output on resize" enabled (default), everything works fine.
Am I doing something wrong or is disabling "wrap text output on resize" not supported by clink?
The text was updated successfully, but these errors were encountered: