mortie / swaylock-effects

Swaylock, with fancy effects
MIT License
707 stars 46 forks source link

Multihead - Main Monitor has white background instead of blurred desktop image on resume from DPMS off #22

Closed smsegal closed 3 years ago

smsegal commented 4 years ago

When resuming from DPMS off on a multihead system, my secondary monitor displays the correct blurred background image for the lock screen, but my main monitor only displays a white background image behind it.

(A hint that this might be an upstream sway problem: windows on the main monitor reports being resized to a small value during sleep, while ones on the secondary monitor do not)

Sway v1.5, swaylock-effects latest from AUR

Thanks for the help!

mortie commented 4 years ago

Hmm, I can't reproduce this. I'm running this command:

swaylock -f --screenshots --effect-blur 10x3; sleep 4; swaymsg 'output * dpms off'; sleep 4; swaymsg 'output * dpms on'

Exactly what you would expect happens for me, the lock screen is displayed, then both the primary and the secondary screens turn off, then after some seconds, the screens turn on while still showing the lock screen. What happens for you if you run that command line?

Can you give an exact series of commands which reproduces the issue for you?

smsegal commented 4 years ago

So this was a little tedious to narrow down. Using your commands from above, the issue does not occur when the sleep between dpms off and on is less than ~2 minutes. Beyond that, the monitors wake and my primary display has the white background I reported before.

smsegal commented 4 years ago

scratch that, same issue with a minute of sleep. I'll continue with the binary search :)

EDIT: Okay, with a bit of narrowing down, sleep above 5 seconds causes the primary monitor to resume with a white background. Below that, everything works as expected.

swaylock -f --screenshots --effect-blur 10x3; sleep 4; swaymsg 'output * dpms off'; sleep 6; swaymsg 'output * dpms on' white background

swaylock -f --screenshots --effect-blur 10x3; sleep 4; swaymsg 'output * dpms off'; sleep 5; swaymsg 'output * dpms on' blurred screenshot

weird.

mortie commented 4 years ago

Well, I'm definitely able to reproduce the issue. What happens for me is that, when the screen locks, everything looks perfect and the image fades in as it should; then, after dpms has been enabled for a while and then is turned off, the secondary screen starts with a transparent lock screen which fades to white, over what seems like the period of time configured using --fade-in. It makes sense that if you don't use --fade-in, you would just immediately see the screen as white.

I have some suspicions about where in the code the issue might be. I'll have to experiment a bit. Sadly, the place where I mostly encounter this issue is at work (with my laptop's display + an external display), where I can't exactly just take the rest of the day off to work on swaylock-effects :p

smsegal commented 4 years ago

Thanks for taking a look. I should have some spare time in the next couple of weeks. I might brush off my years-neglected C skills and take a look myself.

thecatwasnot commented 4 years ago

I'm seeing something that might be related to this issue. It's not exactly the same and I'm trying to pin it down better. My original issue is that swaylock-effects works as expected until dpms off and then dpms on, when the screens come on I get a black screen, no screen locker, can't unlock it. I'm running dual out on an nvidia card with the Nouveau drivers.
I tried the above command swaylock -f --screenshots --effect-blur 10x3; sleep 4; swaymsg 'output * dpms off'; sleep 6; swaymsg 'output * dpms on' and the screens never go off. The screen locker stays up and works as expected. I get the following error msg twice: 00:00:00.000 [common/ipc-client.c:67] Unable to connect to /run/user/1000/sway-ipc.1000.713.sock Is it possible that this is the same issue? Is the error message related to the original issue? I've tried looking for logs where that error might be logged but so far no luck. In the first case, running with swayidle dpms off does work, in the second it doesn't work so I think something odd is happening when I run the command manually. I'd be happy to create a new issue if needed but I was hoping to figure out better what is actually happening.

Edit: Something weird is happening. I rebooted and am not currently showing the original issue and if I try to manually run swaylock with the above command, no issue, dpms off and on also work as expected. If it pops back up I'll start a new issue.

mortie commented 4 years ago

FWIW, I'm pretty sure I understand why this happens now. The normal flow is that all the outputs are discovered first, then a screenshot is taken for each output, then the effects are applied to each screenshot, then that modified screenshot is set as the corresponding surface's background image.

That process only happens once, but swaylock-effects can receive the "a new output has appeared" event at any time. I haven't added the screenshots/effects logic to that flow, so swaylock-effects just does its normal thing when that happens (which, by default, means creating a white surface). The fade-in effect still happens with the new surface though.

