After reading through the blog post and relevant MSDN pages, I didn't find a way for a modern Windows console app to detect when its output console gets resized. On Unix we have SIGWINCH, but on Windows we only have ReadConsoleInput and WINDOW_BUFFER_SIZE_EVENT, which seems awkward when used alongside simple stdin reading (will they fight for normal input events?).
Can someone share some light on this situation?
Thanks.
There's also GetConsoleScreenBufferInfo which will tell you dimensions, but it's obviously done by polling. You could also poll with an ANSI sequence - there are some half-baked tricks like moving the cursor way off screen - beyond any reasonable window size, then reading the actual position of the cursor afterwards. Example with WSL:
oisin@laptop$ echo -e "\e[999;999H"; echo -e "\e[6n"; echo ""
^[[47;1R;oisin@laptop$
The CR killed the horizontal position reporting interactively, but at least you can see my window is 47 rows high. Again, this would need to be polled but at least it's somewhat cross platform. Other techniques I've seen on other platforms (osx,linux) is either shelling out to stty to get info, or more commonly, with an ioctl call to TIOCGWINSZ.
Unfortunately, the only SIGWINCH equivalent on Windows is, as you've noted, using ReadConsoleInput for reading the input from the console and looking for WINDOW_BUFFER_SIZE_EVENTs. It's really not great, but if your app is dependent upon the size of the viewport, then that's the only way to do it :/
Well, thanks for the clarification. The situation feels kind of disappointing, though. It's hard to qualify a console system as "VT-speaking" when it can't get SIGWINCH right without making clients "un-speak" VT. Polling is not really a solution if one needs to forward SIGWINCH or port something that relies on it.
If all other console input types are converted anyway, maybe we can just do a simple hack and PostMessageW something somewhere for WINDOW_BUFFER_SIZE_EVENT? Then we'll be able to listen to that in a separate thread and simulate SIGWINCH without disturbing stdin.
Unfortunately, the only SIGWINCH equivalent on Windows is, as you've noted, using
ReadConsoleInputfor reading the input from the console and looking forWINDOW_BUFFER_SIZE_EVENTs. It's really not great, but if your app is dependent upon the size of the viewport, then that's the only way to do it :/
@zadjii-msft Mike, I've been playing with this the last few days and noticed that using WINDOWS_BUFFER_SIZE_EVENT doesn't concern itself with the viewport at all; it only deals with the underlying buffer. Additionally, the buffer only ever gets increased in size, so when you resize the console window larger than the buffer, you get a resize event - which is actually defective in itself since it currently only seems to be reporting the vertical size/number of lines, and returning 1 for columns each time. - and you never get a resize event when you reduce the viewport. (running 18282)
I'm gonna go ahead and link in #281 here - that thread has WAY more information on basically the same topic.
In fact, we shout probably just commit to that thread being the master thread for all window WINDOW_BUFFER_SIZE_EVENT / SIGWINCH discussion.