Problem

I have an external monitor attached to my Macbook at work. Frequently I would leave my desk, and for privacy I would lock my screen.

Mac would activate sleep mode shortly.

But I don’t want it to settle into sleep mode! Because when I come back it would take me more than 10 seconds to wake up the system and the monitor!

I would like to keep my screen on when I lock the screen and this behavior should ONLY be applied when I am at work.

Solution

I need a daemon running that checks if I am in the office, based on which keep screen on or let it sleep accordingly.

For the daemon, I chose to go with Screenwatcher, a daemon that executes custom scripts when screen goes on and/or off. For my use case, only execute the script when screen goes on is sufficient.

To check whether I am in the office, I check the wireless SSID the Macbook is currently connected to instead, because at work I always connect to a particular wireless SSID.

To keep screen on, a Mac utility called Caffeinate will do.

Here are the steps:

  1. brew install sleepwatcher
  2. By default, Screenwatcher reads $HOME/.wakeup for screen on actions. Create that script.
  3. brew services start sleepwatcher to start the daemon.

My wakeup script

#!/bin/bash

OFFICE_SSID="blizzard"
DEBUG_LOG_FILE="/tmp/sleep-watcher-debug"
SCREEN_ON_CMD="caffeinate -d"
OFFICE_MODE_ON_FILE="/tmp/office_mode_on"

wlan_ssid() {
    local AIRPORT_CMD="/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport"
    local SSID=`$AIRPORT_CMD -I | awk '/ SSID/ {print substr($0, index($0, $2))}'`
    echo $SSID
}

is_in_office() {
    [ "`wlan_ssid`" = $OFFICE_SSID ]
}

debug_log() {
    local MESSAGE=$1
    echo `date` $MESSAGE >> $DEBUG_LOG_FILE
}

office_mode_on_actions() {
    $SCREEN_ON_CMD &
    osascript -e "set Volume 0"
}

turn_on_office_mode() {
    if [ -f $OFFICE_MODE_ON_FILE ]; then
        debug_log "Already on office mode, exiting." && return
    fi
    touch $OFFICE_MODE_ON_FILE

    debug_log "Office mode on"

    office_mode_on_actions
}

office_mode_off_actions() {
    pkill -xf "$SCREEN_ON_CMD"
}

turn_off_office_mode() {
    if [ ! -f $OFFICE_MODE_ON_FILE ]; then
        debug_log "Already off office mode, exiting." && return
    fi
    rm $OFFICE_MODE_ON_FILE

    debug_log "Office mode off"

    office_mode_off_actions
}

main() {
    if is_in_office; then
        turn_on_office_mode
    else
        turn_off_office_mode
    fi
}

main

Future improvements

The script provides the framework to add automatic tasks later that are office-specific. For example, along with keeping screen on in the office, I mute the system volume as well to avoid embarrassing myself when accidentally turning on music >.<