I am currently trying to connect to the Screensaver Signal (org.freedesktop.ScreenSaver - /ScreenSaver - ActiveChanged(bool)) that is emitted when the Screen-Saver is closed:
$ dbus-monitor "interface='org.freedesktop.ScreenSaver'"
...
signal time=1761396762.341364 sender=:1.21 -> destination=(null destination) serial=94408 path=/ScreenSaver; interface=org.freedesktop.ScreenSaver; member=ActiveChanged
boolean true
...
signal time=1761396765.026613 sender=:1.21 -> destination=(null destination) serial=94464 path=/ScreenSaver; interface=org.freedesktop.ScreenSaver; member=ActiveChanged
boolean false
For the past few days, I have been banging my head against the wall trying to implement a DBUS Signal Listener for this signal using PySide6/Qt. This is my current attempt (combining multiple different attempts):
from __future__ import annotations
from PySide6 import QtDBus, QtCore
from PySide6.QtCore import Slot, QObject
from typing import Annotated, get_type_hints
class DBusEventDispatcher(QtCore.QObject):
def __init__(self):
super().__init__()
sessionBus = QtDBus.QDBusConnection.sessionBus()
if not sessionBus.isConnected():
errorMessage = sessionBus.lastError().message()
raise Exception("Cannot connect to DBUS: " + errorMessage)
success = sessionBus.registerService("my_app")
print(success)
success = sessionBus.registerObject(
'/',
'org.freedesktop.ScreenSaver',
self,
QtDBus.QDBusConnection.ExportAllSlots
)
print(success)
#for path in ['org.freedesktop.ScreenSaver', 'org.gnome.ScreenSaver']:
# interface = QtDBus.QDBusInterface(path, '/ScreenSaver', '', sessionBus)
# if interface != None:
# interface.ActiveChanged.connect(self._onActiveChanged)
mo = self.metaObject()
for m in range(mo.methodOffset(), mo.methodCount()):
print(mo.method(m).methodSignature())
self.iface = QtDBus.QDBusInterface(
"org.freedesktop.ScreenSaver", # Service
"/ScreenSaver", # Path
"org.freedesktop.ScreenSaver", # Interface
sessionBus
)
print(self.iface.isValid())
self.iface.connect(
QtCore.SIGNAL("ActiveChanged(bool)"),
self.ActiveChanged
)
QtCore.QObject.connect(
self.iface,
QtCore.SIGNAL("ActiveChanged(bool)"),
self.ActiveChanged
)
# for service in ['org.freedesktop.ScreenSaver']: # 'org.gnome.ScreenSaver'
success = sessionBus.connect(
'org.freedesktop.ScreenSaver', # service,
'/ScreenSaver',
'org.freedesktop.ScreenSaver',
'ActiveChanged',
self,
QtCore.SLOT('ActiveChanged(bool)')
)
print(success)
@QtCore.Slot(bool)
def ActiveChanged(self, active: bool):
print("ActiveChanged")
print(active)
And I get positive return values for the different calls:
$ python3 my_app.py
True
True
b'ActiveChanged(bool)'
True
True
But after that, nothing...
When I lock the screen, I see the message from dbus-monitor from above, but nothing from the python script.
Does anybody know what may be wrong with the script?
Could this be a system-issue, like some systemd-rule blocking the access?
Is there maybe some debug-flag that I could set to see what is happening inside the python / DBUS library?
Any other ideas?
Thanks for any help.
$ python3 --version
Python 3.12.3
$ pip3 list
Package Version
------------------ -------
cysystemd 2.0.1
pip 24.0
PySide6_Essentials 6.10.0
shiboken6 6.10.0
systemd 0.17.1
systemd-python 235
$ uname -a
Linux gerrit-framework 6.14.0-112033-tuxedo #33~24.04.1tux1 SMP PREEMPT_DYNAMIC Tue Sep 30 19:33:36 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/issue
TUXEDO OS 24.04.3 LTS \l
- KDE-Plasma-Version: 6.4.5
- KDE-Frameworks-Version: 6.17.0
- Qt-Version: 6.8.2
- Graphics-Platform: Wayland