Compositing XUL chrome with Windows chrome?

Talk about code development, features, specific bugs, enhancements, patches, and similar things.
Forum rules
Please keep everything here strictly on-topic.
This board is meant for Pale Moon source code development related subjects only like code snippets, patches, specific bugs, git, the repositories, etc.

This is not for tech support! Please do not post tech support questions in the "Development" board!
Please make sure not to use this board for support questions. Please post issues with specific websites, extensions, etc. in the relevant boards for those topics.

Please keep things on-topic as this forum will be used for reference for Pale Moon development. Expect topics that aren't relevant as such to be moved or deleted.
User avatar
fuzzlesnuz
Hobby Astronomer
Hobby Astronomer
Posts: 20
Joined: 2022-06-07, 21:18

Compositing XUL chrome with Windows chrome?

Unread post by fuzzlesnuz » 2022-06-22, 04:27

Premise
<speculation>It seems to be impossible to change the way a XUL control blends with the chrome of the window it lives within. All XUL elements appear to be composited on an intermediary surface, which in turn is composited with the window's surface using normal alpha blending. In PM, the root <window> element's background seems to be the lowest "layer" on that intermediary surface.</speculation> This is demonstrated by the gif below. If someone knowledgeable can confirm/correct this, that would be great.

I would like to know if it possible for PM to skip the intermediary surface and draw directly to the window's surface, including over the window chrome. The intended effect is to allow individual XUL elements to make use of mix-blend-mode to always blend with whatever is below them, which may or may not include part of the window's caption area. Given that the toolbars and buttons in the default PM theme are already half transparent, that the XUL <window> already extends into the window caption, and that PM already draws over the caption area with the appbutton and with Tabs on Top mode, it looks like maybe most or all the pieces of the puzzle already exist for this to be achieved.

Demo of the behavior outlined by the first paragraph
I couldn't find any way to inline a proper media format, like a video, into these forum posts, so please excuse the utterly massive gif. As far as gifs go, it's actually exceptionally optimized :lol:
Image
In this demonstration, I set the home button to use the difference blend mode. The blend mode does not produce the intended result until I disable 3 specific CSS properties on the root XUL <window>. Re-enabling any one or any combination of those properties nullifies the difference blend mode. When the <window> has background: transparent, we can presume that the intermediary surface is filled with float4(?, ?, ?, 0) pixels, which of course results in no effective blending due to the destination alpha of 0. What puzzles me is when the other two properties are set (-moz-appearance: -moz-win-glass and -moz-appearance: -moz-win-borderless-glass). When set alone, they cause the <window> to acquire an off-white background, yet the elements on higher layers fail to blend with that off-white background. My best guess is that there is a distinct draw operation that draws that off-white color to the window surface immediately before drawing the intermediary surface to the window surface, and so the XUL elements continue to (not) blend with an intermediary surface that is always fully transparent at the top of each frame. What really puzzles me is when one of those -moz-appearances is set AND background: transparent is also set, as shown as the very end of the gif. Even through the background is not fully transparent background, the blend mode defies expectation and fails to have any visual effect. Perhaps there is a second intermediary surface at play here?

This demo is applicable to 7 and 8. I haven't tested PM on other OSes.
 
Background
I am working on a theme for PM that, in its intended form, needs control over how certain toolbar elements are blended with the underlying window chrome. For example, some elements require the multiply or screen blend mode to ensure they maintain contrast against the user's chosen window chrome color and opacity level. As far as I can tell, this is unfortunately impossible, due to the way PM effectively "atomically" blends the entire XUL <window> with the window chrome using strictly normal alpha blending. I figured it made the most sense to post this as new topic in this subforum, as opposed to in the thread I created earlier with general questions on themeing. This subject matter seems like it needs its own topic in order to be properly explored and hopefully stir up some ideas or solutions.

vannilla
Moon Magic practitioner
Moon Magic practitioner
Posts: 2181
Joined: 2018-05-05, 13:29

Re: Compositing XUL chrome with Windows chrome?

Unread post by vannilla » 2022-06-22, 11:44

