Skip to content

Commit 32830e6

Browse files
authored
Merge pull request slgobinath#727 from deltragon/kde-do-not-disturb
donotdisturb: implement detection on KDE Plasma Wayland
2 parents cecbbe2 + 4909fd8 commit 32830e6

File tree

2 files changed

+45
-15
lines changed

2 files changed

+45
-15
lines changed

safeeyes/plugins/donotdisturb/dependency_checker.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
def validate(plugin_config, plugin_settings):
2424
command = None
2525
if utility.IS_WAYLAND:
26-
if utility.DESKTOP_ENVIRONMENT == "gnome":
26+
if (
27+
utility.DESKTOP_ENVIRONMENT == "gnome"
28+
or utility.DESKTOP_ENVIRONMENT == "kde"
29+
):
2730
return None
2831
command = "wlrctl"
2932
else:

safeeyes/plugins/donotdisturb/plugin.py

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,32 @@ def is_idle_inhibited_gnome():
176176
return bool(result & 0b1000)
177177

178178

179+
def is_idle_inhibited_kde() -> bool:
180+
"""KDE Plasma doesn't work with wlrctl, and there is no way to enumerate
181+
fullscreen windows, but KDE does expose a non-standard Inhibited property on
182+
org.freedesktop.Notifications, which does communicate the Do Not Disturb status
183+
on KDE.
184+
This is also only an approximation, but comes pretty close.
185+
"""
186+
dbus_proxy = Gio.DBusProxy.new_for_bus_sync(
187+
bus_type=Gio.BusType.SESSION,
188+
flags=Gio.DBusProxyFlags.NONE,
189+
info=None,
190+
name="org.freedesktop.Notifications",
191+
object_path="/org/freedesktop/Notifications",
192+
interface_name="org.freedesktop.Notifications",
193+
cancellable=None,
194+
)
195+
prop = dbus_proxy.get_cached_property("Inhibited")
196+
197+
if prop is None:
198+
return False
199+
200+
result = prop.unpack()
201+
202+
return result
203+
204+
179205
def _window_class_matches(window_class: str, classes: list) -> bool:
180206
return any(map(lambda w: w in classes, window_class.split()))
181207

@@ -229,29 +255,30 @@ def _normalize_window_classes(classes_as_str: str):
229255
return [w.lower() for w in classes_as_str.split()]
230256

231257

232-
def on_pre_break(break_obj):
233-
"""Lifecycle method executes before the pre-break period."""
258+
def __should_skip_break(pre_break: bool) -> bool:
234259
if utility.IS_WAYLAND:
235260
if utility.DESKTOP_ENVIRONMENT == "gnome":
236261
skip_break = is_idle_inhibited_gnome()
262+
elif utility.DESKTOP_ENVIRONMENT == "kde":
263+
skip_break = is_idle_inhibited_kde()
237264
else:
238-
skip_break = is_active_window_skipped_wayland(True)
265+
skip_break = is_active_window_skipped_wayland(pre_break)
239266
else:
240-
skip_break = is_active_window_skipped_xorg(True)
267+
skip_break = is_active_window_skipped_xorg(pre_break)
241268
if dnd_while_on_battery and not skip_break:
242269
skip_break = is_on_battery()
270+
271+
if skip_break:
272+
logging.info("Skipping break due to donotdisturb")
273+
243274
return skip_break
244275

245276

277+
def on_pre_break(break_obj):
278+
"""Lifecycle method executes before the pre-break period."""
279+
return __should_skip_break(pre_break=True)
280+
281+
246282
def on_start_break(break_obj):
247283
"""Lifecycle method executes just before the break."""
248-
if utility.IS_WAYLAND:
249-
if utility.DESKTOP_ENVIRONMENT == "gnome":
250-
skip_break = is_idle_inhibited_gnome()
251-
else:
252-
skip_break = is_active_window_skipped_wayland(False)
253-
else:
254-
skip_break = is_active_window_skipped_xorg(False)
255-
if dnd_while_on_battery and not skip_break:
256-
skip_break = is_on_battery()
257-
return skip_break
284+
return __should_skip_break(pre_break=False)

0 commit comments

Comments
 (0)