You are not logged in.

#1 2012-08-27 10:35:44

Lockheed
Member
Registered: 2010-03-16
Posts: 1,512

Run a program on xscreensaver state change

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

#2 2012-08-27 13:18:08

dolik.rce
Member
From: Czech republic
Registered: 2011-05-04
Posts: 43

Re: Run a program on xscreensaver state change

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

#3 2012-08-27 14:21:40

Lockheed
Member
Registered: 2010-03-16
Posts: 1,512

Re: Run a program on xscreensaver state change

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

#4 2012-08-27 15:02:34

dolik.rce
Member
From: Czech republic
Registered: 2011-05-04
Posts: 43

Re: Run a program on xscreensaver state change

Lockheed wrote:

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).

Lockheed wrote:

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.

Lockheed wrote:

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 smile 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

#5 2012-08-27 15:34:35

Lockheed
Member
Registered: 2010-03-16
Posts: 1,512

Re: Run a program on xscreensaver state change

I see. And do you think that pooling this script every 5 seconds would not put any strain on cpu/battery/interrupts?

Offline

#6 2012-08-27 15:39:26

dolik.rce
Member
From: Czech republic
Registered: 2011-05-04
Posts: 43

Re: Run a program on xscreensaver state change

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

#7 2012-08-28 16:46:39

Lockheed
Member
Registered: 2010-03-16
Posts: 1,512

Re: Run a program on xscreensaver state change

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

#8 2012-08-28 16:57:18

dolik.rce
Member
From: Czech republic
Registered: 2011-05-04
Posts: 43

Re: Run a program on xscreensaver state change

Lockheed wrote:

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 wink

Offline

#9 2012-08-28 17:12:36

Lockheed
Member
Registered: 2010-03-16
Posts: 1,512

Re: Run a program on xscreensaver state change

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

#10 2012-08-28 17:29:59

dolik.rce
Member
From: Czech republic
Registered: 2011-05-04
Posts: 43

Re: Run a program on xscreensaver state change

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

#11 2012-08-29 13:17:00

Lockheed
Member
Registered: 2010-03-16
Posts: 1,512

Re: Run a program on xscreensaver state change

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

#12 2012-08-29 13:40:51

progandy
Member
Registered: 2012-05-17
Posts: 5,184

Re: Run a program on xscreensaver state change

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

#13 2012-08-29 13:46:12

Lockheed
Member
Registered: 2010-03-16
Posts: 1,512

Re: Run a program on xscreensaver state change

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

#14 2012-08-29 13:53:36

progandy
Member
Registered: 2012-05-17
Posts: 5,184

Re: Run a program on xscreensaver state change

Lockheed wrote:

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

#15 2012-08-29 15:16:55

Lockheed
Member
Registered: 2010-03-16
Posts: 1,512

Re: Run a program on xscreensaver state change

Hmm. I run it in terminal, but it returned no output when xcreensaver lunched or when it locked/unlocked.

Offline

#16 2012-10-27 12:10:48

cwgtex
Member
Registered: 2011-07-12
Posts: 4

Re: Run a program on xscreensaver state change

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

Board footer

Powered by FluxBB