From cbdb386ba000de7188055d40bf8f26c679719c0d Mon Sep 17 00:00:00 2001 From: nocode Date: Sat, 4 Jul 2026 13:43:45 +0200 Subject: [PATCH] feat(powermenu): add fws-powermenu universal power menu utility Add a Python-based power menu script that works with both Hyprland (Wayland) and i3 (X11) desktop environments. Supports lock, logout, suspend, reboot, and poweroff actions with appropriate display server backends (wofi for Hyprland, rofi for i3). --- .../airootfs/usr/local/bin/fws-powermenu | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100755 configs/releng/airootfs/usr/local/bin/fws-powermenu diff --git a/configs/releng/airootfs/usr/local/bin/fws-powermenu b/configs/releng/airootfs/usr/local/bin/fws-powermenu new file mode 100755 index 0000000..4002796 --- /dev/null +++ b/configs/releng/airootfs/usr/local/bin/fws-powermenu @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# FWS — menu d'alimentation (verrouiller / déconnexion / suspendre / +# redémarrer / éteindre). Bouton de la barre ou Super+X. Universel : +# • Hyprland (Wayland) → wofi, verrouillage hyprlock, sortie hyprctl. +# • i3 (X11) → rofi, verrouillage i3lock, sortie i3-msg exit. +# Aucune dépendance hors python3 + wofi/rofi (déjà là avec le bureau). + +import os +import subprocess +import sys + +_WOFI_STYLE = "/usr/local/share/fws/wofi-style.css" +_HYPR = bool(os.environ.get("HYPRLAND_INSTANCE_SIGNATURE")) + +# (libellé affiché, commande shell). L'icône Nerd Font aide au repérage. +if _HYPR: + _lock = "hyprlock" + _logout = "hyprctl dispatch exit" +else: + _lock = "i3lock -c 1e1e2e" + _logout = "i3-msg exit" + +_ITEMS = [ + ("󰌾 Verrouiller", _lock), + ("󰗽 Déconnexion", _logout), + ("󰤄 Suspendre", "systemctl suspend"), + ("󰜉 Redémarrer", "systemctl reboot"), + ("󰐥 Éteindre", "systemctl poweroff"), +] + + +def _menu(entries): + text = "\n".join(entries) + if _HYPR: + cmd = ["wofi", "--dmenu", "--prompt", "Alimentation", + "--width", "300", "--height", "260", "--cache-file", "/dev/null"] + if os.path.exists(_WOFI_STYLE): + cmd += ["--style", _WOFI_STYLE] + else: + cmd = ["rofi", "-dmenu", "-i", "-p", "Alimentation", "-no-custom", + "-theme-str", "window { width: 300px; } listview { lines: 5; }"] + out = subprocess.run(cmd, input=text, text=True, + capture_output=True, check=False) + return out.stdout.strip() + + +def main(): + choice = _menu([label for label, _ in _ITEMS]) + if not choice: + return 0 + for label, command in _ITEMS: + if label == choice: + subprocess.Popen(["sh", "-c", command]) # noqa: S603,S607 + break + return 0 + + +if __name__ == "__main__": + sys.exit(main())