After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 758368 - Apply dimming
Apply dimming
Status: RESOLVED OBSOLETE
Product: vte
Classification: Core
Component: general
git master
Other Linux
: Normal minor
: ---
Assigned To: VTE Maintainers
VTE Maintainers
Depends on:
Blocks:
 
 
Reported: 2015-11-19 21:21 UTC by Egmont Koblinger
Modified: 2021-06-10 15:07 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Egmont Koblinger 2015-11-19 21:21:00 UTC
Terminator allows to dim inactive panes. It does it so by redefining the palette.

This works for the basic 256 colors, but not for ones overridden by escape sequences, or RGB colors.

There could be a generic dimming value, settable strictly only via API and not via escapes, that would apply to all colors.

(Or is there some Gtk+ magic by which Terminator could do this on its own, applying a filter on top of what we draw?)
Comment 1 Christian Persch 2015-11-20 16:19:40 UTC
Dimming like the 'backdrop' shading that gtk+ applies to the chrome of unfocused windows?

I'm not opposed to adding API to do this (off by default, probably). I guess this would 'mix' the colours against the background colour (so for dark bg, make the colours darker)? Or use transparency to blend with the bg ?
Comment 2 Egmont Koblinger 2015-11-20 17:27:27 UTC
Not sure what backdrop you mean.

Dimming as Terminator does already :) Changing all the colors to a slightly darker one.

I'm not sure what algorithm they use. Probably they don't modify towards the background color, since that'd make it brighter. But I really don't know.

Maybe allow to install an arbitrary callback method that maps the RGB colors in whatever way it wants to?

(Or could something like this be done entirely from Gtk+, without help from vte? Such as placing a solid rectangle with alpha channel in front of vte?)
Comment 3 Egmont Koblinger 2015-11-20 17:28:26 UTC
... since that'd make it brighter - for light backgrounds I mean.
Comment 4 Egmont Koblinger 2015-11-21 12:10:38 UTC
Terminator simply multiplies the R, G and B components by the given factor.
Comment 5 Egmont Koblinger 2015-11-21 12:26:31 UTC
Terminator maintainer Stephen came up with a nice proof of concept of resurrecting background image support, without modifying vte. It uses some Gtk+ magic and overrides do_draw somehow to draw underneath a translucent vte.

Using the same kind of magic, I _guess_ it should be possible to place a black+alpha overlay in front of vte.
Comment 6 Egmont Koblinger 2016-04-21 21:49:08 UTC
Terminix managed to implement it nicely without vte's help:

https://github.com/gnunn1/terminix/issues/263
Comment 7 Christian Persch 2016-04-24 11:25:58 UTC
Alright, WONTFIX then.
Comment 8 Egmont Koblinger 2016-05-04 15:25:31 UTC
Terminix's solution is more problematic than we hoped for. No clue if Terminix's fault or Gtk's limitation:

https://github.com/gnunn1/terminix/issues/288

Maybe the simplest would be if vte implemented this feature, it should be really trivial. Just allow to register a callback that takes a GdkRGBA* and modifies the components in place, plus of course also takes a gpointer user_data. And invalidate_all when a new callback is installed. Then just call this callback at a few places.
Comment 9 Christian Persch 2016-05-04 15:44:06 UTC
I'd suggest to, as a test, implement this in our test app, and see if that repros or not. Might well be something terminix does wrongly.

I'd rather not have a callback that's called twice per cell painted...
Comment 10 Gerald Nunn 2016-05-04 15:59:02 UTC
I think I've fixed it in Terminix and it was indeed something I was doing wrong.
Comment 11 Egmont Koblinger 2016-05-04 16:07:36 UTC
> I'd rather not have a callback that's called twice per cell painted...

Calling the callback twice per cell might still be cheaper than applying an alpha in front of it (and computing the new color for each antialiased pixel). I don't know how applying the alpha works technically (e.g. whether it's done massively in parallel by the video card??)

