WhyNotHugo / caffeine-ng

⚠ This project has migrated to codeberg.org
https://codeberg.org/WhyNotHugo/caffeine-ng
GNU General Public License v3.0
180 stars 21 forks source link

caffeine doesn't work well with xscreensaver #45

Closed protist closed 1 year ago

protist commented 4 years ago

caffeine and xscreensaver don't play together so well. Slightly related to and might be fixed by issue #2.

Steps to reproduce

  1. Enable/activate caffeine-ng
  2. Start xscreensaver. I want my system on, but the screen locked.

Expected behaviour

Observed behaviour

If I disable caffeine, xscreensaver behaves normally. Is caffeine-ng sending keypresses every 50 seconds?

Implications

This is a bit annoying, because xscreensaver displays the dialogue box frequently. It does time out after a few seconds, so it's not a very horrible issue.

However, recently this has resulted in me being locked out of the system. The output from screensaver

Aug 22 13:54:43 <hostname> xscreensaver[21031]: pam_unix(xscreensaver:auth): conversation failed
Aug 22 13:54:43 <hostname> xscreensaver[21031]: pam_unix(xscreensaver:auth): auth could not identify password for [protist]
Aug 22 13:54:43 <hostname> xscreensaver[21031]: pam_systemd_home(xscreensaver:auth): Failed to query user record: Unit dbus-org.freedesktop.home1.service not found.
Aug 22 13:55:33 <hostname> xscreensaver[21031]: pam_unix(xscreensaver:auth): conversation failed
Aug 22 13:55:33 <hostname> xscreensaver[21031]: pam_unix(xscreensaver:auth): auth could not identify password for [protist]
Aug 22 13:55:33 <hostname> xscreensaver[21031]: pam_systemd_home(xscreensaver:auth): Failed to query user record: Unit dbus-org.freedesktop.home1.service not found.
Aug 22 13:56:23 <hostname> xscreensaver[21031]: pam_unix(xscreensaver:auth): conversation failed
Aug 22 13:56:23 <hostname> xscreensaver[21031]: pam_unix(xscreensaver:auth): auth could not identify password for [protist]
Aug 22 13:56:23 <hostname> xscreensaver[21031]: pam_systemd_home(xscreensaver:auth): Failed to query user record: Unit dbus-org.freedesktop.home1.service not found.
Aug 22 13:56:23 <hostname> xscreensaver[21031]: pam_faillock(xscreensaver:auth): Consecutive login failures for user protist account temporarily locked

And then I can't dismiss xscreensaver, and am told that my account is locked due to 3 failed logins. I then tried to kill xscreensaver from another TTY, but I can't log in there either.

<hostname> login: protist
The account is locked due to 3 failed logins
(7 minutes left to unlock)
Password:
Login incorrect

And in journalctl

Aug 22 13:13:09 <hostname> audit[12896]: USER_AUTH pid=12896 uid=0 auid=4294967295 ses=4294967295 msg='op=PAM:authentication grantors=? acct="protist" exe="/usr/bin/login" hostname=<hostname> addr=? terminal=tty3 res=failed'
Aug 22 13:13:09 <hostname> kernel: kauditd_printk_skb: 4 callbacks suppressed
Aug 22 13:13:09 <hostname> kernel: audit: type=1100 audit(1598065989.781:486): pid=12896 uid=0 auid=4294967295 ses=4294967295 msg='op=PAM:authentication grantors=? acct="protist" exe="/usr/bin/login" hostname=<hostname> addr=? terminal=tty3 res=failed'
Aug 22 13:13:11 <hostname> login[12896]: FAILED LOGIN 1 FROM tty3 FOR protist, Authentication failure

What exactly is going on here? Is caffeine-ng sending fake keystrokes to the system every 50 seconds? Presumably these are then recognised by xscreensaver, and (1) bring up the login window and (2) enter the incorrect password?

WhyNotHugo commented 4 years ago

xscreensaver should run as normal, but the system should not suspend.

Uh, if caffeine is on, xscreensaver should not run normally, but be inhibited from running.

What really confuses me is why your screen gets locked despite caffeine being on. What's the timeout you've set for the screensaver to activate?

protist commented 4 years ago

Sorry, I should have been more precise. At 2. Start xscreensaver, I meant I manually start it with xscreensaver-command -lock.

