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 cursorTextColor attribute to colour schemes #15766

Open
weibeld opened this issue Jul 26, 2023 · 4 comments
Open

Add cursorTextColor attribute to colour schemes #15766

weibeld opened this issue Jul 26, 2023 · 4 comments
Labels
Area-Rendering Text rendering, emoji, complex glyph & font-fallback issues Area-Settings Issues related to settings and customizability, for console or terminal Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal.
Milestone

Comments

@weibeld
Copy link

weibeld commented Jul 26, 2023

Description of the new feature/enhancement

Colour schemes allow setting the cursor colour (cursorColor), however, they don't allow setting the text colour of the character under the cursor. The character under the cursor just keeps its native colour. This is a problem for the Filled Box cursor type because the character under the cursor may become very illegible if the cursor colour and character colour don't happen to naturally contrast.

This problem is exacerbated in applications like Vim where the text that the cursor moves over comes in many different colours. Thus, the problem can't be generally solved by changing the cursor colour because there might always be some combination of cursor and text colour that remain illegible.

The best solution to this problem would be to always change the colour of the character under the cursor to a colour that contrasts well with the cursor colour. In this way, it's guaranteed that the character under the cursor is always legible.

This could be implemented by adding a cursor text colour attribute to the colour scheme (e.g. cursorTextColor attribute), so that colour scheme designers can choose a good combination.

That's also exactly how it is done in iTerm2:

unnamed

Considerations:

  • This applies only to the Filled Box cursor type. For the other cursor types, it's not necessary to change the colour of the character under the cursor.
  • Thus, the attribute could maybe be named cursorFilledBoxTextColor to make this clear.

Related:

@weibeld weibeld added the Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. label Jul 26, 2023
@microsoft-github-policy-service microsoft-github-policy-service bot added Needs-Tag-Fix Doesn't match tag requirements Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels Jul 26, 2023
@carlos-zamora carlos-zamora added this to the Backlog milestone Jul 26, 2023
@carlos-zamora carlos-zamora added Area-Rendering Text rendering, emoji, complex glyph & font-fallback issues Area-Settings Issues related to settings and customizability, for console or terminal Product-Terminal The new Windows Terminal. and removed 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 Jul 26, 2023
@zadjii-msft
Copy link
Member

zadjii-msft commented Jul 26, 2023

After some discussion, I think we did end up losing this over the course of #1203 and #9610. Rather than resurrect one of those, we thought it best to use this fresh thread to track this again. That way we won't have any of the old legacy notes about DxEngine-specific implementation details.

🚧 This space to be updated 🚧

I too have not paged this back in yet, but IIRC there was a collection of related issues:

  • Allow filled box cursors to display the glyph under them in
    • a sane color contrast
    • the terminalBackground color
    • inverted colors (like, rgb(255, 255, 255) - pixelColor or whatever)
    • an arbitrary color (cursorForeground)

again, long since paged this out 😕

notes:


@DHowett proposal

  1. {scheme}.cursorColor and {profile}.cursorColor gain support for inverse and (later) reverse
    • Eventually, this means cursorColor will support foreground+background, inverse, reverse.
    • This requires some UI work around pickable things that are not colors. It is somewhat unclear: these are not colors.
    • Color schemes are no longer color schemes; they are forced to decide the visual properties of the cursor
  2. {profile}.cursorColor becomes deprecated¹ (as well as .foreground, .background, and .selectionColor; it only seems right) and we add the {profile}.cursorStyle enum, which supports color, inverse, and reverse.
    • I am hesitant to introduce a new setting for 1.7, but it would be in our best interest to do so.
  3. As yet unexplored option 3. Proposals welcome.

@zadjii-msft proposal from #6151

We'll introduce cursorTextColor as a setting that accepts the following
values:

  • "#rrggbb" (a color): paint the character the cursor is on in the given color
  • "textForeground": paint the character the cursor is on on top of the cursor in the text foreground color.
  • "textBackground": paint the character the cursor is on on top of the cursor in the text background color. (This is like what gVim does, see this comment).
  • null: Paint the cursor on top of the character always.

@klausman
Copy link

klausman commented Jul 27, 2023

The easiest and most user-friendly option is to let the user choose. Guessing/auto-computing the 'right" color is not trivial and may completely miss some needs of the user, e.g. vision impairment, or output-device-specific constraints.

On the other bugs, a lot of time was spent on finding the perfect algorithm to determine the right color, to the point of exasperation of several users that just wanted to set the color themselves for their own needs. Please just implement user choice. It's the right thing to do.

