fix managed windows drawing above unmanaged ones (e.g. punching through screen lockers)#233
fix managed windows drawing above unmanaged ones (e.g. punching through screen lockers)#233Nabile-Rahmani wants to merge 8 commits into
Conversation
|
Oh, this is awesome! I've noticed this behavior but haven't got my hands on it! I use screentime manager that relies on unmanaged windows, and sometimes new windows appear on top of it. I thought that it might be the issue with my app, not the wm. Thank you! |
| return; | ||
|
|
||
| Window wins[count + 1]; | ||
| wins[i++] = check; // Always prepend an oldest fake window managed by berry to inherit its lower stacking order to ensure the WM doesn't draw above unmanaged windows. Fixes things like punching through screen lockers (https://www.jwz.org/xscreensaver/faq.html#popup-windows). |
There was a problem hiding this comment.
I haven't dug into the "why" much, but the changes in this PR sadly break the functionality of the first opened window for me. The first window I open has its decorations draw above the window itself.
There was a problem hiding this comment.
Resolved in 30016c3
Only fixed when decorate is false, my bad.
Haha, I should be the one thanking you, you provided me 99% of the fix ! Sometimes the stars do align :D ... But unfortunately I've run into berry crashes and Xorg hangs introduced by 529c988 and I'm scratching my head. Did you also run into them ? BTW, polybar users need to add |
Hmm, I have not noticed any crashes or hangs, and I haven't noticed the issue with the first opened window decorations. For me it worked flawlessly. UPD: I actually use berry with decorations, check the next answer! |
I think you should try #229, it changes restack and raise functionality. I was testing merge of #223 #226 #227 #228 #229 this whole time. There were hangs that I've noticed. I'm not sure if they were introduced during #229 or #227, but they are solved in #229. Tell me, if it solves hangs or the issue with the first window for you! |
|
Thanks, I'll check it out. Here's where it crashed just in case: And the Xorg hang was spending its time in |
Ok, everything seems to be working well so far ! Great job. I'll rebase #229 onto this. ... I spoke too soon: while it fixes the crash and first window stacking, there's still a hang shared between berry & Xorg preventing me from quitting berry. berry is aggressively looping while handling IPCQuit (it doesn't exit The client linked list is somehow infinitely looping despite the next pointer being null, and the workspace loop counter never increments, because client_raise reassigns c->next to a valid window. |
|
How do I achieve that hang? If I use berryc quit, everything works without issues. I haven't noticed such behavior while testing everything and continuously closing berry. Are you testing #229 only or #233 on top of #229? Might it be the issue with your patch? Here is the log, from the side of the berry everything seems ok: |
Testing only #229: You only need two windows in the list and they'll raise each other for ever. We should either iterate an immutable copy of that list or ignore the windows we already raised so we can exit that loop, right ? Do you want me to look anything up while I still have that debugging process open ? Not sure how easily I can reproduce it. |
|
Truly, I was able to reproduce it with two windows open on quit! I'll try to look deeper into this problem! It would be nice if you'll give me more details, I'm not good at debugging, but I'll look into the code itself. |
|
Only immutable data structures can safely be iterated. Because client_raise mutates the iterator, any other loop inside berry that uses this function runs the same risk of infinitely looping. I'm not sure if there's a better way than to copy the client list into an array. Here's a video of what the code does if it helps at all (look at Source, Variables & Expressions). |
|
I'm not sure that something can theoretically change the list while it's being iterated. Berry is not a parallel program, there is no way... Or am I not understanding you correctly? If that's what you mean then the problem might be in event handling loop, not in the We are not getting |
|
client_raise is mutating our client's next pointer as it's switching places, undoing the null that's supposed to terminate the list ;) |
Null at the end of the list is set by the previous code block. I don't see any issues here. In what situation should we lose Null? Oh, I see it... |
|
Yup, in the block I pointed out ( null.mp4 |
|
Fixed it, even though it feels dirty iterating 3 lists. I'm gonna clean that up and push it, and also check other client_raise callers. |
|
I don't think your fix is correct. Don't push it. We're not losing |
|
Yup, my fix was in refresh_config, but if we can remove client_raise from it altogether that'd be ideal. |
|
Yes! We just should not use |
|
I'll push the fix to the #229! |
|
Perfect ! That's one case where Chesterton's fence doesn't apply 😆 |
56517ae to
43bdcf3
Compare
|
@JLErvin it should be good to give this another spin now ! Hopefully berry is as stable as ever. I'm stress testing this on my own. |
|
@Nabile-Rahmani @JLErvin I updated the #229 fix after some shower thoughts which confirmed that we need to call a |
|
Thanks for the heads up. Quick note: do you have to restack all workspaces or can you get away with only restacking the current workspace ? |
|
I think it's just safer to restack all of them. I tested restacking only the current one and it works unreliably for some reason. |
…gh screen lockers) Always prepend an oldest fake window managed by berry to inherit its lower stacking order to ensure the WM doesn't draw above unmanaged windows. Fixes JLErvin#231 (https://www.jwz.org/xscreensaver/faq.html#popup-windows) Depends on JLErvin#229
43bdcf3 to
b559a66
Compare
|
The first window always being on top problem reappeared. Repro in an empty workspace, spawn a window, snap it left, and spawn/move new windows around. :/ |
|
Ok, now the issue is in my commit.
BTW, Right after manage_new_window, there's another xprop on the root window tells me _NET_ACTIVE_WINDOW is window 2, and window 2 is focused, but still draws behind window 1 despite XRestackWindows getting the right order. ??? _NET_CLIENT_LIST also matches what gets passed to XRestackWindows, and window 1 is always the last in the list. Restacking works between any window except the first until it gets its focus back. I don't know if berry's check/nofocus windows have any special property that doesn't play well with that first window. It's so strange. I checked the return value of XRestackWindows just in case, and it always returns 1, with or without prepending the check window, and even when the bug is gone.
Should all managed windows be children of the check window for restacking to work properly ? |
Restacking works between any window except the first until it gets its focus back, so let's just make it happy and forget about this [nonsense](JLErvin#233 (comment)).
Always prepend an oldest fake window managed by berry to inherit its lower stacking order to ensure the WM doesn't draw above unmanaged windows.
Fixes #231 (https://www.jwz.org/xscreensaver/faq.html#popup-windows)
Depends on #229