i3 / i3lock

improved screen locker
https://i3wm.org/i3lock
BSD 3-Clause "New" or "Revised" License
918 stars 399 forks source link

windows get shown on top when compton is active #204

Open bebehei opened 5 years ago

bebehei commented 5 years ago

Current Behavior

Windows appearing after i3lock's start and in combination with compton will get shown on top. When compton is not active, the behavior is not seen.

Here's a screenshot of a clean Ubuntu VM with the reproduction instructions executed:

screenshot-bionic

Expected Behavior

Windows shall get drawn below i3lock.

Reproduction Instructions

# On a clean Ubuntu 18.04 installation
$> sudo apt install i3-wm i3lock i3status dunst compton

# And after i3 login:
$> compton -c &
$> dunst &
$> (sleep 7 && notify-send a b) &
$> i3lock

Environment

Output of i3lock --version:

$> i3lock --version
i3lock: version 2.10 (2017-11-25) © 2010 Michael Stapelberg

Related

130

Originally reported on dunst-project/dunst#553

Airblader commented 5 years ago

@stapelberg Why did we want to open a new issue here? We fixed it, it broke stuff, we reverted it. I'm not sure what else there is to do?

stapelberg commented 5 years ago

Can’t we find a new fix which doesn’t break? Or at least document the defect.

bebehei commented 5 years ago

Oh, shit, I forgot the most important part: I cannot reproduce it on ArchLinux.

I've also cloned now i3lock's repo and tested the following tags/branches: 2.9.1, 2.10, 2.11.1, master. All show the same bad behavior in the Ubuntu VM.

I believe it's a problem in the coupling of some library, which is used by Ubuntu 18.04.

bebehei commented 5 years ago

Sorry, my browser lagged. About "the library": I can definitely exclude compton: ArchLinux uses a fork of compton. I've compiled the fork on Ubuntu 18.04, but it doesn't help either.

Airblader commented 5 years ago

@stapelberg The author of xsecurelock commented on #96 and said that they also have the problem with different compositors and different configs thereof. His idea (for xsecurelock) was to maybe make it a flag whether to use the overlay window or not. That's about the only thing I can think of.

4goettma commented 5 years ago

I can partially confirm the descriped behaviour on Arch Linux. (I'm using compton with compton -b --dbe, not sure whether it works too with compton -c. I had also cases where I can't confirm the behaviour, I will do soon further tests.)

$> i3lock --version
i3lock: version 2.11.1 © 2010 Michael Stapelberg
$> compton --version
v4-rc1-14-gf834cf2
$> uname -a
Linux <hostname> 4.18.16-arch1-1-ARCH #1 SMP PREEMPT Sat Oct 20 22:06:45 UTC 2018 x86_64 GNU/Linux
bebehei commented 5 years ago

I can finally reproduce it on my own setup now, too. :see_no_evil:

Same compton and i3lock version, but Linux kernel 4.19.2-arch1-1-ARCH.

Airblader commented 5 years ago

@stapelberg How do you feel about hiding it behind a flag? We have a PR for that now.

stapelberg commented 5 years ago

I’m not a fan of flags for bugfixes.

Ideally, the fix would work in all environments. The next best thing is if the code can auto-detect where the fix works.

Have we really exhausted all approaches yet?

Airblader commented 5 years ago

I didn't try to research this more, but with my current knowledge I can't think of anything else to try. @divVerent has the most knowledge about this with xsecurelock as far as I can see, and so his comment on #96 is the best information available to me.

Apart from a flag he suggested detecting the compositor, but that won't work in my opinion: 1) Only enabling it if no compositor is present kills the entire usecase since we usually only see this issue when a compositor is running and 2) if used a whitelist and didn't whitelist compton we might as well not bother at all, because compton is by far the most common compositor used with i3lock.

Looking at xsecurelock right now, some things seem to have happened:

  1. It uses composite by default now but has an option to disable it.
  2. There's an obscurer window feature, which sounds like what i3lock is doing too (didn't look in detail though). Noteworthy here is that the obscurer window is 1px smaller to prevent the compositor from unredirecting (I have no idea what that means)
stapelberg commented 4 years ago

Finally got a chance to look at this in a little more detail. IIUC, compositors are supposed to be transparent (conceptually, not visually) as far as X11 programs are concerned.

The relevant difference when running with a compositor vs. running without a compositor is that i3lock’s raise_loop is no longer notified of the i3lock lock window being obscured by another window: https://github.com/i3/i3lock/blob/f6e0218fa7a4a6045792e61bcae10e16d34dcd2b/i3lock.c#L952-957

It’s not 100% clear to me why these notifications are no longer sent by the X11 server when compositing is used, but I do see that compton has its own concept of a window stack: https://github.com/yshui/compton/blob/93f0d80572e47a1297dbf1af18a4ef498fa0bfe2/src/win.c#L1742-L1779

@yshui What do you think about synthesizing VisibilityNotify X11 events when compton’s window stacking changes? Do you know how other screen lockers work with compton, if they do?

yshui commented 4 years ago

I am not familiar with synthesizing X11 events, if you could point me to information about how I can do that, it would be appreciated. (Looks like I just need to use xcb_send_event?)

This behavior of X server surprises me. Do we know exactly why the X server is doing that? Is this actually a X server bug?

Relevant code seems to be: https://gitlab.freedesktop.org/xorg/xserver/blob/master/mi/mivaltree.c#L196-200 and https://gitlab.freedesktop.org/xorg/xserver/blob/master/mi/mivaltree.c#L482

stapelberg commented 4 years ago

I am not familiar with synthesizing X11 events, if you could point me to information about how I can do that, it would be appreciated.

Have a look at https://github.com/i3/i3/blob/0b4d4e799b4c4608cf4309624191e73711e48d6b/src/xcb.c#L90-L111 for how we do it in i3.

I haven’t looked at the X server implementation yet.

yshui commented 4 years ago

Does this problem only occur when using compton? How does other compositors deal with this problem?

divVerent commented 4 years ago

There's an obscurer window feature, which sounds like what i3lock is doing too (didn't look in detail though). Noteworthy here is that the obscurer window is 1px smaller to prevent the compositor from unredirecting (I have no idea what that means)

FYI the point of the reduced size is that some compositors - especially kwin - hide the composite overlay window when there is a window that occupies the entire screen, thereby making the screen lock transparent too.

So if the obscurer window had full size, we'd end up in situations where the entire screen is white (in case of xsecurelock, as that's the obscurer window's color); with the reduced size, the composite overlay window stays active and its child windows (which xsecurelock created) get drawn.

However, i3lock is much simpler than xsecurelock, so for i3lock I'd actually suggest another approach: why not have a full-sized obscurer and draw the login BOTH on the obscurer AND on a full-size child of the composite overlay window? That actually should be more compatible than what xsecurelock does, and will work because there's not much of a cost to drawing everything twice.

Of course, no matter what, i3lock should also detect events that indicate that another window is obscuring it (by bringing itself to front while locked). For that reason xsecurelock listens to VisibilityNotify.

yshui commented 4 years ago

Of course, no matter what, i3lock should also detect events that indicate that another window is obscuring it (by bringing itself to front while locked). For that reason xsecurelock listens to VisibilityNotify.

i3lock does exactly that. the problem here is the VisibilityNotify is not sent when a compositor is active.

yshui commented 4 years ago

draw the login BOTH on the obscurer AND on a full-size child of the composite overlay window?

this is both brilliant and absolutely terrifying.

stapelberg commented 4 years ago

FYI the point of the reduced size is that some compositors - especially kwin - hide the composite overlay window when there is a window that occupies the entire screen, thereby making the screen lock transparent too.

I don’t fully understand this yet: doesn’t hiding the composite overlay window mean that the screen locker window is visible? Where does transparency come into the picture?

(Also, is kwin’s rationale that full-screen applications are often 3D games or otherwise hardware-accelerated programs?)

However, i3lock is much simpler than xsecurelock, so for i3lock I'd actually suggest another approach: why not have a full-sized obscurer and draw the login BOTH on the obscurer AND on a full-size child of the composite overlay window?

Are compositors actually okay with X11 clients creating child windows of the composite overlay window?

I’m asking because making i3lock’s lock window (we only have a single window right now, no separate obscurer window) a child of the composite overlay is what we have tried previously, but that flickers — sometimes the composite overlay window will be visible, sometimes i3lock (whichever draws most recently, I suppose?).

stapelberg commented 4 years ago

Does this problem only occur when using compton? How does other compositors deal with this problem?

I can reproduce the issue with unagi, too. Are there any others that would be good to test?

If you want to run the test yourself, here’s how I trigger the problem (using SSH and one terminal per command for convenience):

DISPLAY=:0 dunst &
DISPLAY=:0 compton --experimental-backends --log-level DEBUG
DISPLAY=:0 i3lock --debug -n
DISPLAY=:0 notify-send test
stapelberg commented 4 years ago

Relevant code seems to be: https://gitlab.freedesktop.org/xorg/xserver/blob/master/mi/mivaltree.c#L196-200 and https://gitlab.freedesktop.org/xorg/xserver/blob/master/mi/mivaltree.c#L482

Here are Xorg’s SendVisibilityNotify calls when dunst obscures i3lock (without a compositor running): https://gist.github.com/stapelberg/38c8320608d3bd0cc5dcb3206f3a6484

When a compositor is running, the breakpoint is only hit once: https://gist.github.com/stapelberg/06bf82b1e9cec104772a0b80411631ac

The first breakpoint hit in each of these gists is the event being sent to the window itself (as per the pWin pointer values).

Here are the results of running p *pWin whenever https://gitlab.freedesktop.org/xorg/xserver/blob/3340ddf37743fdf197dfc16a97107435ff53c6e4/mi/mivaltree.c#L678 is hit:

https://gist.github.com/stapelberg/6d3ffa21c636c00151132b54d8bed4b6 (without compositor) https://gist.github.com/stapelberg/2d07cfd9862f0b4fff91ba2deb291325 (with compositor)

I’m out of time for now, but perhaps something sticks out to you?

yshui commented 4 years ago

I can reproduce the issue with unagi, too.

I think this is strong enough evidence this is not a compton issue.

I’m out of time for now, but perhaps something sticks out to you?

If I read the code correctly, when a compositor is running, window are always considered fully visible. Your debugger output seems to confirm this. Without compositor, you can see some visibility = 1 (VisibilityPartiallyObscured), with compositor, visibility is either 3 (VisibilityNotViewable) or 0 (VisibilityUnobscured)

yshui commented 4 years ago

Whether this is an intentional behavior of X server, I don't know. I certainly cannot find any documentation about it.

stapelberg commented 4 years ago

Thanks for looking into it. I have filed https://gitlab.freedesktop.org/xorg/xserver/issues/922, so hopefully we’ll hear from xorg folks about whether this behavior is intended or a bug.

vincentbernat commented 4 years ago

As a simple workaround, I simply kill compton before i3lock and restart it after. It also fixes the issue that if the RandR settings change, i3lock doesn't end behind all the windows. i3lock is invoked by xss-lock in my case, with the -n option.

divVerent commented 4 years ago

Yeah, with a separate compositor this is always an option.

Isn't when compositor and WM are integrated though, like in many modern DEs.

On Fri, Jan 17, 2020, 05:31 Vincent Bernat notifications@github.com wrote:

As a simple workaround, I am simply killing compton before i3lock and restart it after. It also fixes the issue that if the RandR settings change, i3lock doesn't end behind all the windows. i3lock is invoked by xss-lock in my case, with the -n option.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/i3/i3lock/issues/204?email_source=notifications&email_token=AAB5NMBXM6LFB3J46CQQTZTQ6GCJVA5CNFSM4GDAD5H2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJHH7DQ#issuecomment-575569806, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB5NMFE7E5ZJWJRUVFXUB3Q6GCJVANCNFSM4GDAD5HQ .

yshui commented 4 years ago

@stapelberg I just added support for _NET_WM_BYPASS_COMPOSITOR. now i3lock can set that property to prevent picom (compton) from redirecting the window (if the user has --unredir-if-possible set), even if i3lock is obscured by another window.

this should solve this problem.

divVerent commented 4 years ago

On Sat, Jan 18, 2020, 13:15 yshui notifications@github.com wrote:

@stapelberg https://github.com/stapelberg I just added support for _NET_WM_BYPASS_COMPOSITOR. now i3lock can set that property to prevent picom (compton) from redirecting the window (if the user has --unredir-if-possible set), even if i3lock is obscured by another window.

this should solve this problem.

Does that actually work against transparent windows covering it? How do those get rendered then?

Because this does sound interesting for sure.

You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/i3/i3lock/issues/204?email_source=notifications&email_token=AAB5NMD5KMOZFDW6I5ZWXYDQ6NBLBA5CNFSM4GDAD5H2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJJ6VIY#issuecomment-575924899, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB5NMEEKKVK536BCYDZEXDQ6NBLBANCNFSM4GDAD5HQ .

divVerent commented 4 years ago

The spec BTW says about this option:

"but MUST NOT bypass if it would cause differences from the composited appearance"

So in theory this should not be able to fix any bug related to locking.

Practice may look different though.

On Sat, Jan 18, 2020, 13:30 Rudolf Polzer divVerent@xonotic.org wrote:

On Sat, Jan 18, 2020, 13:15 yshui notifications@github.com wrote:

@stapelberg https://github.com/stapelberg I just added support for _NET_WM_BYPASS_COMPOSITOR. now i3lock can set that property to prevent picom (compton) from redirecting the window (if the user has --unredir-if-possible set), even if i3lock is obscured by another window.

this should solve this problem.

Does that actually work against transparent windows covering it? How do those get rendered then?

Because this does sound interesting for sure.

You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/i3/i3lock/issues/204?email_source=notifications&email_token=AAB5NMD5KMOZFDW6I5ZWXYDQ6NBLBA5CNFSM4GDAD5H2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJJ6VIY#issuecomment-575924899, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB5NMEEKKVK536BCYDZEXDQ6NBLBANCNFSM4GDAD5HQ .

yshui commented 4 years ago

@divVerent You are right. But compton (picom) does not implement the "MUST NOT bypass if it would cause differences from the composited appearance" bit.

Maybe you couldn't use this property to solve this problem in general, but it would work if the compositor is picom.

stapelberg commented 4 years ago

Sent pull request https://github.com/i3/i3lock/pull/256 to add the hint, I think it can’t hurt :)

ouuan commented 3 years ago

I think this is just #22 and no one has mentioned it yet?