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

[x11] Add pseudo-transparency #4496

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

elParaguayo
Copy link
Member

@elParaguayo elParaguayo commented Oct 6, 2023

Adds a new config option, x11_fake_transparency, to emulate transparency in bars/widgets by copying the root window contents to the background of the bar/widget before rendering the contents on top.

Primary benefit of this is to prevent issues with the Systray widget which cannot currently be displayed with semi-transparent backgrounds.

Unlike the previous version, I've (largely) managed to contain the logic to the x11 backend.

Draft for now as some things to check:

  • Check behaviour when widgets don't fill bar
  • Check multiple screen behaviour (e.g. positioning)
  • Fix Systray behaviour
  • Handle wallpaper changes (both by set_wallpaper and by external commands)

Adds a new config option, `x11_fake_transparency`, to emulate
transparency in bars/widgets by copying the root window contents to the
background of the bar/widget before rendering the contents on top.

Primary benefit of this is to prevent issues with the `Systray` widget
which cannot currently be displayed with semi-transparent backgrounds.
@elParaguayo elParaguayo mentioned this pull request Oct 6, 2023
5 tasks
@elParaguayo
Copy link
Member Author

elParaguayo commented Oct 6, 2023

Getting some weird behaviour with a second screen:

  • Widget background is blank until redrawn
  • Systray background does not work on secondary monitor

EDIT: Fixed these!

@elParaguayo elParaguayo marked this pull request as ready for review October 8, 2023 07:49
@ervinpopescu
Copy link
Contributor

So far, this does not fix #2935, as can be seen in the screenshot below:
image
Expected behavior:
image
Is it a problem with the decoration, as in qtile-extras should be updated too?

@elParaguayo
Copy link
Member Author

elParaguayo commented Oct 8, 2023

I'll need to fix qtile-extras separately. Is that just the systray in a rectdecoration? Can you share the config for that decoration?

EDIT: try with the systray-pseudotransparent branch of qtile-extras.

@ervinpopescu
Copy link
Contributor

ervinpopescu commented Oct 9, 2023

Hmm, that branch still doesn't solve it... Currently my bar bg is #ffffff00 and the systray decoration config is:

decor_bg = "#1e1e2e"
RectDecoration(
    colour=decor_bg,
    radius=10,
    extrawidth=10,
    line_width=8,
    line_colour=decor_bg,
    padding_y=-3,
    padding_x=3,
    filled=True,
)

Additionally, I get issues like the one below where neither the bar nor the systray icons' backgrounds' aren't redrawn:
image
This seems to get fixed when the bar is redrawn, eg. when I trigger my MouseOverClock widget (copied directly from the docs btw).

@elParaguayo
Copy link
Member Author

Are you talking about the overlapping icon issue or an issue with rendering the decoration? I can't recreate this. Can you try disabling your compositor?

As for the bar not updating, have you pulled the latest update to this PR? I think that issue should be fixed now.

@ervinpopescu
Copy link
Contributor

ervinpopescu commented Oct 9, 2023

qtile-extras on latest version (built using makepkg -sic in ~/.cache/yay/qtile-extras-git)

$ yay -Qi qtile-extras-git | grep Version
Version         : r291.3c00b08-1
$ qtile --version
0.23.0b3.dev64+g8ce36674

The decoration renders fine, however the icons are still overlapping and I can't figure out ATM what to change for this to work. My compositor is turned off, the bar transparency is working and the bar seems to be correctly drawn (no more weird artifacts), but I would prefer using the compositor. The bar not updating was with the latest commit.

@elParaguayo
Copy link
Member Author

elParaguayo commented Oct 9, 2023

I assume you have x11_fake_transparency = True in your config.

Which apps are giving the overlapping widgets?

Are you able to post a link to your config so I can try the whole thing?

@ervinpopescu
Copy link
Contributor

ervinpopescu commented Oct 10, 2023

