-
Notifications
You must be signed in to change notification settings - Fork 8.1k
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
Cannot use stream-based I/O to ConPTY/Console and receive WINDOWS_BUFFER_SIZE_EVENT simultaneously #394
Comments
Just to put this in context, I'm writing a terminal multiplexer under coreclr (2.2). When I've bound conhost to a cmd/wsl/pwsh subprocess, I can't resize the virtual terminal in response to the user resizing conhost. |
@oising to be clear, are you trying to be a client application or a server application? Your title is mixing both ConPTY and the usage of the classic console API, which implies to me that you're trying to be a client application and a server (console window host) to yourself at the same time. Or is it that you're trying to be a client application but speaking 99% VT on WriteFile and only using the minimal amount of other Windows client-APIs as possible? EDIT: I'm dumb. Let me re-read this and try again. |
OK so you've got this: (A) Conhost in standard window visible mode <----> (B) Multiplexer application <------> (C) Conhost in ConPty mode <-----> (D) Client application A is the server on top displaying stuff. D is probably speaking classic Win32 to the C conhost in ConPTY mode. And I think your problem is that between A and B, it's difficult or nigh impossible to know when the A window has resized and have an event come into B in a format that is easy to consume. Sound right? |
@miniksa Right. Between A (physical, visible conhost window) and B (multiplexer watching conpty C running D, and relaying stdin/stdout between D and A.) If I resize the physical window (A), it seems impossible to capture that informational event while streaming stdin/stdout to and from (A) and (D). D is speaking classic win32 yes, but since it's conpty, it doesn't really matter. |
It seems that the moment you start reading from Console.OpenInputStream() then ReadConsoleInput stops receiving any data. Now obviously this makes sense at first glance, since you're gonna use one or the other but unfortunately resize events are only consumable from the latter. (update: I invited you to my private repo hosting the full code if you're interested in taking a look for more context) |
I think that the .NET abstractions here cause inadvertant flushes. If you're trying to do something advanced like this, I would strongly discourage using I'll have to give your private repo and the rest of this a more thorough scrub tomorrow morning. I have a few other things to get through today. I might also need @zadjii-msft to get back to work to confer with him on the state of resize as he's been in that space more recently than I have (he's just on vacation this week, due back on Monday.) |
I dug into FX already and there was nothing there that stood out initially. Internally the console PAL layer uses
Trying to force
I suppose this shouldn't be a surprise since Blergh. |
Yes, sorry, uhhh... When the calls are serviced, it's the same queue underlying both APIs inside the Also, I have a massive pile of e-mail in my inbox this morning so I'm not remotely closer to looking at your private repro that you shared with me. Please bear with me. I'll try to get to it. |
@miniksa Don't stress man over the private repo. It's something you might enjoy reading through to get an idea how someone is trying to do something more advanced than a sample app. In your own time! |
Okay, so it looks like I've no choice but to wrap |
This is one of the classes of issue I want to solve when we get time to do something about #281. Might leave it open. |
So I managed to hack together a prototype |
Excellent to hear. If you have a useful reusable component that helps make this easier, I'd be happy to accept a pull into this repo in the tools directory so we can have it for others to use as well. |
I think this is answered, done, and relatively over with for now. Any further calculations on getting the event out will have to do with that one that I said "I need to make this a deliverable for size events". |
Microsoft Windows [Version 10.0.18362.1]
To monitor console buffer resize events (and viewport resize events in more recent builds),
ReadConsoleInput
must be used to look forINPUT_BUFFER
events with an event type of 4 (WINDOW_BUFFER_SIZE_EVENT
).My problem is that when I open a pseudoconsole session for a new cmd.exe process and I want to use bidirectional VT codes (stream based) for stdin/stdout for maximum cross platform portability. That is to say, I don't want to use the windows console APIs because they are windows specific. This seems to make it very difficult - without gag-inducing and complex task synchronization - to watch for resize events at the same time. When stdin/stdout are flushed, any
INPUT_BUFFER
records inReadConsoleInput
are too, includingWINDOWS_BUFFER_SIZE_EVENT
records.VT allows capturing mouse movement - or at least it should in the future since ConPTY doesn't seem to forward mouse coords/actions yet, but there is no equivalent VT sequence for resizes of the viewport. Here's some demo/repro code:
My specific NuGet dependencies for the repro are:
TL;DR -- it's very hard, if not impossible, to watch for viewport resizing and also use a pure VT implementation (no console API).
Solution? I'd suggest draining the input buffer if streaming but leaving resize, menu, mouse (if enabled) events etc. This may be a memory leak (but probably fixed max, circular buffer etc) if the default behaviour changed, so I guess it should be opt-in.
The text was updated successfully, but these errors were encountered: