Skip to content

Commit 06cd271

Browse files
authored
Merge pull request slgobinath#757 from deltragon/screensaver-dbus
screensaver: don't rely on qdbus or dbus-send
2 parents dce9d69 + 4be9ef2 commit 06cd271

File tree

2 files changed

+63
-25
lines changed

2 files changed

+63
-25
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ Some Linux systems like CentOS do not have matching dependencies available in th
157157
1. Install the necessary dependencies for CentOS 7
158158

159159
```bash
160-
sudo yum install python3-devel dbus dbus-devel cairo cairo-devel cairomm-devel libjpeg-turbo-devel pango pango-devel pangomm pangomm-devel gobject-introspection-devel cairo-gobject-devel
160+
sudo yum install python3-devel cairo cairo-devel cairomm-devel libjpeg-turbo-devel pango pango-devel pangomm pangomm-devel gobject-introspection-devel cairo-gobject-devel
161161
```
162162

163163
2. Create a virtual environment in your home folder

safeeyes/plugins/screensaver/plugin.py

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,39 @@
2222

2323
import logging
2424
import os
25+
import typing
26+
27+
import gi
28+
29+
gi.require_version("Gio", "2.0")
30+
from gi.repository import Gio
2531

2632
from safeeyes import utility
2733
from safeeyes.model import TrayAction
2834

2935
context = None
30-
lock_screen = False
36+
is_long_break: bool = False
3137
user_locked_screen = False
32-
lock_screen_command = None
38+
lock_screen_command: typing.Union[list[str], typing.Callable[[], None], None] = None
3339
min_seconds = 0
3440
seconds_passed = 0
3541
tray_icon_path = None
3642
icon_lock_later_path = None
3743

3844

39-
def __lock_screen_command():
45+
def __lock_screen_command() -> typing.Union[list[str], typing.Callable[[], None], None]:
4046
"""Function tries to detect the screensaver command based on the current
4147
envinroment.
4248
49+
Returns either a command to execute or function to call.
50+
4351
Possible results:
44-
Gnome, Unity, Budgie: ['gnome-screensaver-command', '--lock']
52+
Modern GNOME: DBus: org.gnome.ScreenSaver.Lock
53+
Old Gnome, Unity, Budgie: ['gnome-screensaver-command', '--lock']
4554
Cinnamon: ['cinnamon-screensaver-command', '--lock']
4655
Pantheon, LXDE: ['light-locker-command', '--lock']
4756
Mate: ['mate-screensaver-command', '--lock']
48-
KDE: ['qdbus', 'org.freedesktop.ScreenSaver',
49-
'/ScreenSaver', 'Lock']
57+
KDE: DBus: org.freedesktop.ScreenSaver.Lock
5058
XFCE: ['xflock4']
5159
Otherwise: None
5260
"""
@@ -63,6 +71,7 @@ def __lock_screen_command():
6371
elif desktop_session == "cinnamon" and utility.command_exist(
6472
"cinnamon-screensaver-command"
6573
):
74+
# This calls org.cinnamon.ScreenSaver.Lock internally
6675
return ["cinnamon-screensaver-command", "--lock"]
6776
elif (
6877
desktop_session == "pantheon" or desktop_session.startswith("lubuntu")
@@ -71,14 +80,23 @@ def __lock_screen_command():
7180
elif desktop_session == "mate" and utility.command_exist(
7281
"mate-screensaver-command"
7382
):
83+
# This calls org.mate.ScreenSaver.Lock internally
84+
# However, it warns not to rely on that
7485
return ["mate-screensaver-command", "--lock"]
7586
elif (
7687
desktop_session == "kde"
7788
or "plasma" in desktop_session
7889
or desktop_session.startswith("kubuntu")
7990
or os.environ.get("KDE_FULL_SESSION") == "true"
8091
):
81-
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+
)
82100
elif (
83101
desktop_session in ["gnome", "unity", "budgie-desktop"]
84102
or desktop_session.startswith("ubuntu")
@@ -87,29 +105,49 @@ def __lock_screen_command():
87105
if utility.command_exist("gnome-screensaver-command"):
88106
return ["gnome-screensaver-command", "--lock"]
89107
# From Gnome 3.8 no gnome-screensaver-command
90-
return [
91-
"dbus-send",
92-
"--type=method_call",
93-
"--dest=org.gnome.ScreenSaver",
94-
"/org/gnome/ScreenSaver",
95-
"org.gnome.ScreenSaver.Lock",
96-
]
97-
elif os.environ.get("GNOME_DESKTOP_SESSION_ID"):
98-
if "deprecated" not in os.environ.get(
99-
"GNOME_DESKTOP_SESSION_ID"
100-
) and utility.command_exist("gnome-screensaver-command"):
108+
return lambda: __lock_screen_dbus(
109+
destination="org.gnome.ScreenSaver",
110+
path="/org/gnome/ScreenSaver",
111+
method="Lock",
112+
)
113+
elif gd_session := os.environ.get("GNOME_DESKTOP_SESSION_ID"):
114+
if "deprecated" not in gd_session and utility.command_exist(
115+
"gnome-screensaver-command"
116+
):
101117
# Gnome 2
102118
return ["gnome-screensaver-command", "--lock"]
103119
return None
104120

105121

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+
106136
def __lock_screen_later():
107137
global user_locked_screen
108138
user_locked_screen = True
109139

110140

111141
def __lock_screen_now() -> None:
112-
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()
113151

114152

115153
def init(ctx, safeeyes_config, plugin_config):
@@ -134,15 +172,15 @@ def init(ctx, safeeyes_config, plugin_config):
134172

135173
def on_start_break(break_obj):
136174
"""Determine the break type and only if it is a long break, enable the
137-
lock_screen flag.
175+
is_long_break flag.
138176
"""
139-
global lock_screen
177+
global is_long_break
140178
global seconds_passed
141179
global user_locked_screen
142180
user_locked_screen = False
143181
seconds_passed = 0
144-
if lock_screen_command:
145-
lock_screen = break_obj.is_long_break()
182+
183+
is_long_break = break_obj.is_long_break()
146184

147185

148186
def on_countdown(countdown, seconds):
@@ -155,7 +193,7 @@ def on_stop_break():
155193
"""Lock the screen after a long break if the user has not skipped within
156194
min_seconds.
157195
"""
158-
if user_locked_screen or (lock_screen and seconds_passed >= min_seconds):
196+
if user_locked_screen or (is_long_break and seconds_passed >= min_seconds):
159197
__lock_screen_now()
160198

161199

0 commit comments

Comments
 (0)