refactor(fws-keys): make keyboard shortcuts tool universal for hyprland and i3
Rename fws-hypr-keys to fws-keys and extend it to support both Hyprland and i3 desktop environments. The tool now detects the session type and uses appropriate methods: - Hyprland: queries hyprctl binds for real loaded bindings (wofi dmenu) - i3: parses ~/.config/i3/config with variable resolution (rofi dmenu) Update all references in configs and templates. Add VM detection warning in fws-vr-setup to prevent VR attempts in virtual machines where GPU/USB access is unavailable. Add ttf-liberation font dependency for Steam UI stability on minimal installations and improve error guidance for Steam crashes.
This commit is contained in:
@@ -29,6 +29,6 @@ file_permissions=(
|
|||||||
["/usr/bin/load_policy"]="0:0:755"
|
["/usr/bin/load_policy"]="0:0:755"
|
||||||
["/usr/bin/setstatus"]="0:0:755"
|
["/usr/bin/setstatus"]="0:0:755"
|
||||||
["/usr/local/bin/fws-setup-hardware"]="0:0:755"
|
["/usr/local/bin/fws-setup-hardware"]="0:0:755"
|
||||||
["/usr/local/bin/fws-hypr-keys"]="0:0:755"
|
["/usr/local/bin/fws-keys"]="0:0:755"
|
||||||
["/usr/local/bin/fws-vr-setup"]="0:0:755"
|
["/usr/local/bin/fws-vr-setup"]="0:0:755"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# FWS — affiche les raccourcis clavier RÉELS de Hyprland.
|
|
||||||
#
|
|
||||||
# Source de vérité : « hyprctl binds -j » = les binds effectivement CHARGÉS
|
|
||||||
# par le compositeur (ceux de ~/.config/hypr/hyprland.conf, y compris ceux
|
|
||||||
# ajoutés par l'utilisateur après l'installation). Les descriptions viennent
|
|
||||||
# des « bindd » de la config ; un bind sans description affiche son action
|
|
||||||
# brute (dispatcher + argument). Affichage : wofi en mode dmenu (recherche
|
|
||||||
# incrémentale intégrée) — déclenché par le bouton ⌨ de la waybar ou SUPER+K.
|
|
||||||
#
|
|
||||||
# python3 et wofi sont déjà sur le système (image FWS + paquets Hyprland) :
|
|
||||||
# aucune dépendance supplémentaire.
|
|
||||||
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
_STYLE = "/usr/local/share/fws/wofi-keys.css"
|
|
||||||
|
|
||||||
# Bits de modmask (masques X11) dans l'ordre d'affichage voulu.
|
|
||||||
_MODS = [
|
|
||||||
(64, "SUPER"),
|
|
||||||
(4, "CTRL"),
|
|
||||||
(8, "ALT"),
|
|
||||||
(1, "SHIFT"),
|
|
||||||
]
|
|
||||||
|
|
||||||
# Libellés humains pour les « touches » spéciales.
|
|
||||||
_KEY_LABELS = {
|
|
||||||
"mouse:272": "clic gauche",
|
|
||||||
"mouse:273": "clic droit",
|
|
||||||
"mouse:274": "clic molette",
|
|
||||||
"mouse_down": "molette bas",
|
|
||||||
"mouse_up": "molette haut",
|
|
||||||
"return": "Entrée",
|
|
||||||
"space": "Espace",
|
|
||||||
"escape": "Échap",
|
|
||||||
"tab": "Tab",
|
|
||||||
"left": "←",
|
|
||||||
"right": "→",
|
|
||||||
"up": "↑",
|
|
||||||
"down": "↓",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def _mods(mask):
|
|
||||||
return [name for bit, name in _MODS if mask & bit]
|
|
||||||
|
|
||||||
|
|
||||||
def _combo(bind):
|
|
||||||
parts = _mods(bind.get("modmask", 0))
|
|
||||||
key = bind.get("key") or ""
|
|
||||||
if not key and bind.get("keycode"):
|
|
||||||
key = f"code {bind['keycode']}"
|
|
||||||
parts.append(_KEY_LABELS.get(key.lower(), key))
|
|
||||||
return " + ".join(p for p in parts if p)
|
|
||||||
|
|
||||||
|
|
||||||
def _action(bind):
|
|
||||||
desc = (bind.get("description") or "").strip()
|
|
||||||
if desc:
|
|
||||||
return desc
|
|
||||||
arg = (bind.get("arg") or "").strip()
|
|
||||||
return f"{bind.get('dispatcher', '?')} {arg}".strip()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
try:
|
|
||||||
raw = subprocess.check_output(["hyprctl", "binds", "-j"], text=True)
|
|
||||||
binds = json.loads(raw)
|
|
||||||
except (OSError, subprocess.CalledProcessError, ValueError) as exc:
|
|
||||||
subprocess.run(["notify-send", "Raccourcis FWS",
|
|
||||||
f"hyprctl binds a échoué : {exc}"], check=False)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
lines = []
|
|
||||||
seen = set()
|
|
||||||
for bind in binds:
|
|
||||||
combo = _combo(bind)
|
|
||||||
if not combo or combo in seen: # binde répétés (resize) : une ligne
|
|
||||||
continue
|
|
||||||
seen.add(combo)
|
|
||||||
lines.append(f"{combo:<24} {_action(bind)}")
|
|
||||||
|
|
||||||
if not lines:
|
|
||||||
lines = ["(aucun raccourci déclaré)"]
|
|
||||||
|
|
||||||
# dmenu = liste + filtre incrémental ; la sélection n'a pas d'effet.
|
|
||||||
cmd = ["wofi", "--dmenu", "--prompt", "Raccourcis clavier — taper pour filtrer",
|
|
||||||
"--width", "820", "--height", "600", "--insensitive",
|
|
||||||
"--cache-file", "/dev/null"]
|
|
||||||
if os.path.exists(_STYLE):
|
|
||||||
# Style dédié : monospace (colonnes alignées) + palette FWS.
|
|
||||||
cmd += ["--style", _STYLE]
|
|
||||||
subprocess.run(cmd, input="\n".join(lines), text=True, check=False)
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
sys.exit(main())
|
|
||||||
+129
@@ -0,0 +1,129 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# FWS — affiche les raccourcis clavier RÉELS de la session (bouton ⌨ de la
|
||||||
|
# barre ou Super+K). Universel :
|
||||||
|
# • Hyprland : « hyprctl binds -j » = les binds effectivement chargés
|
||||||
|
# (descriptions des bindd) — affichage wofi (Wayland).
|
||||||
|
# • i3 : parse ~/.config/i3/config (bindsym, variables résolues)
|
||||||
|
# — affichage rofi (X11).
|
||||||
|
# Aucune dépendance hors python3 + wofi/rofi (déjà installés avec le bureau).
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
_WOFI_STYLE = "/usr/local/share/fws/wofi-keys.css"
|
||||||
|
|
||||||
|
# Bits de modmask Hyprland (masques X11) dans l'ordre d'affichage voulu.
|
||||||
|
_MODS = [(64, "SUPER"), (4, "CTRL"), (8, "ALT"), (1, "SHIFT")]
|
||||||
|
|
||||||
|
_KEY_LABELS = {
|
||||||
|
"mouse:272": "clic gauche",
|
||||||
|
"mouse:273": "clic droit",
|
||||||
|
"mouse:274": "clic molette",
|
||||||
|
"mouse_down": "molette bas",
|
||||||
|
"mouse_up": "molette haut",
|
||||||
|
"button4": "molette haut",
|
||||||
|
"button5": "molette bas",
|
||||||
|
"return": "Entrée",
|
||||||
|
"space": "Espace",
|
||||||
|
"escape": "Échap",
|
||||||
|
"tab": "Tab",
|
||||||
|
"left": "←",
|
||||||
|
"right": "→",
|
||||||
|
"up": "↑",
|
||||||
|
"down": "↓",
|
||||||
|
"print": "Impr écran",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _label(key):
|
||||||
|
return _KEY_LABELS.get(key.lower(), key)
|
||||||
|
|
||||||
|
|
||||||
|
# --- Hyprland : binds réels via hyprctl ------------------------------------
|
||||||
|
def hyprland_lines():
|
||||||
|
raw = subprocess.check_output(["hyprctl", "binds", "-j"], text=True)
|
||||||
|
lines, seen = [], set()
|
||||||
|
for bind in json.loads(raw):
|
||||||
|
parts = [name for bit, name in _MODS if bind.get("modmask", 0) & bit]
|
||||||
|
key = bind.get("key") or (f"code {bind['keycode']}" if bind.get("keycode") else "")
|
||||||
|
parts.append(_label(key))
|
||||||
|
combo = " + ".join(p for p in parts if p)
|
||||||
|
if not combo or combo in seen:
|
||||||
|
continue
|
||||||
|
seen.add(combo)
|
||||||
|
desc = (bind.get("description") or "").strip() \
|
||||||
|
or f"{bind.get('dispatcher', '?')} {(bind.get('arg') or '').strip()}".strip()
|
||||||
|
lines.append(f"{combo:<24} {desc}")
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
# --- i3 : parse de la config (variables résolues) ----------------------------
|
||||||
|
def i3_lines():
|
||||||
|
path = os.path.expanduser("~/.config/i3/config")
|
||||||
|
variables = {}
|
||||||
|
lines, seen = [], set()
|
||||||
|
with open(path, encoding="utf-8", errors="replace") as fh:
|
||||||
|
content = fh.readlines()
|
||||||
|
for line in content:
|
||||||
|
m = re.match(r"\s*set\s+(\$\S+)\s+(.+)$", line)
|
||||||
|
if m:
|
||||||
|
variables[m.group(1)] = m.group(2).strip()
|
||||||
|
def resolve(text):
|
||||||
|
# $var les plus longs d'abord ($filemanager avant $file…).
|
||||||
|
for var in sorted(variables, key=len, reverse=True):
|
||||||
|
text = text.replace(var, variables[var])
|
||||||
|
return text
|
||||||
|
for line in content:
|
||||||
|
m = re.match(r"\s*bindsym\s+(?:--\S+\s+)*(\S+)\s+(.+)$", line)
|
||||||
|
if not m:
|
||||||
|
continue
|
||||||
|
combo_raw, action = m.groups()
|
||||||
|
combo_raw = resolve(combo_raw).replace("Mod4", "Super").replace("Mod1", "Alt")
|
||||||
|
combo = " + ".join(_label(k) for k in combo_raw.split("+"))
|
||||||
|
if combo in seen:
|
||||||
|
continue
|
||||||
|
seen.add(combo)
|
||||||
|
action = resolve(action)
|
||||||
|
action = re.sub(r"^exec\s+(--no-startup-id\s+)?", "", action).strip().strip('"')
|
||||||
|
lines.append(f"{combo:<24} {action}")
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
|
def show(lines):
|
||||||
|
if not lines:
|
||||||
|
lines = ["(aucun raccourci trouvé)"]
|
||||||
|
text = "\n".join(lines)
|
||||||
|
if os.environ.get("HYPRLAND_INSTANCE_SIGNATURE"):
|
||||||
|
cmd = ["wofi", "--dmenu", "--prompt", "Raccourcis clavier — taper pour filtrer",
|
||||||
|
"--width", "820", "--height", "600", "--insensitive",
|
||||||
|
"--cache-file", "/dev/null"]
|
||||||
|
if os.path.exists(_WOFI_STYLE):
|
||||||
|
cmd += ["--style", _WOFI_STYLE]
|
||||||
|
else:
|
||||||
|
# X11/i3 : rofi en dmenu, style assorti (mono pour l'alignement).
|
||||||
|
cmd = ["rofi", "-dmenu", "-i", "-p", "Raccourcis clavier",
|
||||||
|
"-no-custom",
|
||||||
|
"-theme-str", 'window { width: 880px; } listview { lines: 18; }',
|
||||||
|
"-theme-str", '* { font: "Noto Sans Mono 11"; }']
|
||||||
|
subprocess.run(cmd, input=text, text=True, check=False)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
if os.environ.get("HYPRLAND_INSTANCE_SIGNATURE"):
|
||||||
|
lines = hyprland_lines()
|
||||||
|
else:
|
||||||
|
lines = i3_lines()
|
||||||
|
except Exception as exc: # noqa: BLE001 — best effort, jamais de crash muet
|
||||||
|
subprocess.run(["notify-send", "Raccourcis FWS", f"Erreur : {exc}"],
|
||||||
|
check=False)
|
||||||
|
return 1
|
||||||
|
show(lines)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
@@ -24,6 +24,18 @@ if [ "$(id -u)" -ne 0 ]; then
|
|||||||
exec sudo "$0" "$@"
|
exec sudo "$0" "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# VM = cul-de-sac VR : pas d'accès direct au GPU ni à l'USB/DisplayPort du
|
||||||
|
# casque, et Steam (steamwebhelper) est INSTABLE en rendu logiciel (llvmpipe).
|
||||||
|
# On prévient au lieu de laisser l'utilisateur croire à une panne de FWS.
|
||||||
|
if systemd-detect-virt --quiet 2>/dev/null; then
|
||||||
|
warn "Machine VIRTUELLE détectée ($(systemd-detect-virt 2>/dev/null))."
|
||||||
|
warn "La VR ne fonctionnera PAS ici : casque et GPU inaccessibles depuis une VM."
|
||||||
|
warn "Steam lui-même peut planter en rendu logiciel (steamwebhelper)."
|
||||||
|
echo " → Fais cette installation sur la machine RÉELLE avec le casque branché."
|
||||||
|
read -rp " Continuer quand même (tests uniquement) ? [o/N] " _ok
|
||||||
|
case "$_ok" in o|O|oui) ;; *) exit 0 ;; esac
|
||||||
|
fi
|
||||||
|
|
||||||
# lib32 Vulkan selon le GPU (indispensable à SteamVR, qui est 32/64 bits).
|
# lib32 Vulkan selon le GPU (indispensable à SteamVR, qui est 32/64 bits).
|
||||||
GPU="$(lspci 2>/dev/null | grep -iE 'VGA compatible controller|3D controller|Display controller')"
|
GPU="$(lspci 2>/dev/null | grep -iE 'VGA compatible controller|3D controller|Display controller')"
|
||||||
LIB32="lib32-mesa"
|
LIB32="lib32-mesa"
|
||||||
@@ -48,12 +60,20 @@ install_pkgs() {
|
|||||||
|
|
||||||
steamvr_base() {
|
steamvr_base() {
|
||||||
say "Installation de la base SteamVR (Steam + Vulkan 32 bits : $LIB32)…"
|
say "Installation de la base SteamVR (Steam + Vulkan 32 bits : $LIB32)…"
|
||||||
|
# ttf-liberation : polices attendues par l'interface Steam (évite des
|
||||||
|
# rendus cassés/plantages cosmétiques sur install minimale).
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
install_pkgs steam $LIB32 || return 1
|
install_pkgs steam $LIB32 ttf-liberation || return 1
|
||||||
say "Base installée. Étapes suivantes :"
|
say "Base installée. Étapes suivantes :"
|
||||||
echo " 1. Lance Steam, connecte-toi, puis installe « SteamVR » (Bibliothèque → Outils)."
|
echo " 1. Lance Steam, connecte-toi, puis installe « SteamVR » (Bibliothèque → Outils)."
|
||||||
echo " 2. Branche le casque et les stations, puis lance SteamVR."
|
echo " 2. Branche le casque et les stations, puis lance SteamVR."
|
||||||
echo " 3. Premier lancement : SteamVR peut demander à ajuster les règles udev — accepte."
|
echo " 3. Premier lancement : SteamVR peut demander à ajuster les règles udev — accepte."
|
||||||
|
say "Si Steam PLANTE (fenêtre qui se ferme, souvent steamwebhelper) :"
|
||||||
|
echo " • Vérifie l'espace disque (SteamVR ≈ 5 Go) : df -h ~"
|
||||||
|
echo " • GPU faible / VM / rendu logiciel — lance :"
|
||||||
|
echo " steam -cef-disable-gpu -cef-disable-gpu-compositing"
|
||||||
|
echo " • Pour voir l'erreur exacte : lance « steam » depuis un terminal,"
|
||||||
|
echo " ou regarde ~/.steam/steam/logs/ (console_log.txt, bootstrap_log.txt)."
|
||||||
}
|
}
|
||||||
|
|
||||||
case "${1:-menu}" in
|
case "${1:-menu}" in
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
# Les raccourcis sont déclarés avec « bindd » (bind + description) : la
|
# Les raccourcis sont déclarés avec « bindd » (bind + description) : la
|
||||||
# description alimente l'écran « Raccourcis clavier » (bouton ⌨ de la barre
|
# description alimente l'écran « Raccourcis clavier » (bouton ⌨ de la barre
|
||||||
# ou SUPER+K → fws-hypr-keys, qui lit les binds RÉELS via hyprctl). Ajoute
|
# ou SUPER+K → fws-keys, qui lit les binds RÉELS via hyprctl). Ajoute
|
||||||
# tes propres bindd : ils apparaîtront automatiquement dans la liste.
|
# tes propres bindd : ils apparaîtront automatiquement dans la liste.
|
||||||
# ⚠ Pas de virgule dans les descriptions (séparateur de champs Hyprland).
|
# ⚠ Pas de virgule dans les descriptions (séparateur de champs Hyprland).
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ bindd = $mod SHIFT, Return, Terminal flottant, exec, kitty --class floating-term
|
|||||||
bindd = $mod, R, Menu des applications, exec, wofi --show drun
|
bindd = $mod, R, Menu des applications, exec, wofi --show drun
|
||||||
bindd = $mod, E, Gestionnaire de fichiers, exec, thunar
|
bindd = $mod, E, Gestionnaire de fichiers, exec, thunar
|
||||||
bindd = $mod, B, Ouvrir Firefox, exec, firefox
|
bindd = $mod, B, Ouvrir Firefox, exec, firefox
|
||||||
bindd = $mod, K, Afficher les raccourcis clavier, exec, fws-hypr-keys
|
bindd = $mod, K, Afficher les raccourcis clavier, exec, fws-keys
|
||||||
|
|
||||||
# --- Fenêtres ---------------------------------------------------------------
|
# --- Fenêtres ---------------------------------------------------------------
|
||||||
bindd = $mod, Q, Fermer la fenêtre, killactive,
|
bindd = $mod, Q, Fermer la fenêtre, killactive,
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ bindsym $mod+e exec $filemanager
|
|||||||
bindsym $mod+b exec $browser
|
bindsym $mod+b exec $browser
|
||||||
# VR : installation des drivers/runtimes casque (HTC Vive, Index, Quest…)
|
# VR : installation des drivers/runtimes casque (HTC Vive, Index, Quest…)
|
||||||
bindsym $mod+Shift+v exec kitty -e fws-vr-setup
|
bindsym $mod+Shift+v exec kitty -e fws-vr-setup
|
||||||
|
# Panneau des raccourcis clavier (aussi via le bouton ⌌ de la barre)
|
||||||
|
bindsym $mod+k exec fws-keys
|
||||||
|
|
||||||
##############
|
##############
|
||||||
## FENETRES ##
|
## FENETRES ##
|
||||||
@@ -133,23 +135,16 @@ for_window [title="Picture-in-Picture"] floating enable
|
|||||||
###########
|
###########
|
||||||
## BARRE ##
|
## BARRE ##
|
||||||
###########
|
###########
|
||||||
bar {
|
# Polybar (config ~/.config/polybar/config.ini) : clone visuel de la waybar
|
||||||
status_command i3status
|
# Hyprland FWS — pilules, icônes, horloge+date au centre, bouton Raccourcis.
|
||||||
position top
|
# exec_always + pkill : la barre survit proprement aux reload ($mod+Shift+c).
|
||||||
colors {
|
exec_always --no-startup-id sh -c 'pkill -x polybar; sleep 0.3; exec polybar -q fws'
|
||||||
background $base
|
|
||||||
statusline $text
|
|
||||||
separator $surface0
|
|
||||||
# classe bordure fond texte
|
|
||||||
focused_workspace $blue $blue $base
|
|
||||||
inactive_workspace $surface0 $base $text
|
|
||||||
urgent_workspace $red $red $base
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
###############
|
###############
|
||||||
## AUTOSTART ##
|
## AUTOSTART ##
|
||||||
###############
|
###############
|
||||||
|
# picom : coins arrondis (parité visuelle avec Hyprland) — config FWS légère.
|
||||||
|
exec --no-startup-id picom --config ~/.config/picom.conf
|
||||||
exec --no-startup-id dunst
|
exec --no-startup-id dunst
|
||||||
exec --no-startup-id nm-applet
|
exec --no-startup-id nm-applet
|
||||||
exec --no-startup-id /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
|
exec --no-startup-id /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# FWS — picom minimal (session i3) : coins arrondis comme sous Hyprland.
|
||||||
|
# xrender : fiable partout, y compris en VM (rendu logiciel) ; pas de flou ni
|
||||||
|
# d'ombres (parité avec la config Hyprland FWS, et léger pour la VR).
|
||||||
|
backend = "xrender";
|
||||||
|
vsync = true;
|
||||||
|
|
||||||
|
corner-radius = 8;
|
||||||
|
rounded-corners-exclude = [
|
||||||
|
"window_type = 'dock'", # polybar gère son propre arrondi
|
||||||
|
"class_g = 'i3-frame'"
|
||||||
|
];
|
||||||
|
|
||||||
|
shadow = false;
|
||||||
|
fading = true;
|
||||||
|
fade-in-step = 0.08;
|
||||||
|
fade-out-step = 0.08;
|
||||||
|
|
||||||
|
# VR / jeux plein écran : ne pas composer par-dessus (latence).
|
||||||
|
unredir-if-possible = true;
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
; FWS — polybar (session i3) : clone visuel de la waybar Hyprland.
|
||||||
|
; Barre flottante arrondie, modules en « pilules » Catppuccin Mocha,
|
||||||
|
; icônes Nerd Font (ttf-nerd-fonts-symbols). Horloge + date au centre,
|
||||||
|
; bouton « ⌌ Raccourcis » (fws-keys), volume/réseau/CPU/RAM/tray à droite.
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
base = #E01e1e2e
|
||||||
|
surface0 = #313244
|
||||||
|
text = #cdd6f4
|
||||||
|
subtext = #a6adc8
|
||||||
|
blue = #89b4fa
|
||||||
|
sapphire = #74c7ec
|
||||||
|
teal = #94e2d5
|
||||||
|
mauve = #cba6f7
|
||||||
|
maroon = #eba0ac
|
||||||
|
yellow = #f9e2af
|
||||||
|
red = #f38ba8
|
||||||
|
darkbase = #1e1e2e
|
||||||
|
|
||||||
|
[bar/fws]
|
||||||
|
monitor = ${env:MONITOR:}
|
||||||
|
width = 100%:-20
|
||||||
|
offset-x = 10
|
||||||
|
offset-y = 6
|
||||||
|
height = 36
|
||||||
|
radius = 14
|
||||||
|
background = ${colors.base}
|
||||||
|
foreground = ${colors.text}
|
||||||
|
border-size = 1
|
||||||
|
border-color = #5989b4fa
|
||||||
|
padding-left = 1
|
||||||
|
padding-right = 1
|
||||||
|
module-margin = 1
|
||||||
|
line-size = 0
|
||||||
|
font-0 = Noto Sans:size=10;2
|
||||||
|
font-1 = Symbols Nerd Font:size=12;3
|
||||||
|
font-2 = Noto Sans:weight=bold:size=10;2
|
||||||
|
modules-left = i3 xwindow
|
||||||
|
modules-center = date
|
||||||
|
modules-right = keyhelp backlight pulseaudio network cpu memory tray
|
||||||
|
enable-ipc = true
|
||||||
|
wm-restack = i3
|
||||||
|
|
||||||
|
[module/i3]
|
||||||
|
type = internal/i3
|
||||||
|
pin-workspaces = true
|
||||||
|
show-urgent = true
|
||||||
|
strip-wsnumbers = false
|
||||||
|
format = <label-state> <label-mode>
|
||||||
|
label-focused = %name%
|
||||||
|
label-focused-background = ${colors.blue}
|
||||||
|
label-focused-foreground = ${colors.darkbase}
|
||||||
|
label-focused-padding = 2
|
||||||
|
label-unfocused = %name%
|
||||||
|
label-unfocused-background = ${colors.surface0}
|
||||||
|
label-unfocused-foreground = ${colors.subtext}
|
||||||
|
label-unfocused-padding = 2
|
||||||
|
label-visible = %name%
|
||||||
|
label-visible-background = ${colors.surface0}
|
||||||
|
label-visible-padding = 2
|
||||||
|
label-urgent = %name%
|
||||||
|
label-urgent-background = ${colors.red}
|
||||||
|
label-urgent-foreground = ${colors.darkbase}
|
||||||
|
label-urgent-padding = 2
|
||||||
|
|
||||||
|
[module/xwindow]
|
||||||
|
type = internal/xwindow
|
||||||
|
label = %title:0:45:…%
|
||||||
|
label-foreground = ${colors.subtext}
|
||||||
|
format-padding = 1
|
||||||
|
|
||||||
|
[module/date]
|
||||||
|
type = internal/date
|
||||||
|
interval = 1
|
||||||
|
date = %A %d %B %Y
|
||||||
|
time = %H:%M
|
||||||
|
label = %time% %date%
|
||||||
|
label-font = 3
|
||||||
|
format-background = ${colors.surface0}
|
||||||
|
format-padding = 3
|
||||||
|
|
||||||
|
[module/keyhelp]
|
||||||
|
type = custom/script
|
||||||
|
exec = echo " Raccourcis"
|
||||||
|
interval = 3600
|
||||||
|
click-left = fws-keys
|
||||||
|
format-background = ${colors.blue}
|
||||||
|
format-foreground = ${colors.darkbase}
|
||||||
|
format-padding = 2
|
||||||
|
label-font = 3
|
||||||
|
|
||||||
|
[module/backlight]
|
||||||
|
type = internal/backlight
|
||||||
|
enable-scroll = true
|
||||||
|
format = <label>
|
||||||
|
label = %percentage%%
|
||||||
|
format-background = ${colors.surface0}
|
||||||
|
format-foreground = ${colors.yellow}
|
||||||
|
format-padding = 2
|
||||||
|
|
||||||
|
[module/pulseaudio]
|
||||||
|
type = internal/pulseaudio
|
||||||
|
use-ui-max = false
|
||||||
|
click-right = pavucontrol
|
||||||
|
format-volume = <label-volume>
|
||||||
|
label-volume = %percentage%%
|
||||||
|
format-volume-background = ${colors.surface0}
|
||||||
|
format-volume-foreground = ${colors.blue}
|
||||||
|
format-volume-padding = 2
|
||||||
|
label-muted = muet
|
||||||
|
format-muted-background = ${colors.surface0}
|
||||||
|
format-muted-foreground = ${colors.subtext}
|
||||||
|
format-muted-padding = 2
|
||||||
|
|
||||||
|
[module/network]
|
||||||
|
type = internal/network
|
||||||
|
interface-type = wired
|
||||||
|
interval = 5
|
||||||
|
format-connected = <label-connected>
|
||||||
|
label-connected = %local_ip%
|
||||||
|
format-connected-background = ${colors.surface0}
|
||||||
|
format-connected-foreground = ${colors.teal}
|
||||||
|
format-connected-padding = 2
|
||||||
|
format-disconnected = <label-disconnected>
|
||||||
|
label-disconnected = hors ligne
|
||||||
|
format-disconnected-background = ${colors.surface0}
|
||||||
|
format-disconnected-foreground = ${colors.red}
|
||||||
|
format-disconnected-padding = 2
|
||||||
|
|
||||||
|
[module/cpu]
|
||||||
|
type = internal/cpu
|
||||||
|
interval = 3
|
||||||
|
label = %percentage%%
|
||||||
|
format-background = ${colors.surface0}
|
||||||
|
format-foreground = ${colors.mauve}
|
||||||
|
format-padding = 2
|
||||||
|
|
||||||
|
[module/memory]
|
||||||
|
type = internal/memory
|
||||||
|
interval = 3
|
||||||
|
label = %percentage_used%%
|
||||||
|
format-background = ${colors.surface0}
|
||||||
|
format-foreground = ${colors.maroon}
|
||||||
|
format-padding = 2
|
||||||
|
|
||||||
|
[module/tray]
|
||||||
|
type = internal/tray
|
||||||
|
format = <tray>
|
||||||
|
format-background = ${colors.surface0}
|
||||||
|
format-padding = 1
|
||||||
|
tray-spacing = 8px
|
||||||
|
tray-size = 16px
|
||||||
|
|
||||||
|
[settings]
|
||||||
|
screenchange-reload = true
|
||||||
|
pseudo-transparency = false
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"custom/keyhelp": {
|
"custom/keyhelp": {
|
||||||
"format": " Raccourcis",
|
"format": " Raccourcis",
|
||||||
"tooltip-format": "Raccourcis clavier (SUPER+K)",
|
"tooltip-format": "Raccourcis clavier (SUPER+K)",
|
||||||
"on-click": "fws-hypr-keys"
|
"on-click": "fws-keys"
|
||||||
},
|
},
|
||||||
"backlight": {
|
"backlight": {
|
||||||
"format": "{icon} {percent}%",
|
"format": "{icon} {percent}%",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* FWS — style du panneau « Raccourcis clavier » (fws-hypr-keys).
|
/* FWS — style du panneau « Raccourcis clavier » (fws-keys).
|
||||||
Même palette que le menu wofi, mais police MONOSPACE : les colonnes
|
Même palette que le menu wofi, mais police MONOSPACE : les colonnes
|
||||||
combinaison/description sont alignées par des espaces. */
|
combinaison/description sont alignées par des espaces. */
|
||||||
|
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ case "$DESK" in
|
|||||||
# xorg-server est requis (SDDM ne le tire pas) ; maim+xclip = captures X11,
|
# xorg-server est requis (SDDM ne le tire pas) ; maim+xclip = captures X11,
|
||||||
# dunst = notifications X11 (équivalent de mako), i3lock = verrouillage.
|
# dunst = notifications X11 (équivalent de mako), i3lock = verrouillage.
|
||||||
# fws-vr-setup (Super+Shift+V ou menu) installe les drivers du casque.
|
# fws-vr-setup (Super+Shift+V ou menu) installe les drivers du casque.
|
||||||
i3) PKGS="i3-wm i3status i3lock xorg-server rofi kitty thunar sddm noto-fonts ttf-nerd-fonts-symbols maim xclip dunst libnotify polkit-gnome network-manager-applet gvfs playerctl brightnessctl pipewire pipewire-alsa pipewire-pulse wireplumber pavucontrol bluez bluez-utils blueman"; DM="sddm" ;;
|
i3) PKGS="i3-wm i3lock xorg-server polybar picom rofi kitty thunar sddm noto-fonts ttf-nerd-fonts-symbols maim xclip dunst libnotify polkit-gnome network-manager-applet gvfs playerctl brightnessctl pipewire pipewire-alsa pipewire-pulse wireplumber pavucontrol bluez bluez-utils blueman"; DM="sddm" ;;
|
||||||
cli|*) PKGS="" ;;
|
cli|*) PKGS="" ;;
|
||||||
esac
|
esac
|
||||||
# Navigateur de base ajouté DÈS QU'un bureau est choisi (jamais en CLI).
|
# Navigateur de base ajouté DÈS QU'un bureau est choisi (jamais en CLI).
|
||||||
@@ -414,13 +414,13 @@ if [ "$DESK" = "hyprland" ] && [ -f /usr/local/share/fws/hyprland.conf.tmpl ]; t
|
|||||||
sed -e "s/__KB_LAYOUT__/${XL:-us}/" -e "s/__KB_VARIANT__/${XV}/" \
|
sed -e "s/__KB_LAYOUT__/${XL:-us}/" -e "s/__KB_VARIANT__/${XV}/" \
|
||||||
/usr/local/share/fws/hyprland.conf.tmpl > /tmp/fws-hyprland.conf
|
/usr/local/share/fws/hyprland.conf.tmpl > /tmp/fws-hyprland.conf
|
||||||
install -Dm644 /tmp/fws-hyprland.conf /etc/skel/.config/hypr/hyprland.conf
|
install -Dm644 /tmp/fws-hyprland.conf /etc/skel/.config/hypr/hyprland.conf
|
||||||
# Waybar FWS : barre assortie + bouton « ⌨ Raccourcis » (fws-hypr-keys,
|
# Waybar FWS : barre assortie + bouton « ⌨ Raccourcis » (fws-keys,
|
||||||
# aussi sur SUPER+K) qui liste les binds RÉELS chargés par Hyprland
|
# aussi sur SUPER+K) qui liste les binds RÉELS chargés par Hyprland
|
||||||
# (hyprctl binds -j) — les descriptions viennent des bindd de la config.
|
# (hyprctl binds -j) — les descriptions viennent des bindd de la config.
|
||||||
install -Dm644 /usr/local/share/fws/waybar-config.json /etc/skel/.config/waybar/config
|
install -Dm644 /usr/local/share/fws/waybar-config.json /etc/skel/.config/waybar/config
|
||||||
install -Dm644 /usr/local/share/fws/waybar-style.css /etc/skel/.config/waybar/style.css
|
install -Dm644 /usr/local/share/fws/waybar-style.css /etc/skel/.config/waybar/style.css
|
||||||
# wofi : style du menu d'applications (Super+R) — le panneau « Raccourcis »
|
# wofi : style du menu d'applications (Super+R) — le panneau « Raccourcis »
|
||||||
# a son propre style (wofi-keys.css), passé en --style par fws-hypr-keys.
|
# a son propre style (wofi-keys.css), passé en --style par fws-keys.
|
||||||
install -Dm644 /usr/local/share/fws/wofi-config /etc/skel/.config/wofi/config
|
install -Dm644 /usr/local/share/fws/wofi-config /etc/skel/.config/wofi/config
|
||||||
install -Dm644 /usr/local/share/fws/wofi-style.css /etc/skel/.config/wofi/style.css
|
install -Dm644 /usr/local/share/fws/wofi-style.css /etc/skel/.config/wofi/style.css
|
||||||
while IFS=: read -r _u _x _uid _g _gec _home _sh; do
|
while IFS=: read -r _u _x _uid _g _gec _home _sh; do
|
||||||
@@ -442,11 +442,18 @@ fi
|
|||||||
# /etc/X11/xorg.conf.d/00-keyboard.conf, écrite à l'étape 3bis.
|
# /etc/X11/xorg.conf.d/00-keyboard.conf, écrite à l'étape 3bis.
|
||||||
if [ "$DESK" = "i3" ] && [ -f /usr/local/share/fws/i3-config ]; then
|
if [ "$DESK" = "i3" ] && [ -f /usr/local/share/fws/i3-config ]; then
|
||||||
install -Dm644 /usr/local/share/fws/i3-config /etc/skel/.config/i3/config
|
install -Dm644 /usr/local/share/fws/i3-config /etc/skel/.config/i3/config
|
||||||
|
# Polybar (clone de la waybar) + picom (coins arrondis) : même rendu
|
||||||
|
# visuel que la session Hyprland FWS.
|
||||||
|
install -Dm644 /usr/local/share/fws/polybar-config.ini /etc/skel/.config/polybar/config.ini
|
||||||
|
install -Dm644 /usr/local/share/fws/picom.conf /etc/skel/.config/picom.conf
|
||||||
while IFS=: read -r _u _x _uid _g _gec _home _sh; do
|
while IFS=: read -r _u _x _uid _g _gec _home _sh; do
|
||||||
[ "$_uid" -ge 1000 ] && [ "$_uid" -le 60000 ] && [ -d "$_home" ] || continue
|
[ "$_uid" -ge 1000 ] && [ "$_uid" -le 60000 ] && [ -d "$_home" ] || continue
|
||||||
install -Dm644 /usr/local/share/fws/i3-config "$_home/.config/i3/config"
|
install -Dm644 /usr/local/share/fws/i3-config "$_home/.config/i3/config"
|
||||||
|
install -Dm644 /usr/local/share/fws/polybar-config.ini "$_home/.config/polybar/config.ini"
|
||||||
|
install -Dm644 /usr/local/share/fws/picom.conf "$_home/.config/picom.conf"
|
||||||
chown "$_u": "$_home/.config" 2>/dev/null || true
|
chown "$_u": "$_home/.config" 2>/dev/null || true
|
||||||
chown -R "$_u": "$_home/.config/i3" 2>/dev/null || true
|
chown -R "$_u": "$_home/.config/i3" "$_home/.config/polybar" \
|
||||||
|
"$_home/.config/picom.conf" 2>/dev/null || true
|
||||||
done < /etc/passwd
|
done < /etc/passwd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,6 @@ file_permissions=(
|
|||||||
["/usr/bin/load_policy"]="0:0:755"
|
["/usr/bin/load_policy"]="0:0:755"
|
||||||
["/usr/bin/setstatus"]="0:0:755"
|
["/usr/bin/setstatus"]="0:0:755"
|
||||||
["/usr/local/bin/fws-setup-hardware"]="0:0:755"
|
["/usr/local/bin/fws-setup-hardware"]="0:0:755"
|
||||||
["/usr/local/bin/fws-hypr-keys"]="0:0:755"
|
["/usr/local/bin/fws-keys"]="0:0:755"
|
||||||
["/usr/local/bin/fws-vr-setup"]="0:0:755"
|
["/usr/local/bin/fws-vr-setup"]="0:0:755"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user