Search code examples
linuxeventssignalssystemgnome

In a linux/gnome setting, how can I react to system-wide events such as log offs and shut downs, before they conclude?


In an application I am developing, I want it watch for power off, lock, or suspension, and execute certain tasks before those events happen.

How does something like this look like? What do I have to listen for, where and how?

Currently, this needs to work only on Linux gnome, but I will have to extend to macOS, once that works.


Solution

  • You can use D-Bus, a message bus system, to listen for logoff, shutdown, and suspend events on a Linux system.

    To listen for logoff, shutdown, and suspend events, you can use the dbus-monitor command to listen for the appropriate signals on the org.gnome.SessionManager interface. For example, to listen for logoff events, you can run the following command:

    dbus-monitor "interface='org.gnome.SessionManager',member='SessionClosed'"
    

    This will print out a message every time a logoff event occurs. To filter the messages to only show logoff events, you can use the grep command as follows:

    dbus-monitor "interface='org.gnome.SessionManager',member='SessionClosed'" | grep SessionClosed
    

    To listen for shutdown and suspend events, you can use the following commands:

        dbus-monitor "interface='org.gnome.SessionManager',member='PrepareForShutdown'"
    dbus-monitor "interface='org.gnome.SessionManager',member='PrepareForSleep'"
    

    To execute certain tasks before the logoff, shutdown, or suspend event occurs, you can write a script that listens for these events using the dbus-monitor command and then performs the tasks you want before the event occurs.

    Here is a simple bash script that uses dbus-monitor to listen for shutdown events and execute an echo command when a shutdown event occurs:

    #!/bin/bash
    
    # Run dbus-monitor in the background to listen for shutdown events
    dbus-monitor "interface='org.gnome.SessionManager',member='PrepareForShutdown'" &
    
    # Store the PID of the dbus-monitor process
    pid=$!
    
    # Run an infinite loop to check for shutdown events
    while true; do
        # Check if dbus-monitor has exited (indicating a shutdown event has occurred)
        if ! kill -0 $pid 2>/dev/null; then
            # dbus-monitor has exited, so a shutdown event has occurred
            # Execute the command you want to run before the shutdown
            echo "Shutdown event detected, executing command..."
            # Replace "echo" with the command you want to run
            exit 0
        fi
        # Sleep for a short time before checking again
        sleep 1
    done
    

    You can change echo command to above script to command that you want.