-
Notifications
You must be signed in to change notification settings - Fork 568
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
X11: Add support for transparent windows #1803
Conversation
First, some history lesson: X11 originally did not support transparency. Visuals describe how pixel values are interpreted, but they can only describe red/green/blue components. Then, the RENDER extension came and added transparency. Now we have picture formats. That's basically the same as a visual, but it also describes an alpha component. There is a mapping between picture formats and visual. Also, there is a standard ARGB32 format that is always supported. Then came the composite extension. Classically, the X11 server "drew stuff" directly to the output, but there is no alpha compositing involved. With composite, a composite manager can request drawing to be redirected to an off-screen pixmap. The composite manager will then produce the "real" visible screen contents. And in doing so, it can take alpha values into account. This commit adds support for transparent windows to the X11 backend. For that, it has to find the standard ARGB32 render picture format and the corresponding visual. When a transparent window is created, it checks if a composite manager is running. If not, nothing changes. If everything worked out (RENDER is supported, we found the ARGB32 picture format, a composite manager is running), transparent windows are created with this visual instead of the root window's visual. When a window has a different bit depth than its parent window, it has to "fully define" its rendering. Since it has a different bit depth than its parent, the X11 server cannot just copy background and window border from the parent. Thus, when we create an ARGB32 window (which has depth=32), we are creating a window with a different depth than the root window (most likely depth=24) and have to provide some additional settings. Even though no border will be used, we still have to define its color. Signed-off-by: Uli Schlachter <[email protected]>
Signed-off-by: Uli Schlachter <[email protected]>
Just tested the transparency example, does not work on kde, xfce or picom (didn't check on others). ErrorsINFO druid_shell::platform::x11::application: X server supports Present version 1.0 INFO druid_shell::platform::x11::application: X server supports XFIXES version 5.0 DEBUG druid::localization: available locales [en-US, de-DE, fr-CA], current en-US DEBUG druid::localization: resolved: [en-US] WARN druid_shell::platform::x11::window: WindowBuilder::resizable is currently unimplemented for X11 platforms. WARN druid_shell::platform::x11::window: WindowBuilder::show_titlebar is currently unimplemented for X11 platforms. DEBUG druid::window: TextFieldToken(1) added ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: Match, error_code: 8, sequence: 107, bad_value: 38, minor_opcode: 4, major_opcode: 139 } ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: RenderPicture, error_code: 143, sequence: 108, bad_value: 58720289, minor_opcode: 26, major_opcode: 139 } ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: RenderPicture, error_code: 143, sequence: 109, bad_value: 58720289, minor_opcode: 26, major_opcode: 139 } ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: RenderPicture, error_code: 143, sequence: 110, bad_value: 58720289, minor_opcode: 26, major_opcode: 139 } ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: RenderPicture, error_code: 143, sequence: 112, bad_value: 58720289, minor_opcode: 10, major_opcode: 139 } ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: RenderPicture, error_code: 143, sequence: 114, bad_value: 58720289, minor_opcode: 10, major_opcode: 139 } ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: RenderPicture, error_code: 143, sequence: 116, bad_value: 58720289, minor_opcode: 10, major_opcode: 139 } ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: RenderPicture, error_code: 143, sequence: 118, bad_value: 58720289, minor_opcode: 10, major_opcode: 139 } ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: RenderPicture, error_code: 143, sequence: 143, bad_value: 58720289, minor_opcode: 8, major_opcode: 139 } ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: RenderPicture, error_code: 143, sequence: 146, bad_value: 58720289, minor_opcode: 10, major_opcode: 139 } ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: RenderPicture, error_code: 143, sequence: 154, bad_value: 58720289, minor_opcode: 24, major_opcode: 139 } ERROR druid_shell::platform::x11::application: Error handling event: X11 error X11Error { error_kind: Match, error_code: 8, sequence: 156, bad_value: 58720293, minor_opcode: 1, major_opcode: 148 } I think your build error can solved by commenting out the const generic data impl for array |
Thanks for testing. Since the following errors are Picture errors, I guess that Match error is a RENDER CreatePicture request. According to https://gitlab.freedesktop.org/xorg/proto/renderproto/-/blob/master/renderproto.txt
Since this PR doesn't add any CreatePicture requests, I guess that this comes from cairo. Weird...
Thanks. I didn't even look at the code to see how simple it might be to get this to work. I won't have time to investigate for the next seven days. Afterwards, I'll take a look. |
As I already quoted from the spec above:
The window in question uses visual 0x72. The picture is supposed to use format 0x26. (Both values taken from the output of
and
That looks pretty much the same to me....?
I really don't know what is going on here and will take a closer look later this week. |
The code always called Buffers::new() with a depth of screen.root_depth. While this value was always correct previously, for transparency we are using a window with depth=32. The mismatch in depths then caused RENDER's create_picture to fail down the road. For clarity, this commit also replaces a use of COPY_DEPTH_FROM_PARENT with the correct depth. This change should not actually make any difference in practice. Signed-off-by: Uli Schlachter <[email protected]>
Urgh. Turns out I was mis-reading "stuff" previously. The code was really using a wrong depth in one place ( Edit: Also: What is the "proper procedure" to handle the obvious git conflicts in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Working 🎉 . Sorry for being late.
Do you want me to merge master into this PR whenever that occurs? Should I rewrite some git history?
You can do either. We squash and merge so it doesn't matter
druid-shell/src/platform/x11/util.rs
Outdated
&& format.direct.alpha_mask == 0xff | ||
}) | ||
// Now find the corresponding visual ID | ||
.and_then(|format| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These chain are getting a bit large. is helpful to extract these into a functions that returns an Option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. You may decide on the "is it helpful". ;-)
Signed-off-by: Uli Schlachter <[email protected]>
Signed-off-by: Uli Schlachter <[email protected]>
CI fails due to |
Signed-off-by: Uli Schlachter <[email protected]>
You touched it 😅 (
let buffers = RefCell::new(Buffers::new(
- conn,
- id,
- buf_count,
- width_px,
- height_px,
- depth,
+ conn, id, buf_count, width_px, height_px, depth,
)?); |
Signed-off-by: Uli Schlachter <[email protected]>
Argh, sorry. Apparently I am not qualified to read git histories with merges. :-( |
First, some history lesson:
X11 originally did not support transparency. Visuals describe how pixel
values are interpreted, but they can only describe red/green/blue
components. Then, the RENDER extension came and added transparency. Now
we have picture formats. That's basically the same as a visual, but it
also describes an alpha component. There is a mapping between picture
formats and visual. Also, there is a standard ARGB32 format that is
always supported.
Then came the composite extension. Classically, the X11 server "drew
stuff" directly to the output, but there is no alpha compositing
involved. With composite, a composite manager can request drawing to be
redirected to an off-screen pixmap. The composite manager will then
produce the "real" visible screen contents. And in doing so, it can take
alpha values into account.
This commit adds support for transparent windows to the X11 backend. For
that, it has to find the standard ARGB32 render picture format and the
corresponding visual. When a transparent window is created, it checks if
a composite manager is running. If not, nothing changes. If everything
worked out (RENDER is supported, we found the ARGB32 picture format, a
composite manager is running), transparent windows are created with this
visual instead of the root window's visual.
When a window has a different bit depth than its parent window, it has
to "fully define" its rendering. Since it has a different bit depth than
its parent, the X11 server cannot just copy background and window border
from the parent. Thus, when we create an ARGB32 window (which has
depth=32), we are creating a window with a different depth than the root
window (most likely depth=24) and have to provide some additional
settings. Even though no border will be used, we still have to define
its color.
Signed-off-by: Uli Schlachter [email protected]
Since I can only build druid-shell and not druid, this PR only received light testing: I let it open some window and asked
xwininfo
for the window's depth. I only tested that this produces the expected result with a hardcodedtransparent: true
and with/without a composite manager. I did not actually test anything involving transparent window background, but I expect that to work since cairo should handle all that is necessary. Hopefully...