DPMS event notification

Nick nick at kousu.ca
Fri Jan 19 14:51:31 UTC 2018


(re: https://www.mail-archive.com/xorg@lists.freedesktop.org/msg14972.html)

Hello Taylor,

I have the same problem as you! I want to hook DPMS events in X. Given that you never got any
responses to this message, I take it the answer is that it's impossible, but it's been half a
decade so I thought I'd ask again: do you, or anyone else on this list, know how to hook DPMS state
changes in X?

My use case is a little of the more-things-change-the-more-they-stay-the-same: I have a tablet and
I want it to behave like Android: to save power, it should time out and blank the screen, or react
to the power button by blanking the screen, and it should either immediately lock (using slock or
i3lock) or lock after some idle time blanked (`sleep 300; slock` or `xlock -lockdelay 300` are
equally good), and it should disable the mouse and touchscreen while blanked because it's just too easy to knock the screen while it's off and wake it back up again (and possibly tap a button in the offing).

I can blank the screen and lock it after a delay like this:

xset dpms 0 0 45
xautolock -time 5 -locker "xlock -lockdelay 300"

And make the power button trigger:

# (this is i3 syntax but you could do it with xmodmap or the Gnome GUI or whatever)
bindsym XF86PowerOff exec xset dpms force off

It's a bit grungry, because xautolock works in minutes whereas xlock and xset work in seconds, and
you have to do a mental subtraction to work out the gap between blanking and locking, but it
roughly works.

It's the bit about the touchscreen/mouse that makes this really hard. I found
https://superuser.com/questions/71704/dpms-keep-screen-off-when-lid-shut from years ago but there's
no good solutions there. I could add a `xinput set-int-prop $TOUCHSCREEN "Device Enabled" 8 "0"` to the
PowerOff trigger, but there's no place to hook it in the same way for the timeout because y; maybe I could
use two xautolocks, one to turn off the screen and mouse and one to lock later, except xautolock
specifically denies that.
Maybe I could write a "locker" that looks like

#!/bin/sh
xset dpms force off
xinput set-int-prop $TOUCHSCREEN "Device Enabled" 8 "0"
xinput set-int-prop $MOUSE "Device Enabled" 8 "0"
sleep 300
xlock

and have xautolock run that. But I'd need to be careful about trapping signals and relaying them to
children, and it still doesn't know when to re-enable the mouse -- which should be tied to the
screen being on. It would be infinitely easier if there was a dpms-events and I could just run a
script

#!/bin/sh
TOUCHSCREEN=...
MOUSE=...
dpms-events | while read event; do
case $event in
BLANK)
xinput set-int-prop $TOUCHSCREEN "Device Enabled" 8 "0"
xinput set-int-prop $MOUSE "Device Enabled" 8 "0"
;;
UNBLANK)
xinput set-int-prop $TOUCHSCREEN "Device Enabled" 8 "1"
xinput set-int-prop $MOUSE "Device Enabled" 8 "1"
;;
done

And then let X timeout and blank the screen or run "xset force dpms off" at will, or "xset force
dpms on" (which is what waking the machine by tapping a button on the keyboard or press the power
button should do).

For clues, I went digging into jwz's xscreensaver in order to see how he handles it; it turns out
he wrote his own eventing system for screensavers (see https://www.jwz.org/xscreensaver/man3.html
-> `open (IN, "xscreensaver-command -watch |"); while (<IN>) { if (m/^(BLANK|LOCK)/) { ...`), but
how that's actually implemented is on top of a huge pile of hacks and second-guessing X in order to
handle the mismash of X variants out in the wild. The main() comment
<https://github.com/Zygo/xscreensaver/blob/39809ded547bdbb08207d3e514950425215b4410/driver/xscreensa
er.c#L12> reads

> * We do this in one of three different ways: periodically
> * checking with the XIdle server extension; selecting key and mouse events
> * on (nearly) all windows; or by waiting for the MIT-SCREEN-SAVER extension
> * to send us a "you are idle" event.

The only thing it has to do with DPMS is forcing the monitor settings to match what xscreensaver
thinks they should be
<https://github.com/Zygo/xscreensaver/blob/39809ded547bdbb08207d3e514950425215b4410/driver/dpms.c#L1
0>.

So after all that, I'm pretty sure what I'm looking for doesn't exist, but I am not very familiar
with X internals so maybe there's a secret DPMSSelectInput to match XScreenSaverSelectInput. Anyone got a clue?


More information about the xorg mailing list