beengone

This is a revival of an old project of mine, rewritten for v2.0 with some updates for recent versions of macOS and with the addition of some command line flags that make scripting easier. This code is based on a post by Jean-David Gadina, on which I’ve elaborated.

beengone is a (macOS-only) CLI tool that tests how long a Mac has gone without user input (keyboard or mouse/trackpad). It detects any movement or keypress, including modifier keys. Run without arguments, it outputs the number of seconds the machine has been idle.

Current version: 2.0.8

You can print the seconds idle with no newline using -n, simulate input with -i, resetting the idle timer.

For ease of scripting, there’s a -m/--minimum=XXX option which sets a minimum number of seconds required to pass the condition. If the idle time is less than the minimum, beengone returns an error code of 1. If the minimum is met, it exits successfully with an error code of 0.

You can also pause scripts until a limit with the -w/--wait=XXX flag, avoiding having to loop and check exit codes. -w will always exit 0 once the limit is reached.

Both -m and -w accept either integer values in seconds, or strings in the format “Xd Xh Xm Xs”, representing days, hours, minutes, and seconds. Any combination can be used, and spaces aren’t required, e.g. -w 2m30s.

Usage: beengone [options]

Print the system idle time in seconds.


Options
    -n, --no-newline      print idle seconds without newline
    -m, --minimum=<str>   test for minimum idle time in
                          seconds, exit 0 or 1 based on
                          condition, accepts strings
                          like "5h 30m" or "1d12h"
    -w, --wait=<str>      wait until the system has been
                          idle for the specified number of
                          seconds, accepts strings
                          like "5h 30m" or "1m30s"
    -i, --input           simulate user input

Other
    -h, --help            show this help message and exit
    -d, --debug           print debugging info
    -v, --version         show version and exit

Here’s an example in Bash (link) using an infinite loop and the -m flag exit code.

ifgoneraw
"
#! /bin/bash

gone() {
    if [[ -n $1 ]]; then
        TIME=$1
        # loop indefinitely
        # > could also use --wait flag to wait for the user to be
        # > gone instead of looping
        while true; do
            # use the --minimum flag to generate an exit code
            # based on a minimum threshold
            beengone -m "$TIME" &> /dev/null
            # get the exit code
            retVal=$?
            # if the exit code is 0, the user has been gone
            # for the specified time
            if [ $retVal -eq 0 ]; then
                # if a command was specified, execute it
                if [[ -n $COMMAND ]]; then
                    eval "$COMMAND"
                    exit $?
                fi
                break
            fi
            
        done
        
    else
        echo "Missing argument: TIME"
        exit 1
    fi
    
    exit 1
}

POSITIONAL_ARGS=()

display_help() {
    echo "Usage: ifgone [OPTIONS] TIME"
    echo
    echo "TIME (required) is the time to wait for the user to be gone"
    echo "TIME can be formatted as XXX (seconds), XXXm (minutes), XXXh (hours), XXXd (days)"
    echo
    echo "OPTIONS:"
    echo "  -c, --command   Command to execute upon success"
    echo "  -h, --help      Display this help message"
}

while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            display_help
        ;;
        -c|--command)
            COMMAND=$2
            shift
            shift
        ;;
        -*|--*)
            echo "Unknown option $1"
            exit 1
        ;;
        *)
            POSITIONAL_ARGS+=("$1") # save positional arg
            shift # past argument
        ;;
    esac
done

set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters

gone "$1"

More examples in Bash (link).

beengone-more-examples.bashraw
"
#!/bin/bash
# Example script to test the beengone command
# Loops while checking idle time with a minimum threshold before executin a command

# Works while screen saver is running
open /System/Library/CoreServices/ScreenSaverEngine.app

while true; do
    beengone -m 3s
    if [[ $? -eq 0 ]]; then
        osascript -e 'tell application "ScreenSaverEngine" to quit'
        break
    fi
    sleep 1
done

# Pause a timer when there's no activity for a set time
timer=-1

while true; do
    beengone -m 5m
    if [[ $? -eq 0 ]]; then
        # Could be `shortcuts` or any command
        result=$(osascript -e "display dialog "End Timer?" buttons {"END", "CONTINUE"} default button "CONTINUE"" 2>/dev/null)
        if [[ $result =~ END ]]; then
            break
        fi
    fi
    sleep 1
    timer=$((timer+1))
done

osascript -e "display alert \"Timer: $timer seconds\" message \"Timer Ended\" giving up after 5"

# Using the --wait/-w flag to wait for a set time before executing a command
# This avoids the need to loop and check the idle time

beengone -w 5s
osascript -e "display alert \"Waited 5 seconds\" message \"Wait Ended\" giving up after 5"

And here’s an example for Fish (link) using the -w command to block execution until the minimum idle time is reached.

Download

beengone v2.0.8

A command-line tool to check if the user has been AFK for a given time

Published 12/23/24.

Updated 12/24/24. Changelog

DonateMore info…

The GitHub repository for this project is here, MIT licensed.

Changelog

Click to expand

beengone 2.0.8

NEW

  • Add parsing of strings like ‘3h 30m’ to –minimum
  • -i option to fake user input, thus resetting the idle timer

IMPROVED

  • More tests
  • Add debugging feedback on STDERR for –minimum
  • Make STDERR output optional with --debug flag

beengone 2.0.7

IMPROVED

  • Automation updates

beengone 2.0.6

NEW

  • Add version flag to executable

beengone 2.0.5

IMPROVED

  • Allow limit of 0
  • Fix help output (missing t)
  • Fix automation

beengone 2.0.0

NEW

  • Initial release of beengone v2, updated for use on Apple Silicon
  • Set up deploy scripts
  • Add --minimum option for scripting use

Speaking of beengone…

Related Projects