From 861a04827a19facd4ce0eb4693de43f64507df52 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Mon, 19 May 2025 21:27:36 +0200 Subject: ... --- .../waybar_systemd_inhibit/__init__.py | 0 .../waybar_systemd_inhibit/__main__.py | 117 +++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 overlays/waybar-systemd-inhibit/waybar_systemd_inhibit/__init__.py create mode 100644 overlays/waybar-systemd-inhibit/waybar_systemd_inhibit/__main__.py (limited to 'overlays/waybar-systemd-inhibit/waybar_systemd_inhibit') diff --git a/overlays/waybar-systemd-inhibit/waybar_systemd_inhibit/__init__.py b/overlays/waybar-systemd-inhibit/waybar_systemd_inhibit/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/overlays/waybar-systemd-inhibit/waybar_systemd_inhibit/__main__.py b/overlays/waybar-systemd-inhibit/waybar_systemd_inhibit/__main__.py new file mode 100644 index 00000000..35cc7fd1 --- /dev/null +++ b/overlays/waybar-systemd-inhibit/waybar_systemd_inhibit/__main__.py @@ -0,0 +1,117 @@ +import asyncclick as click +from dbus_next.aio import MessageBus +from dbus_next import BusType, Message, PropertyAccess +import asyncio +from functools import update_wrapper +from dbus_next.service import ServiceInterface, method, dbus_property +from dbus_next import Variant, DBusError +import os +import json + +class BlockInterface(ServiceInterface): + def __init__(self, system_bus, logind): + super().__init__('li.yggdrasil.WaybarSystemdInhibit') + self.system_bus = system_bus + self.logind = logind + self.fd = None + + def Release(self): + if not self.fd: + return + + os.close(self.fd) + self.fd = None + self.emit_properties_changed({'IsAcquired': False}) + + async def Acquire(self): + if self.fd: + return + + res = await self.system_bus.call(Message( + destination='org.freedesktop.login1', + path='/org/freedesktop/login1', + interface='org.freedesktop.login1.Manager', + member='Inhibit', + signature='ssss', + body=[ + "handle-lid-switch", + "waybar-systemd-inhibit", + "User request", + "block", + ], + )) + self.fd = res.unix_fds[res.body[0]] + self.emit_properties_changed({'IsAcquired': True}) + + @method() + async def ToggleBlock(self): + if self.fd: + self.Release() + else: + await self.Acquire() + + @dbus_property(access=PropertyAccess.READ) + def IsAcquired(self) -> 'b': + return self.fd is not None + + +@click.command() +async def main(): + system_bus = await MessageBus(bus_type=BusType.SYSTEM, negotiate_unix_fd=True).connect() + session_bus = await MessageBus(bus_type=BusType.SESSION).connect() + + introspection = await system_bus.introspect('org.freedesktop.login1', '/org/freedesktop/login1') + obj = system_bus.get_proxy_object('org.freedesktop.login1', '/org/freedesktop/login1', introspection) + logind = obj.get_interface('org.freedesktop.login1.Manager') + properties = obj.get_interface('org.freedesktop.DBus.Properties') + + def is_blocked_logind(what: str): + return "handle-lid-switch" in what.split(':') + + def print_state(is_blocked: bool, is_acquired: bool = False): + icon = "󰌢" if is_blocked else "󰛧" + text = f"{icon}" + if is_acquired: + text = f"{text}" + elif is_blocked: + text = f"{text}" + print(json.dumps({'text': text, 'tooltip': ("Manually inhibited" if is_acquired else None)}, separators=(',', ':')), flush=True) + + print_state(is_blocked_logind(await logind.get_block_inhibited())) + + async def get_inhibit(): + introspection = await session_bus.introspect('li.yggdrasil.WaybarSystemdInhibit', '/li/yggdrasil/WaybarSystemdInhibit') + return session_bus.get_proxy_object('li.yggdrasil.WaybarSystemdInhibit', '/li/yggdrasil/WaybarSystemdInhibit', introspection) + + async def on_logind_properties_changed(interface_name, changed_properties, invalidated_properties): + if 'BlockInhibited' not in changed_properties: + return + + properties = (await get_inhibit()).get_interface('li.yggdrasil.WaybarSystemdInhibit') + + print_state(is_blocked_logind(changed_properties['BlockInhibited'].value), await properties.get_is_acquired()) + + properties.on_properties_changed(on_logind_properties_changed) + + session_bus.export('/li/yggdrasil/WaybarSystemdInhibit', BlockInterface(system_bus, logind)) + await session_bus.request_name('li.yggdrasil.WaybarSystemdInhibit') + + properties = (await get_inhibit()).get_interface('org.freedesktop.DBus.Properties') + + async def on_inhibit_properties_changed(interface_name, changed_properties, invalidated_properties): + if 'IsAcquired' not in changed_properties: + return + + print_state(is_blocked_logind(await logind.get_block_inhibited()), changed_properties['IsAcquired'].value) + + properties.on_properties_changed(on_inhibit_properties_changed) + + await session_bus.wait_for_disconnect() + +@click.command() +async def toggle(): + session_bus = await MessageBus(bus_type=BusType.SESSION).connect() + introspection = await session_bus.introspect('li.yggdrasil.WaybarSystemdInhibit', '/li/yggdrasil/WaybarSystemdInhibit') + obj = session_bus.get_proxy_object('li.yggdrasil.WaybarSystemdInhibit', '/li/yggdrasil/WaybarSystemdInhibit', introspection) + interface = obj.get_interface('li.yggdrasil.WaybarSystemdInhibit') + await interface.call_toggle_block() -- cgit v1.2.3