Locking Your Desktop Elegantly

Tue 12 October 2010

There are a bunch of tools that allow you to lock your desktop automatically (gnome-screensaver or xscreensaver for example), and several scripts and tools to handle locking and unlocking using bluetooth proximity, etc. One thing that always drove me crazy is that there are so many places you have to set yourself away. IRC, your IM client, and others require you to put in your AFK message. What about sound? If I'm using speakers, I don't want my music/notifications going off while I'm gone and irritate people in the office, so that needs to be muted. What about a timestamp? If I set my AFK message to be "Lunchtime, back in an hour", how does the other person know when I'll be back? Enter lockit. It's rather hackish at the moment, but I think you'll get the idea quickly and can add your own pieces.

You will notice there is some remote-access code in here. If you have multiple systems and use synergy to tie them together, making sure they all lock/unlock together is useful. This script has the ability to log on remotely and call lock-command from there.

Some ideas I've had are modules, miniscripts that get called much like the initscripts rc*.d directories. Call them with "lock" when it locks, and "unlock" when it unlocks, etc. I think that would make it modular enough and allow other languages to handle some of the work.

lockit is two scripts. 'lockit' itself just sets the AFK message and calls lock-command. lock-command does the heavy lifting, setting the AFK message for all commands.

How to use: run

lockit My Message

This will currently:

  • Set you away in xchat
  • Set your away message to: "AFK, left at 07:44 EDT : My Message"
  • Mute your pulseaudio sink (mutes all audio)
  • Set your pidgin away message to "AFK, left at 07:44 EDT : My Message"

It then goes into a monitor loop, waiting for the screensaver to unlock. When it unlocks, it sets you back in xchat and pidgin, then unmutes your audio.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/bin/bash

# Automates lock-unlock of screen using lock-command
# 2009-8-24
# Richard Monk (rmonk@redhat.com)
#

# secsToClockTime is a standard function to convert seconds to HH:MM:SS
    function secsToClockTime {
        local hoursPart
        local minsPart
        local secsPart

        if [ -z "$1" ]; then
            return 1
        else
            secs="$1"
        fi

        hours="$(( $secs / 3600 ))"
        secs="$(( $secs % 3600 ))"
        mins="$(( $secs / 60 ))"
        secs="$(( $secs % 60 ))"

        if [ "$hours" -gt 0 ]; then
            hoursPart="$hours"
        fi

        if [ "$mins" -gt 0 ]; then
            minsPart=":$(printf '%02i' $mins)"
        fi

        secsPart=":$(printf '%02i' $secs)"

        echo "${hoursPart}${minsPart}${secsPart}"
        return 0
    }


# Get message if none on the command line
    if [ -z "$*" ]; then
        awayMessage="$(zenity --entry --title="Lockit" --text="Away Message")"
    else
        awayMessage="$@"
    fi

#Record lock time
    lockTime="$(date +%s)"

# Lock the screen
    lock-command lock "$awayMessage"

# Wait for gnome-screensaver to disengage
    while gnome-screensaver-command -q | grep -q '\'; do
        sleep 1
    done

#response="$(xscreensaver-command -time)"
#echo "$(date): $response" >> /tmp/lockit.out
#while echo "$response" |  grep -q 'locked'; do
#   sleep 1
#   response="$(xscreensaver-command -time)"
#   echo "$(date): $response" >> /tmp/lockit.out
#done

    lock-command unlock

# How long were we locked? 
    lockClock="$(secsToClockTime $(echo $(date +%s) - $lockTime | bc))"
    notify-send -t 2000  "Lockit: Gone for $lockClock"
    echo "Lockit: Gone for $lockClock"


#!/bin/bash

# Set master to true if you want it to go to the hosts in $hosts
    master="false"
    hosts="remote.host.com"

# What hour does your shift start/end (afk vs gone messages)
    shiftStart="7"
    shiftEnd="4"

    PATH="${PATH}:${HOME}/bin"

# This pulls the session info from metacity.  If you use another window manager, set it in termPid
    function getEnviron {
        termPid=$(pgrep metacity)
        cd /proc/$termPid
        $(cat /proc/$termPid/environ |  tr '\000' '\n' | sed 's/^/export /' | egrep 'DISPLAY|DBUS_SESSION_BUS_ADDRESS|SESSION_MANAGER')
    }

# Sends commands to all xchat connected servers
    function xchat-allserv {
        if pgrep xchat &> /dev/null; then
                xchat-command allserv $@
        fi
    }

    case "$1" in
        lock)
            if [ "$master" == "true" ]; then
                echo "Locking $host"
                for host in $hosts; do
                    ssh $host bin/lock-command lock
                done
            else
                if [ -n "$SSH_CONNECTION" ]; then
                    getEnviron
                fi
            fi

            shift
            message="AFK, left at $(date +'%H:%M %Z') : $@"
            gnome-screensaver-command -a
            #xscreensaver-command -lock
            pgrep pidgin &> /dev/null && purple-remote 'setstatus?status=away&message='"$message"
#        amixer set 'Master',0 "mute" &> /dev/null
            # Get pulse sink
            pasink="$(pactl stat | grep 'Default Sink' | cut -d: -f2)"
            pactl set-sink-mute $pasink 1

            xchat-allserv away "$message"
            #xset dpms force off
        ;;
        unlock)
            if [ "$master" == "true" ]; then
                echo "Unlocking $host"
                for host in $hosts; do
                    ssh $host bin/lock-command unlock
                done
            else
                if [ -n "$SSH_CONNECTION" ]; then
                    getEnviron
                fi
            fi

            gnome-screensaver-command -d
            purple-remote 'setstatus?status=available&message='

            #amixer set 'Master',0 "unmute" &> /dev/null
            pasink="$(pactl stat | grep 'Default Sink' | cut -d: -f2)"
            pactl set-sink-mute $pasink 0

            xchat-allserv back
            xset dpms force on
    ;;
    esac

Category: Linux Tagged: audio bash irc linux scripting security shell

comments