When the screen is locked in KDE (my specific version is Kubuntu but hopefully this is something that is generic Linux), is the event logged? If so where would I look to find it?
2 Answers
Use D-Bus to get lockscreen's actived/deactived signals. The name of the screen saver service will vary from system to system. In general, KDE uses org.freedesktop.ScreenSaver
and Gnome uses org.gnome.ScreenSaver
. This cannot be relied upon though, for example, Mint uses org.cinnamon.ScreenSaver
.
Helpful Commands
These assume that your screen saver is org.freedesktop.ScreenSaver
and your DBus service is org.freedesktop.DBus
. You may need to adjust this for other systems. Use the following information to find out what your system uses:
To get a list of the dbus services available in your current session, use:
dbus-send --session --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames
Add
|grep screensaver
to the end if you just want the screen saver services available.To get a list of the commands supported by your screen saver service, use:
qdbus org.freedesktop.ScreenSaver /ScreenSaver
To invoke a command, use:
dbus-send --session --dest=org.freedesktop.ScreenSaver --type=method_call --print-reply --reply-timeout=20000 /org/freedesktop/ScreenSaver org.freedesktop.ScreenSaver.SetActive boolean:true
Where
SetActive
was listed in the list of supported commands and takes a boolean value.To monitor a service:
dbus-monitor --session "type='signal',interface='org.freedesktop.ScreenSaver'"
Automation
Now that you understand how your system works, you can use a python script to log this activity into a file:
#!/usr/bin/env python
from datetime import datetime
import os
import pwd
import subprocess
import time
LOG_FILE = os.path.expanduser('~/hours_log.csv')
cmd = subprocess.Popen(["dbus-monitor \"type='signal',interface="
"'org.freedesktop.ScreenSaver'\""], shell=True,
stdout=subprocess.PIPE)
running = 0
while 1:
time.sleep(0.1)
if running:
output = cmd.stdout.readline()
status = 'unlocked' if 'true' in output else 'locked'
new_line = "{time} {user} {status} the screen\n".format(
time=datetime.now().ctime(),
user=pwd.getpwuid(os.getuid())[0],
status=status
)
with open(LOG_FILE, 'a') as f:
f.write(new_line)
running = 0
line = cmd.stdout.readline()
if "ActiveChange" in line and 'org.freedesktop.ScreenSaver' in line:
running = 1
[ Source: logging-lock-screen-events ]
It isnt logged anywhere for you, but like @krowe said, you can hook into it.
I developed this bash script which works out your setup's specifics for you, if you have this running in the background and pipe it to a log file you will have your log.
#!/bin/bash
#prints out, among other things;
# string "org.kde.screensaver"
#transform it to 'org.kde.screensaver'
service=$(\
dbus-send \
--session \
--dest=org.freedesktop.DBus \
--type=method_call \
--print-reply \
/org/freedesktop/DBus org.freedesktop.DBus.ListNames \
| grep -o '[^"]*.screensaver'
)
#prints out, among other things;
#method bool org.freedesktop.ScreenSaver.SetActive(bool e)
#transform it to 'org.freedesktop.ScreenSaver'
interface=$(
qdbus \
$service /ScreenSaver \
| grep -oP '[^ ]*(?=.SetActive)'
)
path='/ScreenSaver'
#monitor it with a while loop
dbus-monitor "type='signal',interface='$interface',member='ActiveChanged',path='$path'" \
| while read -r line; do
#ignore the metadata and pull the 'boolean <true/false>' line
read line
#check if it is set to true
if echo $line | grep -q 'true'; then
echo "Locked at $(date)"
else
echo "Unlocked at $(date)"
fi
done
This ran fine on my Fedora with KDE, but I guess it should work on other things like Debian with gnome et cetera.
You may have issues if your grep
doesn't support -P
(in which case you can just use sed
).
-
Works well, running as an OpenRC service on Gentoo Linux with KDE/Plasma. However, I get double entries when the service starts and quadruple when I close my laptop. I fixed this by redirecting the output of the
echo
lines to file in this script (>> $LOGFILE) and adding between the last
fi` anddone
the linesuniq $LOGFILE > $LOGFILE.temp
followed bymv -f $LOGFILE.temp $LOGFILE
. The fiirst saves unique entries in a temporary file, and the second replaces the original with the new file. Aug 7, 2022 at 12:32