From 2334582c335ce2ff607f5721428a641e5c07328b Mon Sep 17 00:00:00 2001 From: kiana-S Date: Mon, 13 May 2024 16:34:57 -0400 Subject: [PATCH] Add idle inhibiting programs --- home-manager/wayland/default.nix | 1 + home-manager/wayland/idle.nix | 42 ++++++++++ .../wayland/idle/wayland-idle-inhibitor.py | 81 +++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 home-manager/wayland/idle.nix create mode 100644 home-manager/wayland/idle/wayland-idle-inhibitor.py diff --git a/home-manager/wayland/default.nix b/home-manager/wayland/default.nix index 5baf3c1..84e8a9b 100644 --- a/home-manager/wayland/default.nix +++ b/home-manager/wayland/default.nix @@ -9,5 +9,6 @@ ./hyprland.nix ./wltools.nix ./waybar.nix + ./idle.nix ]; } diff --git a/home-manager/wayland/idle.nix b/home-manager/wayland/idle.nix new file mode 100644 index 0000000..1a810aa --- /dev/null +++ b/home-manager/wayland/idle.nix @@ -0,0 +1,42 @@ +{ pkgs, lib, ... }: +let + wayland-idle-inhibitor = pkgs.python312Packages.buildPythonApplication { + pname = "wayland-idle-inhibitor"; + version = "1.0.0"; + + propagatedBuildInputs = with pkgs.python312Packages; [ + pywayland + ]; + + dontUnpack = true; + installPhase = '' + install -Dm755 ${./idle/wayland-idle-inhibitor.py} \ + $out/bin/wayland-idle-inhibitor + ''; + } +in { + + # Idle inhibiting + + home.packages = [ + wayland-idle-inhibitor + ]; + + systemd.user.services.wayland-pipewire-idle-inhibit = { + Install.WantedBy = [ "graphical-session.target" ]; + + Unit = { + Description = "Inhibit Wayland idling when media is played through pipewire"; + Documentation= "https://github.com/rafaelrc7/wayland-pipewire-idle-inhibit"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + ConditionEnvironment = "WAYLAND_DISPLAY"; + }; + + Service = { + ExecStart = "${lib.getExe pkgs.wayland-pipewire-idle-inhibit}"; + Restart = "always"; + RestartSec = "10"; + }; + }; +} diff --git a/home-manager/wayland/idle/wayland-idle-inhibitor.py b/home-manager/wayland/idle/wayland-idle-inhibitor.py new file mode 100644 index 0000000..5a6d0e4 --- /dev/null +++ b/home-manager/wayland/idle/wayland-idle-inhibitor.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python + +import sys +from dataclasses import dataclass +from signal import SIGINT, SIGTERM, signal +from threading import Event + +from pywayland.client.display import Display +from pywayland.protocol.idle_inhibit_unstable_v1.zwp_idle_inhibit_manager_v1 import ( + ZwpIdleInhibitManagerV1, +) +from pywayland.protocol.wayland.wl_compositor import WlCompositor +from pywayland.protocol.wayland.wl_registry import WlRegistryProxy +from pywayland.protocol.wayland.wl_surface import WlSurface + + +@dataclass +class GlobalRegistry: + surface: WlSurface | None = None + inhibit_manager: ZwpIdleInhibitManagerV1 | None = None + + +def handle_registry_global( + wl_registry: WlRegistryProxy, id_num: int, iface_name: str, version: int +) -> None: + global_registry: GlobalRegistry = wl_registry.user_data or GlobalRegistry() + + if iface_name == "wl_compositor": + compositor = wl_registry.bind(id_num, WlCompositor, version) + global_registry.surface = compositor.create_surface() # type: ignore + elif iface_name == "zwp_idle_inhibit_manager_v1": + global_registry.inhibit_manager = wl_registry.bind( + id_num, ZwpIdleInhibitManagerV1, version + ) + + +def main() -> None: + done = Event() + signal(SIGINT, lambda _, __: done.set()) + signal(SIGTERM, lambda _, __: done.set()) + + global_registry = GlobalRegistry() + + display = Display() + display.connect() + + registry = display.get_registry() # type: ignore + registry.user_data = global_registry + registry.dispatcher["global"] = handle_registry_global + + def shutdown() -> None: + display.dispatch() + display.roundtrip() + display.disconnect() + + display.dispatch() + display.roundtrip() + + if global_registry.surface is None or global_registry.inhibit_manager is None: + print("Wayland seems not to support idle_inhibit_unstable_v1 protocol.") + shutdown() + sys.exit(1) + + inhibitor = global_registry.inhibit_manager.create_inhibitor( # type: ignore + global_registry.surface + ) + + display.dispatch() + display.roundtrip() + + print("Inhibiting idle...") + done.wait() + print("Shutting down...") + + inhibitor.destroy() + + shutdown() + + +if __name__ == "__main__": + main()