I believe that is because the mode with the button on the corner, as opposed to having a menu bar, does not use a normal window but rather an undecorated (i.e. no control button in the corner, etc.) window upon which a "fake" decoration is drawn.
See if using the menu bar mode has a difference.

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 35402
Joined: 2011-08-28, 17:27
Location: Motala, SE
Contact:

Re: Compositing XUL chrome with Windows chrome?

Unread post by Moonchild » 2022-06-22, 13:25

-moz-win-glass modes use a compositor trick to composite the blurred background with the XUL elements and window background. If you disable glass, you also lose your caption buttons as a result because it will no longer provide the click-through cut-out for the caption buttons that are left to the system to be drawn in glass mode (native for Win 7 and 8). Windows 10 uses a different mode for that explicitly and caption buttons are drawn by our own code instead.
In addition, changing these modes "on the fly" does not guarantee a repaint of elements because it's not been designed with that in mind.

It's not possible to draw XUL elements directly on the native window surface because that is not how XUL window hierarchy is rendered, internally. Contrary to popular belief, theming isn't able to overcome every potential corner case of window effects and visuals when dealing with the interaction with the application frame.
You should be able to provide alpha blending of controls though, by using opacity values, but I'm not sure what exactly you are trying to do. Not all blend modes apply to widgets like they do to SVG.
"Sometimes, the best way to get what you want is to be a good person." -- Louis Rossmann
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb
"Linux makes everything difficult." -- Lyceus Anubite

User avatar
fuzzlesnuz
Hobby Astronomer
Hobby Astronomer
Posts: 20
Joined: 2022-06-07, 21:18

Re: Compositing XUL chrome with Windows chrome?

Unread post by fuzzlesnuz » 2022-06-23, 02:28

vannilla wrote:
2022-06-22, 11:44
...See if using the menu bar mode has a difference.
It does not, unfortunately.
Moonchild wrote:
2022-06-22, 13:25
...I'm not sure what exactly you are trying to do...
Here's a visual demonstration of what I am trying to do, using Internet Explorer 11, of all things.
The back and forward buttons in IE 9/10/11 have a medium-gray #8c8c8c outline to them. This assigned color never changes, yet the outline somehow is always comfortably darker than its backdrop. This is because the outline is blended multiplicatively with the window chrome. The user can have a very transparent & light chrome (as shown in the top row) or a fully opaque & dark chrome (as shown in the bottom row) or anything in between, and the back and forward buttons will maintain a very similar level of contrast with the background in all cases.
Image

This, of course, is not possible with normal alpha blending. Here is the same circle with the same #8c8c8c outline as a XUL <image/> on the url toolbar in Pale Moon.
Notice how the outline is dark-on-light when the pixels below it (from dwm) are light, but is light-on-dark when the pixels below it are dark. This is very ugly.
Image

With normal alpha blending, the only way to ensure a color is always darker than its backdrop is to make it solid black. This is also very ugly. The ideal solution, as shown in IE, is to use a medium gray and use some blend mode like multiply, screen, or overlay to blend it tastefully with the pixels below it. This ensures the control always looks good, no matter what the user's chosen window chrome color is.
Moonchild wrote:
2022-06-22, 13:25
-moz-win-glass modes use a compositor trick...It's not possible to draw XUL elements directly on the native window surface because that is not how XUL window hierarchy is rendered, internally.
Can you describe more about this "compositor trick"? I am curious to what exactly it is, and if it can be overcome in any way.

User avatar
Lootyhoof
Themeist
Themeist
Posts: 1566
Joined: 2012-02-09, 23:35
Location: United Kingdom

Re: Compositing XUL chrome with Windows chrome?

Unread post by Lootyhoof » 2022-06-23, 03:36

You might be better served by using an SVG for the button icon and border and passing it an rgba value instead of rgb for this particular use case. Or if that circle is literally just a normal CSS border with a huge border-radius, just give it a rgba value directly.

User avatar
fuzzlesnuz
Hobby Astronomer
Hobby Astronomer
Posts: 20
Joined: 2022-06-07, 21:18

