Skip to content
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

Feature Request: command or proprietary escape codes to set a tab's color #6574

Closed
Adam13531 opened this issue Jun 18, 2020 · 27 comments · Fixed by #13058
Closed

Feature Request: command or proprietary escape codes to set a tab's color #6574

Adam13531 opened this issue Jun 18, 2020 · 27 comments · Fixed by #13058
Labels
Area-VT Virtual Terminal sequence support Help Wanted We encourage anyone to jump in on these. Issue-Task It's a feature request, but it doesn't really need a major design. Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Milestone

Comments

@Adam13531
Copy link

Description of the new feature/enhancement

The request is to be able to set a tab's color via a typed command, e.g. colortab red. iTerm2 does this via proprietary escape codes; this combination of three echo commands will color a tab pink:

echo -e "\033]6;1;bg;red;brightness;255\a"
echo -e "\033]6;1;bg;green;brightness;0\a"
echo -e "\033]6;1;bg;blue;brightness;255\a"

My scenario is that I want a .cmd file to be able to color its resulting tab without manual intervention, e.g. as a blue build process, a green chat bot, a red utility program, etc.

P.S. great job landing #2994!

@Adam13531 Adam13531 added the Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. label Jun 18, 2020
@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Jun 18, 2020
@zadjii-msft
Copy link
Member

Why the heck is that sequence formatted that way? Why isn't it just ^[]6;1;r;g;b^G?

I mean I'm generally fine with the idea, but I'd just imagine that they would have designed a better sequence tbh. What happens when you only emit

echo -e "\033]6;1;bg;red;brightness;255\a"

?

I could see this being useful as another alternative to #3004, where an app could change the tab color as a kind of notification.

@zadjii-msft zadjii-msft added Area-VT Virtual Terminal sequence support Issue-Task It's a feature request, but it doesn't really need a major design. Product-Terminal The new Windows Terminal. and removed Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. labels Jun 18, 2020
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Jun 18, 2020
@zadjii-msft zadjii-msft added the Help Wanted We encourage anyone to jump in on these. label Jun 18, 2020
@zadjii-msft zadjii-msft added this to the Terminal Backlog milestone Jun 18, 2020
@DHowett
Copy link
Member

DHowett commented Jun 18, 2020

I'm alright committing this to the backlog w/ Help Wanted. Yanking triage.

@DHowett DHowett removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Jun 18, 2020
@j4james
Copy link
Collaborator

j4james commented Jun 19, 2020

I believe this originally came from Eterm, which is why it doesn't share the typical XTerm color syntax. And to be honest, I'd probably recommend coming up with our own sequence if we want to support this functionality (or at least looking for an alternative that other terminals might be using). I can't see OSC 6 ever being widely used, because it already has at least two other meanings. In XTerm it's used to enable special colors. In Terminal.app and VTE it's used to set the current file path.

@j4james
Copy link
Collaborator

j4james commented Aug 13, 2020

I had an idea for a sequence we could possibly use for this. On the DEC VT525, there's a DECAC (Assign Color) control sequence which is used to set the default foreground and background colors (essentially the equivalent of the XTerm OSC 10 and OSC 11 sequences). But it can also be used to set the Window Frame color, which I think could be considered somewhat equivalent to our tabs.

The VT525 has a concept of multiple sessions, and when the Frame Windows option is selected, a row of icons is displayed across the top of the screen to keep track of the different sessions, very similar in concept to tabs. You can see an image of a VT520 screen showing the session icons here:

https://i.imgur.com/8ujq0uN.jpg

The second session isn't named in that image, so it's not that obvious that you've got two sessions, but you can still see how similar those session identifiers are to tabs. This particular image is from a monochrome device, but I believe both the window frame and the icons would be displayed using the Window Frame colors, so I don't think it would be unreasonable for us to also use those colors for our tabs.

@j4james
Copy link
Collaborator

j4james commented Aug 13, 2020

Although now that I'm rereading the documentation, I realise you can only specify a color index when setting these colors. And technically the VT525 only supported index values in the range 0 to 15, but we could probably support all 256 colors from the XTerm color table and still be backwards compatible. But if you were hoping to be able to specify a full RGB value, then this isn't quite what you want.