weibeld added a commit to weibeld-setup/settings-windows-terminal that referenced this issue Jul 27, 2023
The preview version of Windows Terminal v1.18 fixes the issue of
illegible text under the cursor by somehow automatically determining the
colour of the character under the cursor.

The colour of the character under the cursor is not constant, it changes
depending on the native colour of the character (and probably the colour
of the cursor). However, the contrast is acceptable in most cases. See
more information about this feature in [1].

Setting the cursor text colour explicitly as part of the colour scheme
(arguably a better solution than the current implementation) is still
separately discussed in [2].

[1] microsoft/terminal#7118
[2] microsoft/terminal#15766
@weibeld
Copy link
Author

weibeld commented Jul 27, 2023

I also support the proposition by @klausman. There's nothing more needed than a cursorTextColour attribute in the colour scheme specification so that colour scheme designers can choose an appropriate value and users never need to worry about it (this also supports the use case of designing special colour schemes, such as for visual impairment, etc.)

As mentioned, this is exactly how it's done in iTerm2, and in fact after many years of using iTerm2, I never even noticed that the separate cursor text colour is a thing until I noticed the absence of it in Windows Terminal.

Actually, the v1.18 preview version implements a separate colour for the character under the cursor (also discussed in #7118), however, the colour is automatically determined and it changes based on the native colour of the text. It seems to be sometimes the inverse of the text colour (e.g. blue becomes red, purple becomes green, etc.), in other cases it's just a colour that contrasts well with the cursor. This actually almost solves the problem, however, contrast could sometimes still be better and the changing of the colour might be more distracting than helpful.

So, in summary, the added complexity of determining the colour automatically doesn't really provide any benefit, and the much simpler solution of just setting the cursor text colour explicitly would most probably provide the better result, including being more transparent and deterministic.

@avih
Copy link

avih commented Aug 25, 2023

Allow filled box cursors to display the glyph under them in

an arbitrary color (cursorForeground)

Except for cases where the block cursor background color can change (are there such cases?) this might be the most bullet-proof solution. It might require some user input in choosing that color, but it guarantees fit for purpose for this user.

However, it does have one disadvantage: the original fg color is lost completely. For some it might be still fine, while others might prefer to show the original color (or some variant of it) where possible.

the terminalBackground color

This would probably be a good simple solution if the user doesn't have control over it. It would fit with the theme, and, assuming the chosen cursor bg color has reasonable contrast with the terminal bg (which might not be true), would result in useful contrast.

inverted colors (like, rgb(255, 255, 255) - pixelColor or whatever)

This might sound reasonable, but actually, IMHO this never worked as a general solution in practice. For instance, red is never a good contrast to cyan (blue+green), etc. Also, obviously, 127,127,127 might not be the best contrast to 128,128,128...

a sane color contrast

As history shows in the other bugs, this is much much tricker than it seems at first.

The biggest contrast is when the chosen color is either exactly white or exactly black. These are the luminance extremes, and one of them would have the greatest distance from the luminance value of the BG color.

However, at these extremes, it could feel out of place with the theme. For instance, with a muted theme, a full white or full black could be jarring (but might also be exactly what the user prefers, who knows?!)

But if we stick to this approach, then it might be best to allow some configuration of the desired minimum contrast to the FG text.

As such, the final FG color is probably someplace between the original FG color and white or black (whichever has the biggest contrast to the BG).

But, it's important to keep in mind that the luminance value is not (R+G+B)/3. That's because the channels don't have the same brightness.

For instance, green is about 6 times brighter than blue.

A simplified formula to get the brightness is:
Grayscale = 0.299R + 0.587G + 0.114B

(I'm not a colorspace expert, so this formula should be taken with a grain of salt)

And so, the best contrast for full-green might be black, while the best contrast to full-blue might be white.

So a solution based on such approach might "push" the original FG color towards either white or black until it reaches some desirable luminance distance from the configured BG color.

This would both keep the original FG color where it already has enough contrast, and might also keep the general fg color even when it's modified to increase the contrast.

So bottom line, the best solution is probably to allow two modes of FG color:

  1. Let the user choose one.
  2. Apply automatic contrast of the FG to some configurable level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Rendering Text rendering, emoji, complex glyph & font-fallback issues Area-Settings Issues related to settings and customizability, for console or terminal Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal.
Projects
None yet
Development

No branches or pull requests

5 participants