WhyNotHugo commented 4 years ago

If you explicitly tell the screensaver to lock your screen while running a tool to prevent the screensaver from activating, things are bound to break.

What do you expect to happen when you issue these two contradicting commands? I don't think it's something that will ever make sense to support.

protist commented 4 years ago

Fair enough. FWIW I use caffeine-ng for two slightly different functions. Sometimes I'll use it to inhibit the screensaver, which is presumably what your intention was.

However, most of the time I'm more interested in preventing the system from suspending while lengthy jobs are running. I then often explicitly lock the screen with the screensaver, to prevent people (usually my kids!) randomly pressing keys, etc. I checked the caffeine list, and most of the triggers are indeed in this category, e.g.

In all of these cases, I don't necessarily need caffeine to prevent the screensaver, but I do need it to prevent suspend. While this might not be an obvious task for caffeine for some people, it does the task very well generally, and AFAIK the best tool for this problem.

My understanding is that issue #2 is based on a similar use case (I presume "media player" there refers to an audio player). However, I totally understand if you are uninterested in addressing this use case, since you don't use it like this yourself.

Just to confirm though, does caffeine-ng indeed work by sending keystrokes every 50 seconds? Thanks in advance.

WhyNotHugo commented 4 years ago

If you're using xscreensaver, it calls xscreensaver-command -deactivate every 50 seconds.

For other screensavers, their API is used directly.

protist commented 4 years ago

Thank you again for that information. Again, I'm not 100% how you feel about addressing this use case for caffeine-ng, but I had a few thoughts.

1) Ideally, caffeine-ng would differentiate between inhibiting the screensaver and inhibiting suspend, as per issue #2. However, I understand this might not be a priority. It would also make the UX more complicated than it is now, as both tiers of inhibition would need to be exposed. (Personally, I'd be happy to manually start the screensaver instead, presuming caffeine-ng could deal elegantly with only inhibiting suspend, and leave the screensaver alone.)

2) Alternatively, instead of spamming xscreensaver-command -deactivate in all cases, caffeine-ng could detect whether xscreensaver is running, with xscreensaver-command -time. If xscreensaver is not active, then caffeine could spam away. However, if xscreensaver is active… then there are potentially two situations:

  i. If the user is using xscreensaver's DPMS screen blanking settings, then what would be the expectation? My understanding is that there is no elegant way to leave the screensaver running, while preventing xscreensaver's DPMS. However, if the user is happy for the screensaver to run (in order to keep the screen locked), then they are probably fine with the screen blanking. In my use cases in my comment above, I would be fine with this. For me, there is no major difference between the screensaver on, or the screen blank. There *is* a major difference between the system on, or suspended though! Thus, if the screensaver is on, there is no reason to inhibit screen blanking, particularly if there is no easy way to do this without the login dialogue box issues as above.

  ii. Alternatively, the user does *not* use xscreensaver's DPMS settings, which is my case. Instead, I use KDE Plasma's screen-blanking and automatic-suspend settings. Hence, if the screensaver is on, I'd prefer caffeine-ng to not spam `xscreensaver-command -deactivate`, but instead just inhibit Plasma's auto-suspend as normal. There is an inconsistency with this result, because Plasma's screen-blanking will still be inhibited, unlike 2i.

With either 2a or 2b, caffeine-ng could check for whether xscreensaver is active, and only inhibit it if it's not. I tested the following, which seems to work fine.

--- inhibitors.py.orig  2019-11-15 20:40:26.000000000 +1100
+++ inhibitors.py   2020-08-24 10:25:49.429035901 +1000
@@ -152,7 +152,7 @@
         self.running = True

         while self.running:
-            os.system("xscreensaver-command -deactivate")
+            os.system("xscreensaver-command -time | grep -q non-blanked && xscreensaver-command -deactivate")
             time.sleep(50)

     def uninhibit(self):
protist commented 4 years ago

Also FWIW I realised that being locked out of my system related to recent changes in the default pam options in Arch Linux. faillock is now enabled by default. It seems that xscreensaver interprets a non-successful xscreensaver-command -deactivate as a login failure.

WhyNotHugo commented 1 year ago

This project has moved to codeberg.

Follow-up for this issue is at https://codeberg.org/WhyNotHugo/caffeine-ng/issues/45