You are not logged in.
I would like to have one program run when xscreensaver locks the screen, and another when it unlocks it.
I looked at the wiki, but it does not go into that much details. How can it be done?
Offline
I'm using a simple shell script for this. It runs as a daemon in the background, checking output of xscreensaver-command periodically:
while true; do
case "`xscreensaver-command -time | egrep -o ' blanked|non-blanked|locked'`" in
" blanked") do_something_when_blanked ;;
"non-blanked") do_something_when_unblanked ;;
"locked") do_something_when_locked ;;
esac
sleep 1
done
With a little more scripting it can be run when the system starts or when X starts, but that will probably depend on your particular setup and needs.
Offline
Thanks. So "do_something_when_x" is the command, right?
But this script runs always and periodically checks status of screensaver, which is not optimal because it adds unnecessary labour.
Have you seen this? http://www.jwz.org/xscreensaver/faq.html#watch
There appears to be a way to make xscreensaver call a function while it changes status, but I know to little about scripting to be able to put this in practice.
Offline
Thanks. So "do_something_when_x" is the command, right?
Yes, just replace "do_something_when_x" with the command (or multiple commands separated by semicolon).
But this script runs always and periodically checks status of screensaver, which is not optimal because it adds unnecessary labour.
The overhead is actually quite small. There is many more CPU hungry thing running all the time on any system.
Have you seen this? http://www.jwz.org/xscreensaver/faq.html#watch
There appears to be a way to make xscreensaver call a function while it changes status, but I know to little about scripting to be able to put this in practice.
Yes, I know about that option. The idea is generally the same, your script using -watch would have to run all the time anyway, perpetually parsing the output from xscreensaver-command -watch. The only difference that some equivalent of sleep function would be called somewhere inside the program itself The solution I posted above was faster and easier to implement for me at the time I needed it, so I just use it, even though there might be a more elegant solution.
Offline
I see. And do you think that pooling this script every 5 seconds would not put any strain on cpu/battery/interrupts?
Offline
I actually use this script with 5s polling interval to set my status in IM application and I haven't notice any change in performance or power usage. If you are really concerned, you can run the script with "nice" to set lower priority, but I think it is not really necessary.
Offline
There is a problem with this solution. Turning a program on 'locked' would work fine. The problem is that after it unlocks, it is supposed to run another program, but ONLY once (once after each unlock).
With a script like that, it would be run every 5 seconds ...
Offline
There is a problem with this solution. Turning a program on 'locked' would work fine. The problem is that after it unlocks, it is supposed to run another program, but ONLY once (once after each unlock).
With a script like that, it would be run every 5 seconds ...
Well, that can be fixed quite easily:
while true; do
case "`xscreensaver-command -time | egrep -o ' blanked|non-blanked|locked'`" in
" blanked") [ $LAST != "blank" ] && do_something_when_blanked && LAST="blank" ;;
"non-blanked") [ $LAST != "unblank" ] && do_something_when_unblanked && LAST="unblank" ;;
"locked") [ $LAST != "lock" ] && do_something_when_locked && LAST="lock" ;;
esac
sleep 5
done
Now any action should only happen once after a change of state. Note that I didn't have time to test the script, so some slight fixes might be necessary
Offline
Thanks a lot! So now just save it as an exacutable and run from rc.local, .xinitrc or cron?
Last edited by Lockheed (2012-08-28 17:12:47)
Offline
Yes, now you can either start it manually each time, or you can put it in rc.local, make the systemd run it, or put it in .xinitrc, .bashrc or some other file that will start it or set it as a task in your desktop environment. IMHO it makes biggest sense to only run it when xscreensaver runs, so .xinitrc or DE startup tasks are best choices.
Offline
Great. If the program I want to run on xscreensaver lock performs some function that require root, I need to run it from rc.local which means it would run as root. Would that affect xcreensaver status read from a regular user session?
Also, one last modification - I only want those commands to be run if the system is on AC power, ie:
if grep -Fxq "1" /sys/class/power_supply/AC/online; then
I am really bad in adding stuff to scripts as I never know what should go at the beginning, end etc. How would the script with this change look like?
Last edited by Lockheed (2012-08-29 13:26:04)
Offline
Something like this? Its also an example for the -watch parameter:
#!/bin/sh
process() {
while read line; do
# ignore event when AC is online
online=$(cat /sys/class/power_supply/AC/online)
[ $online = "1" ] && continue;
case "$line" in
UNBLANK*)
echo "Unblank"
;;
BLANK*)
echo "Blank"
;;
RUN*)
echo "Run"
;;
LOCK*)
echo "Lock"
;;
esac
done
}
xscreensaver-command -watch | process
| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |
Offline
But where do I put the name of the program to run?
Also, it says "# ignore event when AC is online" but I want it to run ONLY when AC is online, not to be ignored.
Offline
But where do I put the name of the program to run?
The echo lines are the places where for your commands. Echo is great to test without doing anything.
Also, it says "# ignore event when AC is online" but I want it to run ONLY when AC is online, not to be ignored.
Change = to != in the test: [ "$online" != "1" ] You could also write it as
if [ "$online" != "1" ]; then
continue
fi
Last edited by progandy (2012-08-29 13:54:28)
| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |
Offline
Hmm. I run it in terminal, but it returned no output when xcreensaver lunched or when it locked/unlocked.
Offline
Thanks progandy! That script works great. Here is mine I'm using for setting my pidgin status.
#!/bin/bash
process() {
while read input; do
case "$input" in
UNBLANK*) /usr/bin/purple-remote "setstatus?status=available&message=" ;;
LOCK*) /usr/bin/purple-remote "setstatus?status=away&message=" ;;
esac
done
}
/usr/bin/xscreensaver-command -watch | process
I saved the script under /usr/local/bin and added it to my openbox autostart, and I'm good to go.
Offline