Use Power Management to run xscreensaver program?

So I made a little tester for the idle time check and it always seems to return 0.

#!/bin/bash

sleep 60

loginctl show-session "$XDG_SESSION_ID" -p IdleHint -p IdleSinceHint

Which suggests I need another idle time to query, it would be neat if I could query kscreenlocker/kscreensaver or even just the runscript timer, since the settings window option regarding that is “When inactive”.

I think I may have stumbled onto a breakthrough in this, I went digging through the KDE git repos and I found this: src/wayland/idle.h · master · Plasma / KWin · GitLab It looks like it’s a perfect tool for this issue but as ever, I don’t know if or how to use it. Please help.

It appears that Plasma / Kwin do not implement neitherorg.freedesktop.ScreenSaver /ScreenSaver org.freedesktop.ScreenSaver.GetSessionIdleTime FreeDesktop D-Bus standard, nor the systemd-logind idle hint (as accessed by loginctl show-session).

The KWin’s org_kde_kwin_idle interface that you linked to is deprecated in favor of the (more) standard ext-idle-notify (see the protocol specification in the Wayland website).

I played a bit with swayidle - that uses the Wayland ext-idle-notify protocol (KWin implements that over the deprecated org_kde_kwin_idle) but it doesn’t give you the time, due to the protocol limitations, the only thing it can do is to monitor for idle notifications and launch your own program after a timeout. Worse, it doesn’t take into effect inhibitions (probably a kwin bug / protocol deficiency, not a swayidle bug) - so it will fire the idle timeout while you are watching a full screen video.

There is maybe something to be done with this, but I’m out of resources to think it through at the moment. I’ll see if I can get back to it over the weekend.

Update: ok, I spent a few more seconds thinking about this (and then 20 minutes typing this up) - the main problem is that swayidle isn’t actually implementing the counter itself, it just registers it with the Wayland server, that is in charge of the notification, and there seems to be a protocol misunderstanding (likely) or a KWin bug (less likely(*)) that if you run swayidle after the idle timeout was already supposed to fire (for example, the user has been idle for a minute, and then you ask for a 10 seconds idle timeout) - the timeout never fires.

I think you can’t use ext-idle-notify from a “activate on idle” script (mostly as you’d need to know what the idle timeout length is, in the KDE configuration and the script, and that makes no sense), but you may be able to run a script to manage the entire idle timeout processing. There is a missing part though - the naive implementation might do something like this:

  • Monitor for idle timeouts
  • When an idle timeout fires, check for inhibitions - if there are none, start the screensaver.
  • If there are any inhibitions, wait for them to finish, then…
  • Wait for another idle timeout event.

The problem is that if the user has been idle throughout the inhibition (the user started the video, then sat idle) you won’t get another timeout until the user stops being idle and then starts being idle again. Classic use case: the user started a video and then went away. They might expect that soon after the video ends, the screensaver will automatically start - but that won’t happen.

The ext-idle-notify protocol does have facilities to enable that use case: the timer object can “simulate user activity” for itself, thereby resetting the idle timeout. So the correct workflow is:

  1. Monitor for idle timeout
  2. When the idle timeout fire, if there are no active inhibitions - start the screensaver
  3. Otherwise - wait for inhibitions to end, then simulate activity (virtually wriggle the mouse)
  4. Go back to 1.

Unfortunately, as far as I can tell swayidle have to facility to do the “simulate user input” action, and I know of no otherway to script ext-idle-notify.

*) Wayland protocol designers often fail to account for all likely use cases. There’s a lengthy review process to help them do that, but this often fails :frowning: .

Maybe the correct way to handle this use case would be to add a Power Management feature to add a 4th condition for running a custom command - “When idle, and no inhibitions are active”.

I’ve just made a request to that end https://bugs.kde.org/show_bug.cgi?id=521388. My thanks again for getting us this far, I never would have expected to hit a dead end on an idle timer.

My thanks too to Skyfishgoo for pointing me in the right direction to begin with and pg-tips for correcting my quotes.

According to bug 512855 (that I wasn’t aware of), the idle command is supposed to be inhibited - or at least it is in some scenarios. I’ll follow up on that.