Repository navigation
Description
Notes from James Holderness (@j4james):
Note that this is a problem for all the VT resizing sequences too. For example, you'll get the same problem resizing the screen from within a bash shell like this:
printf "\e[8;10;10t"And if you want to make
modework, then you'll probably want to start with the VT sequences first, because ultimately that's how you're going to have to communicate this information to the Terminal.The real issue, though, is deciding how the Terminal should deal with a resize request. When you've got multiple tabs, each potentially requesting a different size, you can't satisfy all of them at once. I've been thinking about this for a while, and there were three approaches that I considered:
Ignore the size request, as we are doing now. But for this to work, it's vital that the Terminal communicate back to the host that the request has failed. If you don't do that, the Terminal and conhost get out of sync, and the renderer goes barmy..
Accept the requested size as a kind of virtual window, similar to the way conhost works when the buffer width and window width are different. If the virtual window is larger than the actual window, you'll need to be able to scroll across the viewport, both horizontally and vertically (the latter being kind of tricky to differentiate from the scrollback).
Accept the requested size and actually resize the whole Terminal window to fit, but only if the tab making the request is currently focused. A background tab shouldn't be able to change the size. And as with option 1, it's vital that the resulting sizes are communicated back to the different hosts for each tab.
Personally I'm in favor of option 3, but I suspect others will disagree, and it may need to be a configurable preference. It's also possible there are other better approaches that I haven't thought of.
Notes from Egmont Koblinger (@egmontkob):
On a more important note, I believe that this escape sequence with a fixed size is borderline problematic/harmful, whereas this one with the "maximized" value, and other nearby escape sequences, are straight harmful (just like when webpages that are allowed to move/resize the browser window – everyone hates that, right?) and terminals should deliberately refuse to implement.
Notes from Dustin L. Howett (MSFT) (@DHowett-MSFT):
We should choose one of the above options and stick to our guns.
More notes:
- option 4: Only allow a resize like this if there's a single pane. If there's two panes, we'll do the thing from option 1, and ignore it.
- We're probably gonna just go with option 4
- We'll add a
compatibility.allowWindowResizingdefaulted totrueto let people fully disable this - If there's multiple tabs, then inactive tabs won't notice the current tabs new size till they get focused (and the control is re-added to the UI tree).
- theoretically, one app could ask for 30x80 and another tab 45x120 and switching back and forth would keep resizing the window
- if a inactive tab gets a resize request... then we need to somehow mark that tab asked for a new size, and allow the resize, and resize the
Terminal& buffer, but only resize the window when it gets activated. - This probably needs to be handled as a core->control->app request, so the app can allow/reject
Activity
[-]Terminal: add support for Window Manipulation (CSI t, resize)[/-][+]Terminal: add support for Window Manipulation (CSI t, resize), or reject it explicitly (and force a client resize)[/+]jdebp commentedon Mar 24, 2020
It's worth noting that the problems don't arise with just 1 tab. With just 1 tab, you can resize the terminal GUI window willy-nilly as the resize events come down the pipe, and behave exactly as the prior console server's GUI windows did in response to size changes. It's what to do when there are 2 or more tabs, each wanting a different terminal size, that is the problem.
Looking to existing practice, Konsole has some noteworthy behaviour. The control sequence resizes the terminal exactly as requested.
sttyshows the requested number of rows and columns, and text wraps at the designated column. Size changes take effect even if this is not the active tab. The GUI window does not change when the active tab's size is changed, however. Things stay that way until the next time that the tab is switched back to from another tab, at which point the pseudo-terminal receives a resize event sizing it back to the size of the GUI window. If there is only 1 tab present this never happens, as the single tab is never switched away from and never switched back to.This is of course, to discuss resizing in the GUI front-end. The actual console screen buffer should definitely support resizing via control sequences, just as it supports resizing via
SetConsoleScreenBufferSize().How are you supporting sending along to the GUI front-ends changes made by
SetConsoleScreenBufferSize()andSetConsoleWindowInfo(), and changes to the window size made by the GUI front end? You've only provided one set of size information inResizePseudoConsole(), and appear to be treating that as the console screen buffer size. How are GUI terminal emulator applications to pass the other size through so that console I/O applications can see it?egmontkob commentedon Mar 24, 2020
If I had to make a guess, my guess would be that this behavior is not by design, just whatever happened to come out of the simplest implementation, using the UI libraries used by Konsole.
Let's take a step back. You don't have to support any kind of app-initiated resize. Let's just take a tabbed UI where whatever is inside the tab can query the dimensions at any time, as it's necessarily the case with terminals. There's already a nontrivial question: When should inactive terminals receive the resize event?
Immediately? That might be a waste of CPU time, both from the terminal and from the hosted apps, since you don't squash multiple resize events into one; and a waste of network traffic, if there's ssh involved. Especially if resizing isn't super fast (e.g. in VTE the time required to rewrap is proportional to the number of scrollback lines), doing it for multiple tabs at once might cause a noticeable lag. It also might trigger some apps to exit, if they don't support one of the intermediate (e.g. extremely small) size, or might cause bad display in cases that don't really like getting resized (shell prompts typically play badly with rewrap-on-resize).
Or when that tab is switched to? In that case switching is a weird experience, you don't immediately get to see the desired contents, but you see a resize dance, even including ssh latency if it's involved.
Or some more complex solution in between, e.g. resize when the mouse dragging the window border is released, or after a timeout?)
The same question goes to some other kinds of apps too, e.g. most notably web browsers. Do they resize the page (e.g. responsive layout) immediately, or when that tab is switched to? I wouldn't be surprised if the answer varied across browsers, or even within the same browser varied across OSes (graphical toolkits).
Now combine it with various resizing strategies across terminals (some force a grid, some don't), various tab switching experiences (some prefer to keep the pixel size, some prefer to keep the character size), various zooming experiences (some might zoom all tabs at once, some zoom each tab separately), and then let's even introduce app-initiated resizes. There are loads of possible behaviors to pick from, and it's really hard to tell which one is better.
SWB54 commentedon Apr 7, 2020
Would I be correct to assume that this issue also encompasses non-VT resizing? For example, the .NET API
Console.WindowWidth, which I believe maps (on Windows) to the Win32 APIsSetConsoleScreenBufferSize()andSetConsoleWindowInfo().If so, I am in favor of either option 2 or 3 (some version of honoring the request), but not 1 (ignoring it). I just ran into this issue today. I have a .NET Core console app that prints formatted tables with relatively long rows. If the console width is too narrow to display the table, I increase it via
Console.WindowWidth. This works in acmd.exewindow but not (yet) inside Windows Terminal.j4james commentedon Apr 8, 2020
I think that's the intention, yes (assuming it's decided that we do anything about this at all). The original bug report that prompted this issue was a Windows app using
SetConsoleScreenBufferSize(see issue #5079). I was just saying that we needed to fix the VT sequences first, because that's how the resizing information would be communicated to the Windows Terminal.luke1961 commentedon Apr 14, 2020
100% agreed. Fixing
printf("\x1b[8;%d;%dt", nY, nX);is critical to address app-initiated resizing. This is very important to stay compatible with many apps that just count on running with a specific number of rows and columns. Some of these apps are usually configured to be launched from a batch batch file which includes amode con lines=rrr cols=cccstatement to ensure proper buffer size. Of course themodestatement results in the escape sentence listed above sent to the Terminal.alexrp commentedon Oct 11, 2020
Has any sort of decision been made on this yet?
For what it's worth, I'm for option 3.
I find the comparison to web browsers rather unconvincing. Running applications in a terminal is not the same thing as the arbitrary JavaScript code we encounter on the (probably) 100s of unique web pages we casually visit every day. We all sort of get that the web is a bit of a wild west kind of deal, but command line ecosystems are rarely (if ever) that. We generally know what we're doing when we run things in a terminal.
pjfarleyiii commentedon Dec 29, 2020
I am the author of #8673 which was closed as a duplicate of this issue. I understand the discussion here concerning the intricacies of what other tabs in Terminal do / see and when, but my interest is from the POV of a simple text-based application that wants to ensure an appropriate terminal height and width (in characters) depending on startup options specified by the application user.
In the old CMD.EXE console (which is not tabbed) I can just print the "CSI 8; lines; cols t" sequence and have the window resize immediately. If you can provide that support more quickly for only the "single tab open" case my needs would be satisfied.
Can a single-tab-only solution be considered for more rapid update as an intermediate step pending multi-tab design and implementation solution(s)?
Regards,
Peter
P.S. -- Whatever the mechanism, WSL screens (which I was given to understand are using MS Terminal) DO respond to the "CSI 8; lines; cols t" sequence and immediately resize the WSL console window. Tested with Ubuntu 20.04LTS and Debian 10 WSL instances.
22 remaining items
Handle window resize event (CSI t, resize) (#17721)
BDisp commentedon Nov 1, 2024
In Windows Terminal Preview version 1.22.2912.0 it is no longer possible to resize the buffer. In version 1.21.2911.0 it is working fine with buffer resizing.
lhecker commentedon Nov 4, 2024
BDisp (@BDisp) I don't remember CSI t being supported in either 1.21 or 1.22.
Reading through the linked gui-cs PR I can see that there are various issues with 1.22 being discussed, but I don't fully understand it, as I'm unfamiliar with gui-cs. So, could you please be more specific what's broken and how to reproduce it? I'd be happy to help. 🙂
If it's unrelated with CSI t though, please consider creating a new issue. Just some repro steps and perhaps a screenshot or two should already be sufficient (although it's of course always helpful if you can provide even more information).
Edit: I should mention that the issues you're experiencing are extremely likely due to our new ConPTY implementation (the translation layer between console APIs and VT). That's one of the major new features in 1.22.
BDisp commentedon Nov 4, 2024
Thanks for your attention Leonard Hecker (@lhecker). On Windows 11 using Win32 API, like the
SetConsoleScreenBufferInfoExor even usingCSI tI cannot now resize the screen buffer and it remain greater than the terminal window size. Thus allow the user to scroll using the scroll bar which we don't want for not let the user see corrupted buffer. If is there an alternative to change the buffer size to the same window size I would appreciate any information, thanks.lhecker commentedon Nov 4, 2024
Are you by any chance looking for something like the "alternate screen buffer"? You can enter it by emitting
\x1b[?1049hand exit it by emitting\x1b[?1049l. All versions of Windows that are still officially supported support that sequence.BDisp commentedon Nov 4, 2024
Yes that is done on enter and exit. But during the execution resize the window isn't resizing the buffer size using the Win32 API. I also tried with the escape sequence but also without success.
Here is a screenshot. Maximize the window and restore doesn't not set anymore the buffer size with the same size of the window:
BDisp commentedon Nov 4, 2024
Only to remember that in the WT version 1.21 the resize is working well. Only in the 1.22 (Preview) version this issue is happening.
lhecker commentedon Nov 4, 2024
We should continue this discussion in another issue, since there are over 20 people subscribed to this one. Do you mind filing an issue? It would be great if you could include reproduction steps.
BTW: I'm also confused why you mention the need to resize the buffer. The terminal resizes the buffer for you when the window size changes. There should be no need for you to call anything (nor use CSI t) during a maximize/restore. The alternate screen buffer always has the size of the window.
ClaireCJS commentedon Nov 5, 2024
You know.. I read the entire VT100 manual and hand-tried every single feasible one in the manual. I don't think I remember that one but maybe I just didn't understand it at the time.
Jibun-no-Kage commentedon Nov 5, 2024
Check the VT220 Manual. There were a lot, literally a lot of changes between VT100 and VT220 standards. I want to say, if memory services, it was in the VT220 standard that buffering options were enhanced.
ClaireCJS commentedon Nov 5, 2024
I guess every good story has its sequel 🤣 I'll have to do that, thanks for the recommendation!
Joachim-Otahal commentedon Jun 16, 2025
Just subscribing since I cannot use the new Terminal just because of this.
A simple mode con cols=50 fails... Or a simple
$host.UI.RawUI.BufferSize = @{Width=50;Height=$Host.UI.RawUI.BufferSize.Height}
$host.UI.RawUI.WindowSize = @{Width=50;Height=$Host.UI.RawUI.WindowSize.Height}
OZ1 commentedon Sep 14, 2025
After 5 years, the Console.SetWindowSize(117, 7) still doesn't work.
fix: leave Windows Terminal's window alone instead of sizing it