We could cache it for the 256 + few (default fg, bg, etc.) colors and then only call the callback when rendering RGB. Although this would complicate our code a bit.
Comment 12 Christian Persch 2016-05-08 07:40:34 UTC
If we do implement dimming in vte, I'd say to just make it a style class that can be added/removed to/from the widget (gtk_style_context_add/remove_class) and have ::draw handle its presence by drawing the dimming over the top.
Comment 13 Egmont Koblinger 2017-09-07 10:05:24 UTC
See also https://github.com/gnunn1/tilix/issues/1110 (request for implementing "minimum contrast" as seen in Mac's Terminal.app and iTerm2).

I don't think I'd like to see VTE implementing specifically "minimum contrast" only, as the formula to be used might be really nontrivial and up for neverending discussions.

I'd still be up for a generic framework though that allows apps to do this (as well as dimming conveniently which was the original target).

For that, I believe the best approach would be the aforementioned color-mangling callback API, with the modification that it should take a (fg, bg) color pair in a single step.

Christian, would you be up for it? Okay to reopen this bug?
Comment 14 Egmont Koblinger 2017-10-08 19:13:18 UTC
There are two possible use cases for this feature that occurred to us so far:

- Minimum contrast. This was requested in Tilix's bugtracker (linked above), but apparently Tilix's maintainer is not too keen on implementing it as he's not aware of the necessary color computation algorithms.

- Dimming inactive panes. I thought Tilix implemented this by some Gtk+ magic (a translucent layer placed in front of the widget, or hijacking the draw signal), but apparently I remembered incorrectly. Both Terminator and Tilix implement this by altering the palette on focus in/out. This can be confirmed by truecolor cells not changing their colors, which is obviously a buggy user experience.

The first use case requires that we pass color pairs to the API rather than individual colors. For the second use case it doesn't really matter.

Another problematic area that occurred to me is if we ever implement any kind of image support (e.g. sixel, bug 729204).

For properly dimming inactive panes, just as it is a requirement to dim even 24-bit colors, it will also be a requirement to dim images.

The API that takes color pairs (required for minimum contrast) will be pretty much unusable for this. The other possible API, the one that takes individual colors, if called for each pixel, would be damn slow and ugly as hell.

I guess that in this case there'll need to be another API that registers a callback that takes entire images (e.g. PNGs) and return their arbitrarily modified versions. D'oh!

Or maybe we could stick to the "minimum contrast" use case only, and claim that dimming should be solved by some kind of Gtk+ overlays.

At least for now it seems that this is a very low prio issue.
Comment 15 Egmont Koblinger 2018-05-20 21:27:09 UTC
In various other bugs some issues have been raised about the lack / planned removal of bold / italic / etc. color.

We do have a "bold color" feature, but it applies to cells of the default foreground color only. It's even different from xterm's: xterm removes the bold property, while VTE keeps it. Xterm also has the possibility to change the bold of any color into a particular color.

We might end up removing this feature (bug 762247), while in the mean time some people would prefer to add "italic color" and similar ones, too. And then what if these start conflicting, e.g. a text is both bold and italic, which one should kick in?

The "color mangling API", or let's rather call it "attribute mangling API" could also offer a generic framework for this. Instead of VTE implementing whichever of these, it would delegate the decision and implementation to the container terminal emulator app.

In the previous comment I was wondering whether we should pass single colors or color pairs (fg+bg) to the mangling API. Now I rather believe we should pass color pairs (wait, we've introduced underline colors since, so color triples) plus all other attributes to mangle. (And handle images, if we'll ever have them, in some other way.) This would provide the flexibility of implementing anything along the aforementioned lines by VTE-based terminal emulator apps.

I see two issues to clarify before moving forward:

- The API (and ABI): In what format to pass/receive the colors and attributes to/from the callback? If it's some "nice" format, we'll need to unpack and pack back the bits before/after calling the method, which has a certain cost. Alternatively, we could expose our internal fields, perhaps along with helper methods or macros, but depending on how we exactly do this it might end up noticeably slow, or a further refactoring (e.g. reshuffling of the bits) might break the API and/or ABI. We'll need to carefully evaluate and pick a solution that's presumably the best for performance and future code changes.

- We'd need to figure out the proper stacking order with other means of mangling the colors, e.g. mouse highlight and its OSC 17/19, disabling blinking according to focused state, perhaps there are others as well.