@sba923
Copy link

sba923 commented Jan 26, 2021

Just wondering: is the only reason why this is stalling that there's no agreement on what the escape sequence should be?

@j4james
Copy link
Collaborator

j4james commented Jan 26, 2021

Personally I'm quite keen to implement the DECAC sequence (assuming that's something the core devs would be happy to accept), just because I'd like for us to support as many of the standard DEC sequences as possible. I don't know if that would necessarily satisfy those of you that requested this functionality, though.

So while I'm not exactly waiting for agreement on a sequence (I'd probably submit a PR for DECAC at some point anyway), the fact that nobody seemed interested in my proposed solution made me think it wasn't worth prioritizing.

@zadjii-msft
Copy link
Member

It's probably 50% "no agreement on what the sequence should be" and 50% "there's just not enough demand for us to bother figuring it out".

Using OSC 6 is a bad idea because it's used for other things. DECAC is no good either? So we'd have to come up with our own sequence, and frankly we just haven't done that yet. So this would be setting a precedent in that regard, and isn't something we'd want to do wrong.

In previous issues we've mentioned using the OSC prefix ^[]9001 for WT-specific sequences, and I'm still down with that. So this would be something like ^[]9001;1;r;g;b

As I'm typing this up I see j4james's reply. I'm fine with the DECAC solution if he is. He's got a better head for what is or isn't compatible.

I think mostly, there's just not that much priority on such a feature. I think most people have been doing alright with the "set tab color" actions and right click menu, so this just hasn't bubbled up the task list.

@sba923
Copy link

sba923 commented Jan 26, 2021

I think not being able to specify any RGB color would be quite a limitation / inconsistency with other colors being specified as RGB.

Just my €0.02.

About the priority: yes "set tab color" can be done, but what I'd like to get (and frankly I can't be alone, and those who don't upvote this should really reconsider their line of thinking) is the ability to set the color e.g. when I switch projects, when something special occurs within the tab, to show that some long-lasting command has completed.... etc.

@WSLUser

This comment has been minimized.

@sba923

This comment has been minimized.

@zadjii-msft
Copy link
Member

As noted in #11181 (comment), there's an iTerm2 sequence for setting the tab color, which is a little weird but it's an OSC so of course it is. That's a seemingly unambiguous way of implementing this.

@zadjii-msft zadjii-msft modified the milestones: Terminal Backlog, Backlog Jan 4, 2022
@zippygit
Copy link

zippygit commented Mar 6, 2022

I've grown fond of using the functionality in iTerm2 when working from a Mac, via shell functions setting tab color based on keywords indicating what development host I'm logged into or other parameters. When I move to WSL and Windows Terminal for the same kind of work, I keep invoking the shell functions out of habit :). While those iTerm2 sequences are awkward, they are at least functional, and can be encapsulated once in shell functions/scripts, which may be the most common context for using them. Better sequence alternatives would also be OK, though the logic for determining on a remote host what kind of terminal emulator has logged into it could be unpleasant.

@sba923
Copy link

sba923 commented Mar 6, 2022

Are you referring to the commands used at https://kendsnyder.com/tab-colors-in-iterm2-v10/?

Just tried this in WSL2 running within Windows Terminal Preview 1.13.10395.0, this doesn't change the tab's color...

Did I miss something?

@zippygit
Copy link

zippygit commented Mar 6, 2022

Are you referring to the commands used at https://kendsnyder.com/tab-colors-in-iterm2-v10/?

Just tried this in WSL2 running within Windows Terminal Preview 1.13.10395.0, this doesn't change the tab's color...

Did I miss something?

You didn't miss anything. They do not work in Windows Terminal (Preview or otherwise) today. Under discussion here was the idea of adding a feature to Windows Terminal so that they do work (or some other, similar but better escape sequences could be made to work in lieu of these).

@j4james
Copy link
Collaborator

j4james commented Mar 6, 2022

I actually had a plan for this that I've been meaning to propose, which doesn't require any proprietary sequences, but would still give you full RGB control of the color.

