Menü schliessen
Created: January 15th 2025
Last updated: January 15th 2025
Categories: Linux
Author: Marcus Fleuti

Linux Mint - Cinnamon Screensaver - Execute Script based on Screensaver Status (lockscreen)

Donation Section: Background
Monero Badge: QR-Code
Monero Badge: Logo Icon Donate with Monero Badge: Logo Text
82uymVXLkvVbB4c4JpTd1tYm1yj1cKPKR2wqmw3XF8YXKTmY7JrTriP4pVwp2EJYBnCFdXhLq4zfFA6ic7VAWCFX5wfQbCC

Introduction

In the Linux Mint environment, automating script execution based on system events can significantly enhance productivity and system management. One common requirement is to control scripts based on whether your screen is locked or active. This guide presents a comprehensive solution for Linux Mint users who want to automatically manage script execution based on the screensaver status.

Understanding the Need

Have you ever needed to run certain scripts only when your screen is locked, or conversely, ensure that specific processes stop when you return to your computer? This automation can be particularly useful for various scenarios:

  • Running backup processes when the system is idle
  • Executing resource-intensive tasks during inactive periods
  • Managing system maintenance scripts during locked screen states
  • Controlling background processes based on user presence

Technical Requirements and Prerequisites

Before implementing this solution, ensure you have:

  1. Linux Mint 22 (or newer) with Cinnamon desktop environment
  2. Cinnamon screensaver installed and configured
  3. Basic understanding of Bash scripting
  4. Root access (in case you want your script to be run as root with SUDO)

Important Note on User Sessions

One crucial aspect of this implementation is the requirement to run the script as the currently logged-in user. This is not just a preference but a technical necessity. The script relies on the cinnamon-screensaver command to detect the screensaver status, which is tied to the user's desktop session.

Running the script as root or another user will fail because:

  1. The screensaver status is specific to the user's session
  2. The command needs access to the user's D-Bus session
  3. Desktop environment variables are user-specific

Implementation Overview

The solution consists of two main components:

  1. A controller script that monitors the screensaver status
  2. The target script (referred to as "myscript") that will be controlled

Key Features

  • Continuous monitoring of screensaver status
  • Configurable execution with or without sudo privileges
  • Graceful process management with proper termination signals
  • Robust error handling and status reporting
  • Flexible configuration options

Script Configuration

The script includes several configurable parameters:

Sudo Configuration

The script provides flexibility in execution privileges through a simple configuration variable:

USE_SUDO=false

Set this to true if your controlled script requires elevated privileges. When enabled, ensure proper sudoers configuration is in place. See script code below to find examples for such configurations.