As to why the external monitor disappears and reappears when using DPMS, I don't know. But it shouldn't really matter, because swaylock-effects should just handle it.

I have some ideas of how to fix it, I just haven't taken the time to look at it seriously yet.

mortie commented 4 years ago

Alright, I've spent some time actually looking into this now. I think this patch should fix it: https://github.com/mortie/swaylock-effects/commit/eb2d931b74cbfd942ec11129c3d4d6bd290d708c

Instead of doing all the screenshots at once when main runs, it does them as displays become available. It also only runs the fade in animation on the initial crop of available monitors, not monitors which become available later.

I also fixed an issue where swaylock-effects would crash if a display disappeared while the fade animation is running. I think this is actually a bug in upstream swaylock, which just happens to be triggered by my fade animation.

Anyways, could those of you who have encountered issues try out that fix/dynamic-displays branch and see if you're able to reproduce the issue there?

thecatwasnot commented 4 years ago

Apologies, mine seems to be a separate issue, if gammastep isn't running I don't see the issue I was having. Thank you for your really nice work, I love the fade in to screen blur, exactly what I was looking for.

smsegal commented 4 years ago

Thanks for the work on this @mortie!

I tried the dynamic-displays branch but no luck here. When I run the command from before (swaylock -f --screenshots --effect-blur 10x3; sleep 4; swaymsg 'output * dpms off'; sleep 6; swaymsg 'output * dpms on'), on wakeup the secondary monitor will resume to the correct blurred and locked screen, which is great. But the primary monitor that would previously wakeup to a white background now wakes up to a completely unblurred screen and swaylock doesn't respond to keyboard events. I have to switch to a different tty and restart the session from there.

mortie commented 4 years ago

@smsegal Hmm, that's weird. Could you run it with --debug and send the logs?

And could you run it under valgrind? (valgrind swaylock ...)

smsegal commented 4 years ago

Nothing shows up in the log running with --debug other than:

[
   {
     "success": true
   }
 ]

When running with valgrind the visual operation of swaylock is noticeable different (no blurred background etc) but I gather this is to be expected due to the nature of valgrind? I'm not sure if memory leaks after the resume from sleep will be captured by valgrind like this, would it still be attached to the swaylock binary that runs on resume? The output from valgrind is below:

