Skip to content

Commit b73cd23

Browse files
committed
screensaver: don't rely on qdbus or dbus-send
1 parent 786e066 commit b73cd23

File tree

1 file changed

+53
-16
lines changed

1 file changed

+53
-16
lines changed

safeeyes/plugins/screensaver/plugin.py

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,37 @@
2424
import os
2525
import typing
2626

27+
import gi
28+
29+
gi.require_version("Gio", "2.0")
30+
from gi.repository import Gio
31+
2732
from safeeyes import utility
2833
from safeeyes.model import TrayAction
2934

3035
context = None
3136
is_long_break: bool = False
3237
user_locked_screen = False
33-
lock_screen_command = None
38+
lock_screen_command: typing.Union[list[str], typing.Callable[[], None], None] = None
3439
min_seconds = 0
3540
seconds_passed = 0
3641
tray_icon_path = None
3742
icon_lock_later_path = None
3843

3944

40-
def __lock_screen_command() -> typing.Optional[list[str]]:
45+
def __lock_screen_command() -> typing.Union[list[str], typing.Callable[[], None], None]:
4146
"""Function tries to detect the screensaver command based on the current
4247
envinroment.
4348
49+
Returns either a command to execute or function to call.
50+
4451
Possible results:
45-
Gnome, Unity, Budgie: ['gnome-screensaver-command', '--lock']
52+
Modern GNOME: DBus: org.gnome.ScreenSaver.Lock
53+
Old Gnome, Unity, Budgie: ['gnome-screensaver-command', '--lock']
4654
Cinnamon: ['cinnamon-screensaver-command', '--lock']
4755
Pantheon, LXDE: ['light-locker-command', '--lock']
4856
Mate: ['mate-screensaver-command', '--lock']
49-
KDE: ['qdbus', 'org.freedesktop.ScreenSaver',
50-
'/ScreenSaver', 'Lock']
57+
KDE: DBus: org.freedesktop.ScreenSaver.Lock
5158
XFCE: ['xflock4']
5259
Otherwise: None
5360
"""
@@ -64,6 +71,7 @@ def __lock_screen_command() -> typing.Optional[list[str]]:
6471
elif desktop_session == "cinnamon" and utility.command_exist(
6572
"cinnamon-screensaver-command"
6673
):
74+
# This calls org.cinnamon.ScreenSaver.Lock internally
6775
return ["cinnamon-screensaver-command", "--lock"]
6876
elif (
6977
desktop_session == "pantheon" or desktop_session.startswith("lubuntu")
@@ -72,14 +80,23 @@ def __lock_screen_command() -> typing.Optional[list[str]]:
7280
elif desktop_session == "mate" and utility.command_exist(
7381
"mate-screensaver-command"
7482
):
83+
# This calls org.mate.ScreenSaver.Lock internally
84+
# However, it warns not to rely on that
7585
return ["mate-screensaver-command", "--lock"]
7686
elif (
7787
desktop_session == "kde"
7888
or "plasma" in desktop_session
7989
or desktop_session.startswith("kubuntu")
8090
or os.environ.get("KDE_FULL_SESSION") == "true"
8191
):
82-
return ["qdbus", "org.freedesktop.ScreenSaver", "/ScreenSaver", "Lock"]
92+
# Note that this is unfortunately a non-standard KDE extension.
93+
# See https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/632
94+
# for details.
95+
return lambda: __lock_screen_dbus(
96+
destination="org.freedesktop.ScreenSaver",
97+
path="/ScreenSaver",
98+
method="Lock",
99+
)
83100
elif (
84101
desktop_session in ["gnome", "unity", "budgie-desktop"]
85102
or desktop_session.startswith("ubuntu")
@@ -88,13 +105,11 @@ def __lock_screen_command() -> typing.Optional[list[str]]:
88105
if utility.command_exist("gnome-screensaver-command"):
89106
return ["gnome-screensaver-command", "--lock"]
90107
# From Gnome 3.8 no gnome-screensaver-command
91-
return [
92-
"dbus-send",
93-
"--type=method_call",
94-
"--dest=org.gnome.ScreenSaver",
95-
"/org/gnome/ScreenSaver",
96-
"org.gnome.ScreenSaver.Lock",
97-
]
108+
return lambda: __lock_screen_dbus(
109+
destination="org.gnome.ScreenSaver",
110+
path="/org/gnome/ScreenSaver",
111+
method="Lock",
112+
)
98113
elif gd_session := os.environ.get("GNOME_DESKTOP_SESSION_ID"):
99114
if "deprecated" not in gd_session and utility.command_exist(
100115
"gnome-screensaver-command"
@@ -104,13 +119,35 @@ def __lock_screen_command() -> typing.Optional[list[str]]:
104119
return None
105120

106121

122+
def __lock_screen_dbus(destination: str, path: str, method: str) -> None:
123+
"""This assumes that the interface is the same as the destination."""
124+
dbus_proxy = Gio.DBusProxy.new_for_bus_sync(
125+
bus_type=Gio.BusType.SESSION,
126+
flags=Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES,
127+
info=None,
128+
name=destination,
129+
object_path=path,
130+
interface_name=destination,
131+
)
132+
133+
dbus_proxy.call_sync(method, None, Gio.DBusCallFlags.NONE, -1)
134+
135+
107136
def __lock_screen_later():
108137
global user_locked_screen
109138
user_locked_screen = True
110139

111140

112141
def __lock_screen_now() -> None:
113-
utility.execute_command(lock_screen_command)
142+
global lock_screen_command
143+
144+
if lock_screen_command is None:
145+
return
146+
147+
if isinstance(lock_screen_command, list):
148+
utility.execute_command(lock_screen_command)
149+
else:
150+
lock_screen_command()
114151

115152

116153
def init(ctx, safeeyes_config, plugin_config):
@@ -142,8 +179,8 @@ def on_start_break(break_obj):
142179
global user_locked_screen
143180
user_locked_screen = False
144181
seconds_passed = 0
145-
if lock_screen_command:
146-
is_long_break = break_obj.is_long_break()
182+
183+
is_long_break = break_obj.is_long_break()
147184

148185

149186
def on_countdown(countdown, seconds):

0 commit comments

Comments
 (0)