The idea is you'd use the DECAC sequence to control the palette index for the tab (as suggested above), but then set the actual RGB value of that palette entry with one of the existing palette control sequences: OSC 4 or DECRSTS (once I get around to adding that).

This would work the same way we now handle default foreground and background colors, with the new color alias system. So we'd create a new entry in the color table outside the base 256 range, and that's what the tab color would point to by default.

The simplest way to change the tab color would then be with a palette update sequence setting palette entry 258 (or whatever position we decide to assign to it). If you want to be more robust, though, you could lookup the actual index first with a DECRQSS query.

One of the neat benefits of this approach, is you also have the option of setting the tab color index to match the default background color index, and that way you'd have your tab automatically matching your background color (the UI concept proposed in #702).

@sba923
Copy link

sba923 commented Mar 7, 2022

I would not like a link between background color and tab color, 'cos I want to stick to my (dark grey) background color for my shells, yet I want to be able to easily tell tabs apart thanks to their color.

@zadjii-msft
Copy link
Member

Oh interesting, so it'd be like:

  • By default, the tab color would be set to something like index 258 in the color table.
  • You could set the tab color using DECAC to the color of the DARK_RED entry in the table (index 1), or the default BG color (index... 257?)
  • Alternatively, you could just change the tab color by setting index 258 directly with OSC4.

IMO that's a really clever, elegant solution.

As a sidebar, I actually think there's an API in Window 11 for setting the window frame color. So, we may want to actually extend DECAC here with additional parameters for frame, tab color, etc. I'll leave that best judgement to j4james though, since he's got a better knack for the compat concerns there.

note to self: DECAC docs (search for "DECAC—Assign Color"). Couldn't find a better source.

@ghost ghost added the In-PR This issue has a related PR label May 8, 2022
@ghost ghost closed this as completed in #13058 May 12, 2022
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. and removed In-PR This issue has a related PR labels May 12, 2022
ghost pushed a commit that referenced this issue May 12, 2022
The `DECAC` (Assign Colors) escape sequence controls which color table
entries are associated with the default foreground and background
colors. This is how you would change the default colors on the the
original DEC VT525 terminals.

But `DECAC` also allows you to assign the color table entries for the
"window frame", which in our case is mapped to the tab color (just the
background for now). So this now gives us a way to control the tab color
via an escape sequence as well.

DETAILS
-------

The way this works is there are now two new entries in the color table
for the frame colors, and two new aliases in the color alias table that
are mapped to those color table entries. As previously mentioned, only
the background is used for now.

By default, the colors are set to `INVALID_COLOR`, which indicates that
the system colors should be used. But if the user has set a `tabColor`
property in their profile, the frame background will be initialized with
that value instead.

And note that some of the existing color table entries are now
renumbered for compatibility with XTerm, which uses entries 256 to 260
for special colors which we don't yet support. Our default colors are
now at 261 and 262, the frame colors are 263 and 264, and the cursor
color is 265. 

So at runtime, you can change the tab color programmatically by setting
the color table entry at index 262 using `OSC 4` (assuming you need a
specific RGB value). Otherwise if you just want to set the tab color to
an existing color index, you can use `DECAC 2`.

You can even make the tab color automatically match background color by
mapping the frame background alias to the color table entry for the
default background, using `DECAC 2;261;262` (technically this is mapping
both the the foreground and background).

This PR doesn't include support for querying the color mapping with
`DECRQSS`, and doesn't support resetting the colors with `RIS`, but
hopefully those can be figured out in a future PR - there are some
complications that'll need to be resolved first.

## Validation Steps Performed

I've added a basic unit test that confirms the `DECAC` escape sequence
updates the color aliases in the render settings as expected. I've also
manually confirmed that the tab color in Windows Terminal is updated by
`DECAC 2`, and the default colors are updated in both conhost and WT
using `DECAC 1`.

Closes #6574
@ghost
Copy link

ghost commented Jul 6, 2022

🎉This issue was addressed in #13058, which has now been successfully released as Windows Terminal Preview v1.15.186.:tada:

Handy links:

@sba923
Copy link

sba923 commented Jul 6, 2022

We need documentation describing how to use the newly supported DECAC to set the tab's color.