$ valgrind -- swaylock --debug -f --screenshots --effect-blur 10x3; sleep 4; swaymsg 'output * dpms off'; sleep 6; swaymsg 'output * dpms on'
==6810== Memcheck, a memory error detector
==6810== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6810== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==6810== Command: swaylock --debug -f --screenshots --effect-blur 10x3
==6810== 
2020-10-16 11:37:05 - [main.c:1673] Found config at /home/shane/.config/swaylock/config
2020-10-16 11:37:05 - [main.c:1569] Config Line #1: ignore-empty-password
2020-10-16 11:37:05 - [main.c:1569] Config Line #2: screenshots
2020-10-16 11:37:05 - [main.c:1569] Config Line #3: clock
2020-10-16 11:37:05 - [main.c:1569] Config Line #4: timestr=%l:%M %p
2020-10-16 11:37:05 - [main.c:1569] Config Line #5: indicator
2020-10-16 11:37:05 - [main.c:1569] Config Line #6: indicator-radius=100
2020-10-16 11:37:05 - [main.c:1569] Config Line #7: indicator-thickness=7
2020-10-16 11:37:05 - [main.c:1569] Config Line #8: effect-blur=7x5
2020-10-16 11:37:05 - [main.c:1569] Config Line #9: effect-vignette=0.5:0.5
2020-10-16 11:37:05 - [main.c:1569] Config Line #10: ring-color=0b8e3f
2020-10-16 11:37:05 - [main.c:1569] Config Line #11: key-hl-color=880033
2020-10-16 11:37:05 - [main.c:1569] Config Line #12: line-color=00000002
2020-10-16 11:37:05 - [main.c:1569] Config Line #13: inside-color=00000088
2020-10-16 11:37:05 - [main.c:1569] Config Line #14: separator-color=00000000
2020-10-16 11:37:05 - [main.c:1569] Config Line #15: grace=2
2020-10-16 11:37:05 - [main.c:1569] Config Line #16: fade-in=0.2
2020-10-16 11:37:05 - [main.c:1683] Parsing CLI Args
2020-10-16 11:37:05 - [main.c:619] output name is HDMI-A-1
2020-10-16 11:37:05 - [main.c:619] output name is DP-1
2020-10-16 11:37:05 - [main.c:524] Loaded screenshot for output HDMI-A-1
2020-10-16 11:37:21 - [main.c:524] Loaded screenshot for output DP-1
==6810== 
==6810== HEAP SUMMARY:
==6810==     in use at exit: 59,792,981 bytes in 9,480 blocks
==6810==   total heap usage: 26,706 allocs, 17,226 frees, 182,636,613 bytes allocated
==6810== 
==6810== LEAK SUMMARY:
==6810==    definitely lost: 256 bytes in 1 blocks
==6810==    indirectly lost: 107 bytes in 4 blocks
==6810==      possibly lost: 5,400 bytes in 29 blocks
==6810==    still reachable: 59,787,218 bytes in 9,446 blocks
==6810==                       of which reachable via heuristic:
==6810==                         newarray           : 1,536 bytes in 16 blocks
==6810==         suppressed: 0 bytes in 0 blocks
==6810== Rerun with --leak-check=full to see details of leaked memory
==6810== 
==6810== For lists of detected and suppressed errors, rerun with: -s
==6810== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==6823== 
==6823== HEAP SUMMARY:
==6823==     in use at exit: 59,789,386 bytes in 9,475 blocks
==6823==   total heap usage: 27,408 allocs, 17,933 frees, 184,227,381 bytes allocated
==6823== 
==6823== LEAK SUMMARY:
==6823==    definitely lost: 256 bytes in 1 blocks
==6823==    indirectly lost: 107 bytes in 4 blocks
==6823==      possibly lost: 1,528 bytes in 22 blocks
==6823==    still reachable: 59,787,495 bytes in 9,448 blocks
==6823==                       of which reachable via heuristic:
==6823==                         newarray           : 1,536 bytes in 16 blocks
==6823==         suppressed: 0 bytes in 0 blocks
==6823== Rerun with --leak-check=full to see details of leaked memory
==6823== 
==6823== For lists of detected and suppressed errors, rerun with: -s
==6823== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==6811== 
==6811== HEAP SUMMARY:
==6811==     in use at exit: 49,252 bytes in 239 blocks
==6811==   total heap usage: 401 allocs, 162 frees, 111,227 bytes allocated
==6811== 
==6811== LEAK SUMMARY:
==6811==    definitely lost: 0 bytes in 0 blocks
==6811==    indirectly lost: 0 bytes in 0 blocks
==6811==      possibly lost: 1,352 bytes in 18 blocks
==6811==    still reachable: 47,900 bytes in 221 blocks
==6811==                       of which reachable via heuristic:
==6811==                         newarray           : 1,536 bytes in 16 blocks
==6811==         suppressed: 0 bytes in 0 blocks
==6811== Rerun with --leak-check=full to see details of leaked memory
==6811== 
==6811== For lists of detected and suppressed errors, rerun with: -s
==6811== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
mortie commented 4 years ago

@smsegal Alright, I've restructured how the initialization of a swaylock surface works here: https://github.com/mortie/swaylock-effects/compare/master...mortie:fix/dynamic-displays - I think it should be more correct now. I can't think of any situation where the previous fix should result in a situation where the lock screen surface doesn't appear, but there might have been a race condition in the previous fix.

Could you test the newest commit at the fix/dynamic-displays branch (that's https://github.com/mortie/swaylock-effects/commit/5eecee37767a6e6bbd5b13847c3844e1497fa147)?

If it doesn't work, could you run with --debug again? I added tracing of all the events which happens, which could be useful.

smsegal commented 3 years ago

So, some new information came to light. I was previously connecting with an HDMI cable to one monitor and a DisplayPort to another. Doing some moving around the house and destroyed the HDMI cable by accident. Bought another DP cable to replace it and lo and behold I can't reproduce the issue anymore.

While I can't reproduce anymore, at least that narrows the issue down to how the different display formats might be affecting the race condition? Don't have another HDMI cable to test with but this should help with reproducibility for someone who does.

mortie commented 3 years ago

Alright, I think after the changes in https://github.com/mortie/swaylock-effects/commit/f90adcbbbb31e5c0bcb9fa0bbdd681e43e994b75, this should be good.

Upstream also had the same image actually, but with images associated with outputs instead of screenshots. I sent a pull request upstream: https://github.com/swaywm/swaylock/pull/155 - the fix in swaylock-effects works similarly to the fix in that pull request.

I'm going to close this issue now, because I'm no longer able to reproduce any issues related to external monitors. If the issue comes up again in the future though, feel free to comment with details.