Re: Compositing XUL chrome with Windows chrome?

Unread post by fuzzlesnuz » 2022-06-23, 06:14

Lootyhoof wrote:
2022-06-23, 03:36
You might be better served by using an SVG for the button icon and border and passing it an rgba value instead of rgb for this particular use case. Or if that circle is literally just a normal CSS border with a huge border-radius, just give it a rgba value directly.
At least for the circumstances where multiplicative blending is ideal, my current workaround is to use pure black with varying degrees of opacity. Under normal alpha blending, this produces a (very) rough approximation of the intended look. The shape fails to preserve the chroma of whatever is underneath it, resulting in a dry, washed-out look on colorful window chromes, but at least its luminosity blends in a way similar to what is intended.

The images in my last post are just a contrived example to show the precise difference between normal alpha blending and multiplicative blending.

As for other workarounds, one idea I had was to get the user's Windows preferences for their chosen window chrome color & opacity, then modulate that with the XUL element's color, per whatever blend mode is desired. The net effect would be, at best, the same as if blending with the windows chrome was supported, albeit in an "all or nothing" fashion. That is, not per-pixel blending, as it would properly be done. This would look most correct on Win 8, much less so on Aero or simply if the user has a lightweight skin enabled with a transparent header image. All of this, however, rides on whether or not Pale Moon is aware of the user's Windows chrome preferences and if it reports that info to addons.

User avatar
Moonchild
Pale Moon guru
Pale Moon guru
Posts: 35402
Joined: 2011-08-28, 17:27
Location: Motala, SE
Contact:

Re: Compositing XUL chrome with Windows chrome?

Unread post by Moonchild » 2022-06-23, 08:17

Create the grey value by making it black and giving at an appropriate opacity? I mean, what you really want to achieve here is that the border is "darker than the background", IIUC, which you can achieve with RGBA using black with low(er) opacity. No need for fancy blend mode operations if it's a simple overlay effect.
"Sometimes, the best way to get what you want is to be a good person." -- Louis Rossmann
"Seek wisdom, not knowledge. Knowledge is of the past; wisdom is of the future." -- Native American proverb
"Linux makes everything difficult." -- Lyceus Anubite

User avatar
fuzzlesnuz
Hobby Astronomer
Hobby Astronomer
Posts: 20
Joined: 2022-06-07, 21:18

Re: Compositing XUL chrome with Windows chrome?

Unread post by fuzzlesnuz » 2022-06-23, 23:18

Moonchild wrote:
2022-06-23, 08:17
...what you really want to achieve here is that the border is "darker than the background", IIUC, which you can achieve with RGBA using black with low(er) opacity...
This is an approximation and is my current workaround. The "darker than the background" phrase I used in my second post is a simplification of the intended effect. In the context of multiplicative blending, the meaning is usually clear, though. My reply to Lootyhoof (who offered the same suggestion as you, i.e. the workaround I am using) is more verbatim. The intended appearance, and indeed, more or less the only reason why we use multiplicative blending in design, is to blend both luminosity AND chroma tastefully between layers. Multiplying a colorful destination by a source gray or black results in a darker version of the destination color; no desaturation occurs. In contrast, normal alpha blending a source black onto a colorful destination results in a darker but also desaturated color. I hope this clarifies it. You can play around in Photoshop and observe it for yourself. The details of multiplicative blending, especially in this case (with shadows), may not be obvious at first, since it mimics the way light interacts with surfaces irl. Our monkey brains tend to have difficulty dissecting the details of things that "just look correct" when there's nothing blatantly "wrong" to compare them to. Normal alpha blending - with shadows specifically, NOT in general - is a good enough approximation that it can easily fool anyone. For me and my theme and this workaround, that's a good thing :D, but I would prefer to do it correctly for those tuned in to the fine details.
Moonchild wrote:
2022-06-23, 08:17
...if it's a simple overlay effect.
In the context of this topic, you have to be careful with the term "overlay", since it is a well-defined blend operation (that is the effectively the same as "multiply" in some situations) as well as a colloquial term for ambiguously sticking something transparent over top of something else ;)

Locked