So far, I've experimentally determined that ESC [ 2 ; 0 ; n , | will change the tab's color depending on n, but not what palette n indexes into, nor how to select a color by its RGB value.

@zadjii-msft
Copy link
Member

@sba923 It sure should! Filed MicrosoftDocs/Console-Docs#267 to track.

@DHowett
Copy link
Member

DHowett commented Jul 6, 2022

In short, though: DECAC can assign the frame and default indices each to any other color from the xterm 256-color palette (by index -- therefore, if you reassign what that index means, you can change that color no matter where it is used).

James' PR also added 263 and 264 as virtual indices that contain the tab foreground and background, respectively. You can change them using OSC 4. These are technically unrelated to DECAC[1].

So at runtime, you can change the tab color programmatically by setting the color table entry at index 262 (sic: I think he meant 264) using OSC 4 (assuming you need a specific RGB value). Otherwise if you just want to set the tab color to an existing color index, you can use DECAC 2.
@j4james in commit a69ce89

Therefore, this will change the tab background color to any RGB value (OSC 4):

image

And this will change the tab background color to "whatever the background color of the Terminal is" (DECAC):

image

Our documentation should clarify these new color indices since we're making a contract out of them, and it should further clarify the purpose of DECAC specifically.

[1] Technically. They're related because you can use DECAC to reassign "frame colors" to any two indices instead of 263 and 264.

@sba923
Copy link

sba923 commented Jul 6, 2022

Thanks @DHowett for the short explanation. I'll keep experimenting.

@j4james
Copy link
Collaborator

j4james commented Jul 7, 2022

I just want to note that in an ideal world, apps that want to change the tab colors shouldn't have to know that we're storing them at 263 and 264. They should be able to query those indices via DECRQSS and then decide whether they're safe to update (i.e. you may not want to mess with them if they're pointing to positions in the ANSI color range).

Unfortunately we don't yet support the DECRQSS query for DECAC (see #13091). And if you're just targetting Windows Terminal specifically, then it's obviously a lot easier to just hardcode those values. But it is at least theoretically possible to do this in a generic way (or at least it will be once we support DECRQSS).

@sba923
Copy link

sba923 commented Jul 8, 2022

Experimentation ongoing, several new points / questions I want to raise:

  1. it seems that in some situations the tab color is reset to the default; haven't identified the trigger yet
  2. is there a way to retrieve the RGB value of the original color (default or set via the menu) that was active before using OSC 4 or DECAC?
  3. is there a way to reset the color to the original value (default or set via the menu)?

@j4james
Copy link
Collaborator

j4james commented Jul 8, 2022

  1. it seems that in some situations the tab color is reset to the default; haven't identified the trigger yet

If you update anything in the settings, that will likely reset the palette, which include the new tab color. I think that reset can also be triggered by other things, like switching the keyboard layout (see #11522). That may be what you're experiencing.

  1. is there a way to retrieve the RGB value of the original color (default or set via the menu) that was active before using OSC 4 or DECAC?

Not at the moment, no. In the future you may be able to query the palette entries with something like OSC 4, but we don't support that yet (see #3718).

  1. is there a way to reset the color to the original value (default or set via the menu)?

Again no, but in the future maybe. At the very least we should add support for resetting everything with RIS. We may also want to allow resetting individual palette entries with OSC 104 (see #3719).

I should add that I'm not sure OSC 4 and OSC 104 are appropriate for these colors, though. XTerm only uses those sequences for the main 256-color table, and what they classify as "special colors". They don't support frame colors, but if they did, they'd probably fall under the "dynamic colors" category, which are handled in a completely different way, and I don't think we can extend that.

@sba923
Copy link

sba923 commented Jul 20, 2022

  1. it seems that in some situations the tab color is reset to the default; haven't identified the trigger yet

If you update anything in the settings, that will likely reset the palette, which include the new tab color. I think that reset can also be triggered by other things, like switching the keyboard layout (see #11522). That may be what you're experiencing.

It's very likely I'm hit by #11522.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-VT Virtual Terminal sequence support Help Wanted We encourage anyone to jump in on these. Issue-Task It's a feature request, but it doesn't really need a major design. Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants