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

Add support for more OSC color formats #7578

Merged
merged 47 commits into from
Oct 15, 2020

Conversation

skyline75489
Copy link
Collaborator

@skyline75489 skyline75489 commented Sep 9, 2020

  • Correct the behaviour of parsing rgb:R/G/B. It should be interpreted
    as RR/GG/BB instead of 0R/0G/0B
  • Add support for rgb:RRR/GGG/BBB and rgb:RRRR/GGGG/BBBB. The
    behaviour of 12 bit variants is to repeat the first digit at the end,
    e.g. rgb:123/456/789 becomes rgb:1231/4564/7897.
  • Add support for # formats. We are following the rules of
    XParseColor by interpreting #RGB as R000G000B000.
  • Add support for XOrg app color names, which are supported by xterm, VTE
    and many other terminal emulators.
  • Multi-parameter OSC 4 is now supported.
  • The chaining of OSC 10-12 is not yet supported. But the parameter
    validation is relaxed by parsing the parameters as multi-params but
    only use the first one, which means \e]10;rgb:R/G/B; and
    \e]10:rgb:R/G/B;invalid will execute OSC 10 with the first color
    correctly. This fixes some of the issues mentioned in Add support for multi-param OSC sequences #942 but not
    all of them.

Closes #3715

@ghost ghost added Area-VT Virtual Terminal sequence support Issue-Task It's a feature request, but it doesn't really need a major design. Product-Conhost For issues in the Console codebase labels Sep 9, 2020
@github-actions

This comment has been minimized.

@KalleOlaviNiemitalo
Copy link

The behaviour of 12 bit variants is to repeat the first digit at the end, e.g. rgb:123/456/789 becomes rgb:1234/4567/7897.

Don't you mean rgb:1231/4564/7897?

@skyline75489
Copy link
Collaborator Author

@KalleOlaviNiemitalo Yes you are correct. Thanks for pointing out.

@skyline75489
Copy link
Collaborator Author

I'd very much love to add the color names support in rgb.txt. But I think that file itself is for sure GPL. If we use sources like wikipedia, will it still count as using GPL-licensed content?

CC @DHowett

@Lo0oG
Copy link

Lo0oG commented Sep 10, 2020

I'd very much love to add the color names support in rgb.txt. But I think that file itself is for sure GPL. If we use sources like wikipedia, will it still count as using GPL-licensed content?

You can get a rgb.txt file from XOrg and that's not GPL licensed. https://www.x.org/releases/X11R6.7.0/src/X11R6.7.0-src2.tar.gz
Haven't checked how similar it is to the XParseColor version.
Also see https://en.wikipedia.org/wiki/X11_color_names
Another source could be the HTML specs. https://drafts.csswg.org/css-color/#named-color

@skyline75489
Copy link
Collaborator Author

Thanks @Lo0oG for the information. I’m surprised (also glad) to know that’s not GPL licensed. We are going through the internal legal process for us to be able to use it.

@WSLUser
Copy link
Contributor

WSLUser commented Sep 10, 2020

What I don't get is GPL is still open-source. So why is it an issue to have GPL and MIT in an MS repo? Is it that the legal department doesn't want to have to deal with both? If so, then they should be overridden. Their job isn't to stop usage of OSS based on a particular license.

@AnuthaDev
Copy link
Contributor

AnuthaDev commented Sep 10, 2020

@WSLUser GPL is for "Free" Software, what that means is if you distribute software binaries licensed under GPL, you have to distribute the source code too, MIT on the other hand has no such requirement and MIT licensed software doesn't have to be open source. The problem is that GPL is a "Viral" license, meaning if you include GPL licensed code in your product, you would have to distribute the whole product under GPL, and since some parts of this repo are also synced with the windows source code, it would mean microsoft would have to open-source windows itself, which would be a legal nightmare considering how much code was licensed from third parties(Some of which don't even exist anymore!!). So, while GPL could be used as the license for windows terminal, it can't be used for windows, and hence no GPL licensed code can be included in this repo.

@AnuthaDev
Copy link
Contributor

If so, then they should be overridden.

I don't think microsoft would be too happy with that😅

@skyline75489
Copy link
Collaborator Author

Thanks @AnuthaDev. I wrote basically the same thing then I saw your post and just give up writing my own.

Just want to point out that not allowing GPL code in this repo is actually MS following the rules of the OSS community. Surely one can copy GPL code and keep their work close sourced. And lawsuits about GPL violations are not always feasible. Imagine in what world would XOrg actually sue MS for just some color metadata. It’s not all about getting away from legal issues. It’s also about MS trying to be a good OSS citizen.

@KalleOlaviNiemitalo
Copy link

I think it's perfectly fine to keep settings.json supporting only the #rrggbb format and not these OSC color formats. Wouldn't want to list all the color names in the JSON schema.

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have to worry about the 30kb growth for now. We can book work later to try to optimize it.

That's almost literally just the the color table:

  • 6943 bytes for 676 null-terminated strings
  • 2704 bytes for 676 RGBA quads
  • 10816 bytes for 676 char*, size_t tuples at 16 bytes each (yeah, this part sucks)

That's 20kb alone for the whole table stored fairly inefficiently.

}
else if (wch == L';' && i > 0)
unsigned int tableIndex = 0;
const bool indexSuccess = Utils::StringToUint(parts.at(i), tableIndex);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can put the suppression inside til::at. That's what it's there for -- we use it when we know that the static analyzer is going to complain about something that we've vetted as being safe.

@DHowett
Copy link
Member

DHowett commented Oct 10, 2020

If we had a prefix trie we could probably remove the duplicate cost of the ~514 colors that are literally just colors with different numbers at the end... which would save approximately 5174 bytes. It would complicate this PR a lot, so I'd rather do it later.

@skyline75489
Copy link
Collaborator Author

Oh crap. I think I messed up the commits. Well this is indeed a lengthy thread. In fact I think this is most commented PR I've ever made on Github. I'll force push later.

@skyline75489 skyline75489 force-pushed the chesterliu/dev/osc-color-format branch from 1cb8106 to cf69ae3 Compare October 10, 2020 15:03
@DHowett
Copy link
Member

DHowett commented Oct 11, 2020

Well, cttrie is out of the question.

Even with half the colors removed:

cl

C:\Users\Dustin\Projects\thirdparty\Terminal\trie\cttrie\getindex.h(26): fatal error C1202: recursive type or function dependency context too complex

clang

./cttrie/getindex.h:27:32: warning: stack nearly exhausted; compilation time may suffer, and crashes due to stack
      overflow are likely [-Wstack-exhausted]

(it's still trying to compile, but I had to set the template depth to 1048576.)

@skyline75489
Copy link
Collaborator Author

@DHowett I also tried Trie-Gen and with the 3800 loc it generated, the binary size went up to 1080k. So... you can rule that out, too.

@DHowett
Copy link
Member

DHowett commented Oct 11, 2020

image

cl took 7 minutes before emitting an error message, and clang is still going (miraculously)

@skyline75489
Copy link
Collaborator Author

Man those poor compilers. They didn't even know what hit them.

Trie-Gen gave me pure C code which is no burden for compiles but not optimized for binary size.

@j4james
Copy link
Collaborator

j4james commented Oct 11, 2020

If you're desperate, you could probably save around 5KB by storing the data as two simple arrays. 2704 bytes for the 676 RGBA quads, and 12351 bytes for the strings (6943 bytes of content and 676 pointers). You'd have to then build the map at startup, but I wouldn't think that would be a huge amount of code. Not sure it's worth the complication though.

@DHowett
Copy link
Member

DHowett commented Oct 11, 2020

Yeah, I'd say it's not worth it.

I got the table down to ~5kb using a gperf hash and stripping the color names entirely, but that is riddled with false positives because there's no actual check that the key matched.

(the good)

input: peachpuff
lookup: peachpuff
hash: 2059
found! Color #FFFFDAB9

input: AnTiQuE WhItE
lookup: antiquewhite
hash: 432
found! Color #FFFAEBD7

(the bad)

input: not a color
lookup: notacolor
hash: 599
found! Color #FFEEE0E5
input: ffuphcaep
lookup: ffuphcaep
hash: 2059
found! Color #FFFFDAB9

input: peachpuff
lookup: peachpuff
hash: 2059
found! Color #FFFFDAB9

@skyline75489
Copy link
Collaborator Author

So I was thinking what if we store the colorTable with prefix trie in some kind of string representation and compressed it using gzip or zlib, then decompress and reconstruct the trie...

OK let's do gperf hash then. I think the false positives should have very limited real-life impact, at least to "normal" people who don't mess around with their terminal.

src/types/colorTable.cpp Outdated Show resolved Hide resolved
src/types/colorTable.cpp Outdated Show resolved Hide resolved
@DHowett DHowett changed the title Improve support of OSC color parameters Add support for more OSC color formats Oct 15, 2020
@DHowett DHowett merged commit 02b1202 into microsoft:master Oct 15, 2020
@DHowett
Copy link
Member

DHowett commented Oct 15, 2020

Thanks for your contributions, everyone, and thanks @skyline75489 for working hard on this 😄

@ghost
Copy link

ghost commented Nov 11, 2020

🎉Windows Terminal Preview v1.5.3142.0 has been released which incorporates this pull request.:tada:

Handy links:

@ghost ghost mentioned this pull request Nov 11, 2020
@skyline75489 skyline75489 deleted the chesterliu/dev/osc-color-format branch December 3, 2020 00:07
ghost pushed a commit that referenced this pull request Feb 4, 2021
This adds the support for chaining OSC 10-12, allowing users to set all
of them at once.

**BREAKING CHANGE**
Before this PR, the OSC 10/11/12 command will only be dispatched iff the
first color is valid. This is no longer true. The new implementation
strictly follows xterm's behavior. Each color is treated independently.
For example, `\e]10;invalid;white\e\\` is effectively `\e]11;white\e\\`.

## Validation Steps Performed

Tests added. Manually tested.

Main OSC color tracking issue: #942
OSC 4 & Initial OSC 10-12 PR: #7578

Closes one item in #942
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 Issue-Task It's a feature request, but it doesn't really need a major design. Product-Conhost For issues in the Console codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support more OSC color formats
10 participants