Additional Configuration Options

  • POLL_TIMER: Defines the interval between status checks
  • SCREENSAVER_INACTIVE_RETURN_STRING: Language-dependent status string. The return value of the cinnamon-screensaver-command command is language specific and needs to be adapted according to your environment (users' language).
  • MYSCRIPT_PATH: Path to the script being controlled

Implementation Details

#!/bin/bash

### Sudoers Configuration
### Add these lines to /etc/sudoers.d/yourFile to enable passwordless execution (only needed if USE_SUDO=true):
#ALL ALL = NOPASSWD:/path/to/myScript.sh *
#ALL ALL = NOPASSWD:/usr/bin/killall -HUP myScript.sh

### Script Configuration

# Define whether commands should be executed with sudo
# Set to 'true' if the script needs elevated privileges, 'false' otherwise
# Note: If enabled, ensure proper sudoers configuration is in place to avoid password prompts
USE_SUDO=false

# Path to the script that should be controlled
# Note: Do not include 'sudo' here - it will be added automatically if USE_SUDO=true
MYSCRIPT_PATH="/path/to/myScript.sh"

# Construct the execution command based on sudo setting
if [ "$USE_SUDO" = true ]; then
    MYSCRIPT_EXEC="sudo ${MYSCRIPT_PATH}"
else
    MYSCRIPT_EXEC="${MYSCRIPT_PATH}"
fi

# Time in seconds between screensaver status checks
POLL_TIMER=3

# Define the string that indicates an inactive screensaver
# Note: This string is language-dependent. Verify the exact wording by running
# 'cinnamon-screensaver-command -q' in your terminal
SCREENSAVER_INACTIVE_RETURN_STRING="inaktiv"

# Function to check if a process is running
# Returns 0 if process is running, 1 if not
check_process_running() {
    if [ -z "$1" ]; then
        echo "Error: No process path provided" >&2
        return 1
    fi
    # We use MYSCRIPT_PATH directly since we only want to check the base process
    pgrep -f "$MYSCRIPT_PATH" > /dev/null
    return $?
}

# Function to start the script
# Includes error checking for script existence
start_script() {
    if [ ! -f "$MYSCRIPT_PATH" ]; then
        echo "Error: Script file not found at: $MYSCRIPT_PATH" >&2
        return 1
    fi
    echo "Starting script: $MYSCRIPT_EXEC"
    ${MYSCRIPT_EXEC} 2>&1 &
}

# Function to stop the script using HUP signal
stop_script() {
    local script_name=$(basename "${MYSCRIPT_PATH}")
    local kill_cmd="killall -HUP"
    
    if [ "$USE_SUDO" = true ]; then
        kill_cmd="sudo $kill_cmd"
    fi
    
    echo "Stopping script: $script_name"
    # First try to kill the direct process
    ${kill_cmd} "$script_name" 2>/dev/null
    
    # Wait briefly to ensure process is terminated
    sleep 0.1
    
    # Check if process is really stopped
    if ! pgrep -f "$script_name" > /dev/null; then
        echo "Process terminated gracefully"
        echo "Successfully stopped all instances of $script_name"
    else
        echo "Warning: Some instances of $script_name might still be running"
        
        # If the script was started with sudo, we might need to kill the sudo process too
        if pgrep -f "sudo.*$script_name" > /dev/null; then
            echo "Found sudo process - stopping it as well"
            sudo killall -HUP "sudo" 2>/dev/null
        fi
    fi
}

# Main loop function
# Continuously monitors screensaver status and manages script execution
main_loop() {
    echo "Starting screensaver monitoring..."
    echo "Using inactive string: '$SCREENSAVER_INACTIVE_RETURN_STRING'"
    echo "Running with sudo: $USE_SUDO"
    
    while true; do
        # Get screensaver status
        SCREENSAVER_STATUS=$(cinnamon-screensaver-command -q)
        
        # Check for command execution error
        if [ $? -ne 0 ]; then
            echo "Error: Failed to get screensaver status" >&2
            sleep $POLL_TIMER
            continue
        fi

        if [[ "${SCREENSAVER_STATUS}" == *"${SCREENSAVER_INACTIVE_RETURN_STRING}"* ]]; then
            # Screensaver is inactive (screen is active)
            if check_process_running "$MYSCRIPT_PATH"; then
                echo "Screen is active - stopping script"
                stop_script
            fi
        else
            # Screensaver is active (screen is locked)
            if ! check_process_running "$MYSCRIPT_PATH"; then
                echo "Screen is locked - starting script"
                start_script
            fi
        fi

        sleep $POLL_TIMER
    done
}

# Trap Ctrl+C and cleanup
cleanup() {
    echo -e "\nReceived interrupt signal. Cleaning up..."
    stop_script
    exit 0
}

trap cleanup INT TERM

# Start the main loop
main_loop

Autostart

Simply add this script to your Linux Mint Autostart using the Startup App integrated in your system.

Common Issues and Solutions

Permission Denied Errors

If you encounter permission issues:

  1. Check file permissions on the target script (recommended: 0755)
  2. Ensure proper sudoers configuration if using sudo

Screensaver Detection Issues

If the script fails to detect screensaver status:

  1. Confirm cinnamon-screensaver is installed and running
  2. Verify the correct inactive string for your language
  3. Check if the script is running in the correct user session

Alternative Solutions Comparison

Feature This Solution Cron Jobs systemd Timers
User Presence Detection Yes No Limited
Real-time Response Yes No Partial
Session Awareness Yes No Partial

Best Practices and Tips

  1. Always test the script with non-critical processes first
  2. Use absolute paths in your script configurations
  3. Implement proper logging for troubleshooting
  4. Consider adding error notification mechanisms
  5. Regularly verify the screensaver detection string matches your system's language

Conclusion

This solution provides a robust way to automate script execution based on screensaver status in Linux Mint. While primarily designed for Linux Mint with Cinnamon desktop, the concepts can be adapted for other desktop environments with similar screensaver implementations.