As per bug 796226, the callback might also receive the coordinates of the cell in order to implement e.g. dimming beyond a certain margin, or alternating background color of rows.
Comment 16 Gerald Nunn 2018-05-20 22:18:16 UTC
Just to address one thing, Tilix originally implemented dimming by using a transculent overlay but that technique had a number of issues with it. I ended up switching it to modifying the color palette like Terminator does shortly thereafter to fix those issues.

One thought, would it be viable to have the application load multiple colors/palettes in VTE which would allow VTE to pre-compute the colors into whatever format it needs. The callback would then simply allow the containing terminal application to select a color based on a palette/color index. Not sure if this gives enough flexibility for some of the use cases that Egmont outlined though.
Comment 17 Egmont Koblinger 2018-05-21 21:29:57 UTC
(In reply to Gerald Nunn from comment #16)

> I ended up switching it to modifying the color palette like Terminator does
> shortly thereafter to fix those issues.

Which, on the other hand, has the issue that RGB true colors are left unchanged.

> One thought, would it be viable to have the application load multiple [...]

Sorry, I'm lost here, I don't quite get what you have in mind.

One thing to clarify, not sure though if relevant to understanding each other here:

I imagine the "color mangling API" not to work on the resolved RGB, but on the internal representation of colors which have 16 (legacy) + 256 (256-color) + 16M (RGB) + a few (special, e.g. default fg/bg) possible values. E.g. the mangler callback might go like "oh I see palette index 24, let's use palette index 42 instead", but might also go like "I see palette index 24, nope, let's have #abcdef instead", or "explicit RGB #000000 by escape sequence? nope let's replace it with the default fg" and so on. After this would VTE look up the palette and special colors to figure out their actual RGB.
Comment 18 Egmont Koblinger 2018-05-22 13:20:23 UTC
(In reply to Egmont Koblinger from comment #17)

> I imagine the "color mangling API" not to work on the resolved RGB, but on
> the internal representation of colors which have 16 (legacy) + 256
> (256-color) + 16M (RGB) + a few (special, e.g. default fg/bg) possible
> values.

Although, this approach sucks for implementing dimming. That would need to work on the resolved RGB.

One more nontrivial design decision to make. Sigh.
Comment 19 Gerald Nunn 2018-05-22 13:27:58 UTC
All I was getting at is that the application would be required to pre-load an array of colors that could be selected in the callback into VTE. VTE can then compute it's internal representation like it does now. When the callback is triggered, the application returns the index number into the previously loaded color array. 

It would essentially be an alternate color palette that the application containing VTE would set in advance. i.e. set_alternate_colors,

I was thinking this way VTE doesn't need to manage the colors and the conversion between representations on each callback.
Comment 20 Egmont Koblinger 2018-05-22 19:46:00 UTC
The problem is that there's so much more than 256 or so palette colors to map. For dimming even truecolor cells, you'd need to target 16M colors. For minimum contrast, which needs to map an fg+bg combo rather than the two colors separately, even if solely palette colors existed you'd need to target 256*256 fg+bg combinations. For minimum contrast on RGB, it's already 16M*16M (2^24) possible input values. And then we haven't introduced attributes yet.
Comment 21 Christian Persch 2018-05-23 20:47:59 UTC
As a demonstration, I've added a --backdrop option to vte-2.91 that makes it dim the terminal when the toplevel is in the backdrop state (not focused). Simply overdrawing with highly transparent black colour gives a nice-enough effect, IMHO.  I'm not sure what issue(s) comment 16 referred to?

The rest of the discussion has drifted a bit off course, IMHO; the discussion about colours probably belong in a different bug.
Comment 22 Christian Persch 2020-05-08 09:54:37 UTC
(It seems the issue referred to in comment 16 was https://github.com/gnunn1/tilix/issues/939 although I'm not sure I understand the actual problem there. From reading the code, it appears that tilix uses the ATOP operator with some (possibly non-black) colour, while vte-2.91 uses OVER with transparent black...)
Comment 23 Christian Persch 2020-05-08 09:57:49 UTC
.. it appears that *prior to that change*, tilix use*D*...
Comment 24 GNOME Infrastructure Team 2021-06-10 15:07:41 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/vte/-/issues/2248.