-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
GetConsoleScreenBufferInfoEx doesn't return the actual palette #10639
Comments
@zadjii-msft This is problematic because it makes it impossible for a console mode application to detect whether the current terminal theme is Light or Dark. For example, clink cannot automatically choose colors with correct contrast ratio to be visible. Instead I have to force users to manually configure their colors. Users are unhappy about this. It would be much appreciated if this API could get fixed to return the actual current terminal theme colors. (I understand that GCSBIE() doesn't have any way to return the default foreground or default background colors. At least for my usage cases, that's easily worked around by printing |
The reason we can't easily do this is because conhost (which handles GCSBIE) doesn't know what the terminal's colors are. To find that out, it would need to send an escape sequence to the connected conpty client, and then block while it waits for a response, which isn't great for performance. This is problematic, because some applications call GCSBIE a lot. Imagine a number that you think is a ridiculous amount, and it's likely more than that. And to further complicate the matter, there's no guarantee that the connected conpty client even supports palette queries. I did play around with querying the palette once at startup, but that still introduces the complexity of having to wait for a response which may never arrive. An easier version of that would be to have the client pass in the palette via the initial command line. But both of those solutions fall apart if a user updates their palette settings at run-time. So while I would love to get this working somehow, I just don't see how. But if anyone has any bright ideas, feel free to share them here. |
Why? I have a very basic idea of how all this is organised, but this sounds unnecessarily inverted. Our usage of this API is mostly related to colours mixing, e.g. transparency and shadows. To properly mix index colours we have to know to which exactly RGB values they are mapped. |
@j4james @zadjii-msft Here are some brainstorming thoughts. Maybe some of them will be viable, or maybe some of them with spark further ideas.
What if conhost didn't need to wait?
Yes, GCSBIE can get called a ton. What if the work weren't done every time?
Do you mean that there is a single two-way channel of communication, i.e. all data communication must be through input and output streams, so the two sides can only communicate by passing escape codes to each other? And so if one side doesn't support responding to a query sequence then the other side can hang?
I agree that supporting palette changes at runtime should be considered a requirement for any solution.
I'm not suggesting it would be trivial to implement, nor that it should be perfect with no caveats. But this is currently a pretty significant regression from the perspective of console mode programs. |
My understanding is that conpty is designed to work in a similar fashion to the Linux pty system, so a Linux terminal could theoretically be ported to Windows without too much effort. I don't know all the details, but I think there's an input stream, an output stream, and a signal stream, and it's the latter that is responsible for notifying conhost of window size changes, similar to the There isn't an equivalent signal for palette changes (as far as I'm aware), so that would be something we'd have to invent. Whereas conhost querying the palette from the conpty client just relies on standard escape sequences that a lot of terminals should already support out of the box. That's why I was considering a query as my initial approach to the problem. But as you're both proposing, having the conpty client notify conhost of palette changes does seem like a much better idea. And if some don't support it, they'd be no worse off than they are now. I'm not very familiar with this part of the code, so there may be technical reasons why this isn't feasible, but if the core devs don't raise any objections, I'd be willing to give it a try some time. |
By the way, are these standard escape sequences already supported by WT? |
Btw, not all terminals support the same escape sequences. So I don't think it's safe for conhost to make assumptions about which codes it can send internally. If the conpty client indicated its capabilities, then it could be considered safe. |
@alabuzhev No, for the same reason we don't return the palette in GCSBIE. That's actually the main reason I want to fix this. I don't particular care about GCSBIE, but I would like to get the VT palette queries working (and a number of other VT queries that we can't currently handle).
@chrisant996 Yeah, but we only care about terminals that are using conpty, and it also doesn't really matter if they don't support the sequence - it should just be ignored. But that's not something I'm planning to do now anyway. I much prefer the approach that you guys were suggesting, i.e. the conpty client pushing the palette to conhost. |
Terminal and the new conhost do not support GetConsoleScreenBufferInfoEx returning the actual color table. If/when that issues gets fixed, then Clink will be able to return the color table. (For example, so scripts can infer "light theme" versus "dark theme".) microsoft/terminal#10639
Can't work in Windows Terminal until Terminal#10639 is fixed. microsoft/terminal#10639
Thinking about it again, do we even need a separate notification here? |
Well, yes, that would rather constitute a notification. |
This comment was marked as off-topic.
This comment was marked as off-topic.
@DHowett I mean that in a more conventional sense a "notification" is rather something like: Whereas "build and shove |
Byte swapping discussion (hidden as off-topic)
This is the first we've heard of GCSBIEx returning invalid data in the color palette! Do you have a test app that exhibits this? It sounds (sorry, based on "... detect that the API is malfunctioning") like it isn't consistent. (EDIT: Oh, I see you added one. Thanks!)
Alas, it still will. ConPTY's VT input state machine is vastly different from the output one. |
This comment was marked as off-topic.
This comment was marked as off-topic.
(For thread tending purposes, I moved the byte swapping discussion over to #16795) |
FYI, I came across a discussion recently on the issue tracker of another terminal (most likely VTE), where somebody was asking for similar functionality. The use case was for multiplexers like tmux and zellij, which are in a similar situation to us with conpty, i.e. needing to know the palette of the connected terminal. I think one of the proposals was to trigger The other suggestion was something like a mode that the app would set letting the terminal know that it wanted to receive automatic updates. This seemed a more promising approach to me, but it would need to cover more than just palette changes in my opinion (I made some notes on this subject in #16672 (comment)). Anyway, the main reason I wanted to bring this up was because it would be good if we could agree with other terminals on a standard for this if they are going to be doing the same sort of thing. |
That was my proposal / patch you came across :) Here's the link for reference: |
Windows Terminal version (or Windows build number)
1.9.1523.0
Other Software
No response
Steps to reproduce
Expected Behavior
The same colour codes as in the corresponding section of
C:\Program Files\WindowsApps\Microsoft.WindowsTerminalPreview_1.9.1523.0_x64__8wekyb3d8bbwe\defaults.json
:Actual Behavior
It looks like the default Windows 10 palette is returned instead:
The text was updated successfully, but these errors were encountered: