ConPTY emits nothing to clear the right side when downsizing #12186

Closed
opened 2026-01-31 03:08:21 +00:00 by claunia · 5 comments
Owner

Originally created by @o-sdn-o on GitHub (Jan 25, 2021).

Environment

Windows build number: 10.0.19042.746
Windows Terminal version (if applicable):

Any other software: My own ConPTY-based terminal emulator

I am making my own terminal multiplexer using ConPTY.
ConPTY instances serve as consoles for multiplexer applications. The dimensions of these consoles can be changed by mouse. Each time the console is resized, the ConPTY instance is resized at the same time, which triggers it to redraw its buffer contents.

Using ConPTY in my own terminal emulator, it is impossible to know that visible lines should be truncated when the ConPTY is reduced in size. ConPTY emits nothing to clear the right side when downsizing.
May be related to #5800

Actual behavior

The picture below shows the multiplexer, where the ConPTY consoles are located on the left, and on the right is a window with the output of everything that ConPTY emits when redrawn (top part is raw text, bottom part is code points)

Console lines are doubled in case my built-in terminal wraps the lines by itself:

ConPTY with wrapping

In the case when my built-in terminal has horizontal scrolling enabled, the lines are simultaneously continued and wrapped (since ConPTY wraps lines):

ConPTY without wrapping

It looks like ConPTY does not take into account that the external buffer may be larger and there may be fragments left when the ConPTY is reduced in size.
A possible solution would be to add \e[m\e[K before \r\n at the end of each line to indicate that this is an explicit end of the line.

CSI Ps K Erase in Line (EL), VT100.

Originally created by @o-sdn-o on GitHub (Jan 25, 2021). <!-- 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 I ACKNOWLEDGE THE FOLLOWING BEFORE PROCEEDING: 1. If I delete this entire template and go my own path, the core team may close my issue without further explanation or engagement. 2. If I list multiple bugs/concerns in this one issue, the core team may close my issue without further explanation or engagement. 3. If I write an issue that has many duplicates, the core team may close my issue without further explanation or engagement (and without necessarily spending time to find the exact duplicate ID number). 4. If I leave the title incomplete when filing the issue, the core team may close my issue without further explanation or engagement. 5. If I file something completely blank in the body, the core team may close my issue without further explanation or engagement. All good? Then proceed! --> <!-- This bug tracker is monitored by Windows Terminal development team and other technical folks. **Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to Github issues**. Instead, send dumps/traces to secure@microsoft.com, referencing this GitHub issue. If this is an application crash, please also provide a Feedback Hub submission link so we can find your diagnostic data on the backend. Use the category "Apps > Windows Terminal (Preview)" and choose "Share My Feedback" after submission to get the link. Please use this form and describe your issue, concisely but precisely, with as much detail as possible. --> # Environment ```none Windows build number: 10.0.19042.746 Windows Terminal version (if applicable): Any other software: My own ConPTY-based terminal emulator ``` I am making my own terminal multiplexer using ConPTY. ConPTY instances serve as consoles for multiplexer applications. The dimensions of these consoles can be changed by mouse. Each time the console is resized, the ConPTY instance is resized at the same time, which triggers it to redraw its buffer contents. Using ConPTY in my own terminal emulator, it is impossible to know that visible lines should be truncated when the ConPTY is reduced in size. ConPTY emits nothing to clear the right side when downsizing. May be related to #5800 # Actual behavior The picture below shows the multiplexer, where the ConPTY consoles are located on the left, and on the right is a window with the output of everything that ConPTY emits when redrawn (top part is raw text, bottom part is code points) Console lines are doubled in case my built-in terminal wraps the lines by itself: ![ConPTY with wrapping](https://user-images.githubusercontent.com/11535558/105719118-c0fa2a80-5f43-11eb-8c81-d570d8e27d0f.gif) In the case when my built-in terminal has horizontal scrolling enabled, the lines are simultaneously continued and wrapped (since ConPTY wraps lines): ![ConPTY without wrapping](https://user-images.githubusercontent.com/11535558/105719160-cbb4bf80-5f43-11eb-8268-56eadb4fc39d.gif) It looks like ConPTY does not take into account that the external buffer may be larger and there may be fragments left when the ConPTY is reduced in size. A possible solution would be to add `\e[m\e[K` before `\r\n` at the end of each line to indicate that this is an explicit end of the line. [CSI Ps K Erase in Line (EL), VT100.](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_)
Author
Owner

@zadjii-msft commented on GitHub (Jan 25, 2021):

So, for the record, I've been through madness and back trying to get this just right. You might be interested in #4200, and the PRs and issues linked to that one. I have notes scattered throughout. Be aware, this way leads madness.

It looks like ConPTY does not take into account that the external buffer may be larger and there may be fragments left when the ConPTY is reduced in size.

If that's the end goal, then I think the best plan is to just not decrease the ConPTY size. ConPTY assumes that the end terminal buffer is exactly as large as conpty is. So make conpty exactly as large as you want your buffer. If you want to have your buffer be larger than the viewport, go for it. That's how I'm planning on addressing #1860.

Trying to keep external buffers in sync with the console buffer is really annoying, and there's not a good way to do it. The problem comes from the fact that there fundamentally is a buffer that conpty must maintain for the client apps to be able to query, but it must also keep that buffer in sync with the terminal emulator. Unfortunately, the emulator may resize itself while conpty is reacting to a previous resize attempt, and now conpty is trying to render into a space that's different dimensions. WT gets around this by manually telling conpty "I know what I'm doing, don't repaint on a resize", then manually reflowing the WT buffer exactly the same way conhost would.

So yeah, good luck 😄

@zadjii-msft commented on GitHub (Jan 25, 2021): So, for the record, I've been through madness and back trying to get this just right. You might be interested in #4200, and the PRs and issues linked to that one. I have notes scattered throughout. Be aware, this way leads madness. > It looks like ConPTY does not take into account that the external buffer may be larger and there may be fragments left when the ConPTY is reduced in size. If that's the end goal, then I think the best plan is to just not decrease the ConPTY size. ConPTY assumes that the end terminal buffer is exactly as large as conpty is. So make conpty _exactly as large as you want your buffer_. If you want to have your buffer be larger than the viewport, go for it. That's how I'm planning on addressing #1860. Trying to keep external buffers in sync with the console buffer is really annoying, and there's not a good way to do it. The problem comes from the fact that there fundamentally is a buffer that conpty must maintain for the client apps to be able to query, but it must also keep that buffer in sync with the terminal emulator. Unfortunately, the emulator may resize itself while conpty is reacting to a previous resize attempt, and now conpty is trying to render into a space that's different dimensions. WT gets around this by manually telling conpty "I know what I'm doing, don't repaint on a resize", then manually reflowing the WT buffer _exactly the same way conhost would_. So yeah, good luck 😄
Author
Owner

@o-sdn-o commented on GitHub (Jan 25, 2021):

So make conpty exactly as large as you want your buffer.

my problem is that I don't have a buffer per se, only strings, and the client can emit infinitely (uint32_t) long strings (and use horizontal scrolling or my own wrapping)

@o-sdn-o commented on GitHub (Jan 25, 2021): > So make conpty exactly as large as you want your buffer. my problem is that I don't have a buffer per se, only strings, and the client can emit infinitely (uint32_t) long strings (and use horizontal scrolling or my own wrapping)
Author
Owner

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

Right, but... having no bounded size is incompatible with terminal emulation. Even when you're hosting processes on Linux, they can request the size in both character cells and pixels with TIOCGWINSZ. There's a signal for the window size changing and everything. Unfortunately, there just isn't precedent for boundless pseudoterminals.

@DHowett commented on GitHub (Jan 25, 2021): Right, but... having no bounded size is _incompatible_ with terminal emulation. Even when you're hosting processes on Linux, they can request the size in both character cells and pixels with `TIOCGWINSZ`. There's a signal for the window size changing and everything. Unfortunately, there just _isn't_ precedent for boundless pseudoterminals.
Author
Owner

@o-sdn-o commented on GitHub (Jan 25, 2021):

they can request the size in both character cells and pixels with TIOCGWINSZ. There's a signal for the window size changing and everything

The internal structure of my terminal does not have any width limitation. To implement this, I added a new concept to the "viewport" concept: "right oversize" (+ "left oversize" for RTL). Applications that ask the terminal about its size receive a "viewport" in response. The process of stacking text in the terminal takes into account the "oversize".

unlim width

@o-sdn-o commented on GitHub (Jan 25, 2021): > they can request the size in both character cells and pixels with TIOCGWINSZ. There's a signal for the window size changing and everything The internal structure of my terminal does not have any width limitation. To implement this, I added a new concept to the "viewport" concept: "right oversize" (+ "left oversize" for RTL). Applications that ask the terminal about its size receive a "viewport" in response. The process of stacking text in the terminal takes into account the "oversize". ![unlim width](https://user-images.githubusercontent.com/11535558/105760316-6e386700-5f73-11eb-9e3a-b89b68151aea.gif)
Author
Owner

@o-sdn-o commented on GitHub (Jan 25, 2021):

ConPTY works as expected if I force the use of OpenConsole.exe (from the latest main) instead of conhost.exe that shipped with Windows.

What I missed is that ConPTY is updated independently of Windows Terminal. Now I will rely on the compiled OpenConsole.exe. Sorry for the inattention.

@o-sdn-o commented on GitHub (Jan 25, 2021): ConPTY works as expected if I force the use of `OpenConsole.exe` (from the latest `main`) instead of `conhost.exe` that shipped with Windows. What I missed is that ConPTY is updated independently of Windows Terminal. Now I will rely on the compiled `OpenConsole.exe`. Sorry for the inattention.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#12186