Az xidlehook: precíz tétlenség-kezelés X11 alatt

enlightened Ez az oldal a közösségért készül. heart Kövess minket máshol is:  Linux Mint Magyar Közösség a Mastodon-on  Telegram csatorna – csak hírek  Beszélgessünk a Telegram – Linux csevegő csoport  Hírek olvasása RSS segítségével  Linux Mint Hivatalos Magyar Közösség a Facebook-on      Linux Mint Baráti Kör a Facebook-on
wink Ha hasznosnak találod, és szeretnéd, hogy folytatódjon, támogasd a munkát Ko-fi vagy Paypal segítségével. laugh

Az xidlehook egy Rust nyelven írt, önálló démon, ami az xautolock szerepét váltja ki: figyeli a felhasználó tétlenségét, és egy megadott idő elteltével tetszőleges parancsot futtat le. Amíg egy DE-be épített energiakezelő (pl. az XFCE-é) a képernyővédő-inhibit D-Bus API-ra (org.freedesktop.ScreenSaver) hagyatkozik – vagyis abban bízik, hogy minden alkalmazás korrekten szól, ha nem szabad aludni mennie a gépnek –, addig az xidlehook ezt megkerüli: a fullscreen-állapotot közvetlenül az X szerver ablaklistájából, a hanglejátszást pedig közvetlenül a PulseAudio-tól kérdezi le. Ez a különbség teszi megbízhatóvá olyan környezetben is, mint egy csupasz dwm/chadwm, ahol nincs teljes DE, ami az inhibit-hívásokat kezelné.

Az alapfogalom: timer és canceller

Az xidlehook nem "egy időzítő" – hanem timerek láncolatát kezeli. Minden timer három részből áll:

  1. duration – hány másodperc tétlenség után lépjen működésbe
  2. command – milyen parancsot futtasson le ekkor (/bin/sh -c alatt fut)
  3. canceller – milyen parancsot futtasson, ha a felhasználó a következő timer aktiválódása előtt újra aktívvá válik (üres string, ha nincs rá szükség)

Ez a hármas a --timer kapcsoló három argumentuma, és a --timer kapcsoló többször is megadható egyetlen parancssorban – ez adja a "lánc" jelleget (erről lentebb egy konkrét példa is jön).

A démon (xidlehook) összes kapcsolója

Kapcsoló Típus Mit csinál
--timer <mp> <parancs> <megszakító> ismételhető A lánc egy eleme. Legalább egy kötelező (vagy a --print móddal helyettesíthető).
--not-when-fullscreen be/ki kapcsoló Ha az aktuális fókuszált ablak fullscreen állapotban van, a timer nem kerül végrehajtásra. Videólejátszásnál, játékoknál, prezentációknál hasznos.
--not-when-audio be/ki kapcsoló Ha a PulseAudio szerint bármelyik alkalmazás hangot ad ki, a timer nem kerül végrehajtásra. (Csak akkor elérhető, ha a pulse cargo-feature-rel épült a bináris – az AUR csomag alapból ezzel épül.)
--detect-sleep be/ki kapcsoló Ha a rendszer felébred egy suspend-ből, az idle-számláló nullázódik. Enélkül előfordulhat, hogy felébredés után szinte azonnal újra lefut a timer, mert az "idle idő" a suspend alatt eltelt időt is beleszámolta.
--once be/ki kapcsoló A teljes láncot csak egyszer futtatja végig, utána a démon kilép. Enélkül az xidlehook folyamatosan fut, és minden újabb tétlenségi ciklusnál újra elindítja a láncot.
--print be/ki kapcsoló Nem indít démont, csak kiírja az aktuális tétlenségi időt (ezredmásodpercben) és kilép – az xprintidle kiváltására. Minden más kapcsolóval kizárja egymást.
--socket <útvonal> érték Unix socketet nyit ezen az útvonalon, amin keresztül a xidlehook-client (vagy bármi más, ami JSON-sorokat tud küldeni) vezérelheti futás közben a démont.
-h, --help / -V, --version be/ki kapcsoló Súgó, illetve verziószám.

Fontos, hogy a --not-when-fullscreen és a --not-when-audio minden timerre egyszerre vonatkozik egy adott démonpéldányon belül – nincs lehetőség arra, hogy csak a lánc egyik elemére alkalmazd, a másikra nem. Ha ilyen finomhangolás kell, külön démonpéldányt kell indítani külön socketekkel (az xidlehook ezt is támogatja: több példány futtatható párhuzamosan).

Timerek láncolása – gyakorlati példa

A klasszikus felhasználási eset: a képernyő előbb elhalványul, aztán zárolódik, végül a gép alvó módba megy – de csak akkor, ha közben tényleg nem történik semmi, és nem megy videó vagy fullscreen alkalmazás:

xidlehook \
  --not-when-audio --not-when-fullscreen --detect-sleep \
  --timer 300  'xrandr --output eDP-1 --brightness 0.3' 'xrandr --output eDP-1 --brightness 1.0' \
  --timer 480  'i3lock' '' \
  --timer 600  'systemctl suspend' ''

Ami itt történik:

  • 5 perc (300 mp) tétlenség után elhalványítja a kijelzőt; ha időközben megmozdul az egér, a canceller visszaállítja a fényerőt
  • 8 percnél (480 mp – a lánc előző eleméhez képest számít az idő, tehát ez 3 perccel az elhalványítás után) zárolja a képernyőt; itt nincs canceller, mert a zárolást felesleges "visszavonni"
  • 10 percnél (600 mp, azaz 2 perccel a zárolás után) alvó módba küldi a gépet

A --detect-sleep azért fontos itt, mert enélkül a suspendből ébredés után a démon úgy vélné, hogy még mindig tart a régi tétlenségi periódus, és akár azonnal újra lezárolná/elhalványítaná a képernyőt.

A socket API és a xidlehook-client

Önmagában a démon nem tud külső parancsokra reagálni – ha meg akarod szakítani, szüneteltetni vagy lekérdezni futás közben, kell hozzá a --socket <útvonal> kapcsoló, és egy kliens, ami ír erre a socketre. Erre való a xidlehook-client segédprogram.

xidlehook --socket /tmp/xidlehook.sock --timer 600 'systemctl suspend' ''

A kliens minden hívásnál kötelezően megkapja ugyanazt a --socket útvonalat, utána egy alparancsot:

Alparancs Kapcsolók Mit csinál
query --timer <id>... (opcionális, üresen: mind) Kilistázza a timerek aktuális állapotát (engedélyezett-e, mennyi van hátra stb.), JSON formában.
control --action <Enable\|Disable\|Trigger\|Delete>, --timer <id>... Egy vagy több timer be-/kikapcsolása, azonnali kiváltása, vagy törlése. Az id a --timer kapcsolók sorrendi indexe (0-tól számolva).
add --time <mp>, --activation <parancs>..., --abortion <parancs>..., --deactivation <parancs>..., --index <n> Futás közben ad hozzá egy új timert a lánchoz. Fontos: az --activation parancsa itt nem megy át a /bin/sh -c-n, ellentétben a démon indításkori --timer parancsával – összetettebb shell-szintaxishoz (&&, pipe-ok) explicit sh -c '...'-t kell köréírni.
reset-idle Úgy tesz, mintha a felhasználó éppen mozdult volna – nullázza a tétlenségi számlálót, mintha valódi input érkezett volna.
stop-timers Az összes timert felfüggeszti addig, amíg valódi felhasználói aktivitás nem történik. Ez gyakorlatilag egy "ne aludjon el most" gomb, hasonló funkcióval, mint egy caffeine alkalmazás.

Kliens-példák

Az összes futó timer lekérdezése:

xidlehook-client --socket /tmp/xidlehook.sock query

A második timer (index 1) azonnali kiváltása – hasznos, ha manuálisan akarod triggerelni a zárolást anélkül, hogy megvárnád a tétlenségi időt:

xidlehook-client --socket /tmp/xidlehook.sock control --action Trigger --timer 1

"Ne aludjon most" gomb (pl. egy chadwm billentyűkombóhoz kötve):

xidlehook-client --socket /tmp/xidlehook.sock stop-timers

Új, futásidőben hozzáadott timer, ami 2 perc után értesítést küld (mivel az --activation nem megy át sh -c-n, ha shell-jellemzőt akarunk – pl. változó-behelyettesítést –, azt explicit meg kell hívni):

xidlehook-client --socket /tmp/xidlehook.sock add \
  --time 120 \
  --activation sh -c "notify-send 'Mindjárt zárol'"

Automatikus indítás systemd user service-ként

Mivel a démon önállóan fut, nem kell hozzá teljes DE – elég, ha a bejelentkezéskor elindul. Egy ~/.config/systemd/user/xidlehook.service:

[Unit]
Description=Idle-alapú automatizálás (xidlehook)
After=graphical-session.target

[Service]
Environment=DISPLAY=:0
ExecStart=/usr/bin/xidlehook --socket %t/xidlehook.sock --not-when-audio --not-when-fullscreen --detect-sleep --timer 600 'systemctl suspend' ''

[Install]
WantedBy=graphical-session.target

A %t a runtime könyvtárra (/run/user/<uid>) oldódik fel, így a socket a session-hez kötött helyre kerül. Ha startx/.xinitrc-ből indítod a chadwm-et display manager nélkül, egyszerűbb lehet ugyanezt a sort simán az .xinitrc-be tenni a WM indítása elé, háttérbe küldve.

Amire érdemes figyelni

  • Csak X11-et támogat. Wayland alatt (pl. ha valaha átállnál) nem működik – ott swayidle/hypridle a megfelelő kategória.
  • A --not-when-audio kizárólag PulseAudio-t ismer natívan. PipeWire alatt ez jellemzően működik a pipewire-pulse kompatibilitási réteg miatt, de ha valamiért natív PipeWire session-t futtatsz e nélkül, a hangdetektálás nem fog látni semmit.
  • A fejlesztő (jD91mZM2) elhunyt, a projekt jelenleg közösségi fork-okból él tovább. Az Arch AUR csomag ennek ellenére évek óta stabilan build-elhető és karbantartott – ahogy a fenti fordítás is mutatja, a jelenlegi legfrissebb (0.10.0) tag simán lefordul a jelenlegi függőségekkel.
  • A --not-when-fullscreen/--not-when-audio globális egy démonpéldányon belül, nem timerenkénti – ha erre szükséged van, külön démont kell indítani külön sockettel.