I assume you have x11_fake_transparency = True in your config.

Yes, I do.

Which apps are giving the overlapping widgets?

All which are updating: nm-applet, blueman-applet, mictray, pa-applet.
Of course flameshot has no problems.

Are you able to post a link to your config so I can try the whole thing?

https://github.com/ervinpopescu/dots/tree/qtile-pseudotransparency/configs/.config/qtile

I need to add something about the bar not being redrawn, I was changing the wallpapers when I noticed that, so I suppose the "fake/pseudo" stands for the bar copying the part of the wallpaper which is under it to its background, correct?

@elParaguayo
Copy link
Member Author

Thanks for the info.

You're correct about how pseudotransparency works. We copy the wallpaper to the background of the widget.

Re changing wallpaper. That would make sense as I haven't added any code to redraw the bar in that scenario yet. Are you using the built-in set_wallpaper command or an external command?

I'll take a look again and see if I can recreate the overlapping icons.

@ervinpopescu
Copy link
Contributor

ervinpopescu commented Oct 10, 2023

I'm running the wallpaper update externally. Is there too much overhead if the bar diffs the current root background every x seconds against its own background?

I suppose I should migrate to using set_wallpaper, I've been postponing qtile-related config updates for a while now. I still think the wallpaper change should be handled, whether being done internally or externally.

I'll take a look again and see if I can recreate the overlapping icons.

Thanks!

Can't figure out how to check if the imports can fail for you, so here is a trusty command for you to check them yourself (run in the qtile config root):

grep --binary-files=without-match --color=always -r --no-filename -w import | sort -h | uniq

@elParaguayo
Copy link
Member Author

elParaguayo commented Oct 10, 2023

You're right that the wallpaper change needs to be handled. It's trivial if using the set_wallpaper command (I just haven't implemented it yet) but I need to think about how to do it when it's changed by an external app. I'm reluctant to continuously poll and would prefer to see if there's some event that I can catch.

EDIT: Yes - there is an event we can use for this.

@elParaguayo
Copy link
Member Author

OK - the wallpaper change issue should be fixed (the code needs some tidying but it should work).

# Remove PropertyChange from root window's event mask if it's there
if self.eventmask & xcffib.xproto.EventMask.PropertyChange:
self.eventmask &= ~xcffib.xproto.EventMask.PropertyChange
self._root.set_attribute(eventmask=self.eventmask)
Copy link
Member

Choose a reason for hiding this comment

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

Is this what other projects use when they use pseudo transparency? Polybar perhaps?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes - they listen for the same event. I didn't know that before I wrote the code but just checked!

Copy link
Member Author

Choose a reason for hiding this comment

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

interestingly, polybar suggests that systray always uses pseudotransparency, even if the bar doesn't. I didn't think that was possible as you couldn't reparent a window with 24-bit depth into one with a 32-bit depth. I should look into that.

Copy link
Member

Choose a reason for hiding this comment

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

Nice :) happy to have that in this PR or a follow up

Copy link
Member Author

Choose a reason for hiding this comment

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

I might have a play around and see if I can add it here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Had a play. Will leave this for a follow-up!

libqtile/backend/x11/core.py Outdated Show resolved Hide resolved
Copy link
Member

@m-col m-col left a comment

Choose a reason for hiding this comment

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

Nice work :) couple comments

@ervinpopescu
Copy link
Contributor

The wallpaper change issue is fixed, with some expected artifacts while the bar updates its background. Any progress on the overlapping icons?

@elParaguayo
Copy link
Member Author

No. Because I can't recreate it!

@elParaguayo
Copy link
Member Author

@ervinpopescu Can you confirm that you get the same overlapping issue without using widget decorations? That should be the case but wanted to check.

@ervinpopescu
Copy link
Contributor

Yes, running e2fc6df without using decorations gives the same result.

@ervinpopescu
Copy link
Contributor

This minimal config (no decorations) still gives the same overlapping icons. What should I do to troubleshoot this, given that you are unable to reproduce?

@elParaguayo
Copy link
Member Author

Let me try that config. Does the issue arise when you just have a single icon in the tray or does it only happen with multiple icons?

Can you also explain what you do to trigger the issue i.e. how are you making the tray icon change?

@ervinpopescu
Copy link
Contributor

One icon triggers it and I am changing the icon based on the state of the application I guess. For example, pressing on the mictray icon is muting the microphone so the icon changes to a "cut microphone".

@elParaguayo
Copy link
Member Author

elParaguayo commented Oct 12, 2023

Interesting. I get that behaviour with your config but not mine. Needs further investigating.

EDIT: I only get the behaviour when picom is running. NB I'm also running this within xephyr.

@elParaguayo
Copy link
Member Author

elParaguayo commented Oct 12, 2023

OK - so the first issue with that config is that it has no wallpaper and so it disables pseudotransparency as it can't find a pixmap for the root window (lots of lines in the log). If you add a wallpaper and run your config, the icons behave correctly.

However, the issue returns if you run picom...

EDIT: ah, and I can now recreate with my own config. That's useful.

EDIT 2: I know what the issue is. Now I just need to work out how to fix it!

@elParaguayo
Copy link
Member Author

So, the issue is that picom is swallowing events which means a redraw of the bar is not being called. If you disable picom, you should find that this works ok.

@ervinpopescu
Copy link
Contributor

I assume I need to wait for you to push the changes, right? For me, with picom not running, this is still appearing.

@elParaguayo
Copy link
Member Author

elParaguayo commented Oct 12, 2023

That's odd. I can reliably trigger this when running picom but it works fine without it for me but maybe that's a xephyr thing.

EDIT: And there are no changes yet as I have no idea how to fix it (or if I even can fix it).

@ervinpopescu
Copy link
Contributor

Oh, okay, I misunderstood, my bad. What other application can be swallowing events? And how did you figure out that is what's happening?

@elParaguayo
Copy link
Member Author

elParaguayo commented Oct 12, 2023

I put some print statements in the parts of the widget code that trigger the bar to be redrawn. This happens when certain events are handled by the icon. Those print statements were not called once picom was running.

However, I think there may be more to this than just that. Those print statements happened when I interacted directly with the icon but I'm not sure the same applies when the icons update themselves without interaction.

@elParaguayo
Copy link
Member Author

Can you try with the blueman-applet with and without picom:

  1. toggle the powered state with busctl set-property org.bluez /org/bluez/hci0 org.bluez.Adapter1 Powered b true and false
  2. (exit and restart applet) toggle powered state with context menu from the icon.

Do you get any different behaviours?

@ervinpopescu
Copy link
Contributor

ervinpopescu commented Oct 13, 2023

Unfortunately, with or without picom, the 2 situations behave the same, even if I leave only blueman-applet in the Systray.

@elParaguayo
Copy link
Member Author

elParaguayo commented Oct 13, 2023

Then there's still something I'm missing...

Does qtile cmd-obj -o bar top -f eval -a "self.draw()" clear the issue (albeit temporarily)?

@ervinpopescu
Copy link
Contributor

Nope, nothing is changed.

@elParaguayo
Copy link
Member Author

Really?! Then I've really got no idea what's causing this.

@ervinpopescu
Copy link
Contributor

Glad we're on the same page! 😄

Copy link

This PR is stale because it has been open 90 days with no activity. Remove the status: stale label or comment, or this will be closed in 30 days.

Copy link

This PR is stale because it has been open 90 days with no activity. Remove the status: stale label or comment, or this will be closed in 30 days.

@jooooscha
Copy link

I am still experiencing this issue. Is there any new progress?

I would be willing to work on this, if anyone could summarize the current status.

@elParaguayo
Copy link
Member Author

I'm not actively working on this at the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants