feat(hyprland): add hyprland configuration with keyboard layout injection and vm compatibility

Add Hyprland desktop environment support with:

- New hyprland.conf template with keyboard layout placeholders (__KB_LAYOUT__ and __KB_VARIANT__) that get injected during installation
- Hyprland wrapper script (/usr/local/bin/fws-hyprland) that detects virtual machines and forces software rendering to prevent compositor crashes on virtual GPUs (VMware vmwgfx, VirtualBox)
- Automatic configuration deployment to /etc/skel and existing user home directories
- Refactored keyboard layout detection logic (moved to section 3bis) to support both X11/SDDM and Hyprland configurations
- Added locale generation during installation to ensure proper language support

Keyboard layout is now derived from either kickstart configuration or system locale using langtable, providing consistent keyboard behavior across all desktop environments.
This commit is contained in:
2026-06-24 23:06:20 +02:00
parent ff98a1e186
commit 99006b9ede
2 changed files with 142 additions and 26 deletions
@@ -205,6 +205,44 @@ else
echo "[FWS] AVERTISSEMENT : grub-install a échoué — bootloader à refaire à la main"
fi
# --- 3bis) Clavier (X11) + LOCALE --------------------------------------------
# CLAVIER : Anaconda passe par localed et n'écrit pas fiablement la disposition X
# sur la CIBLE → SDDM / sessions X en QWERTY US. On CALCULE la disposition CHOISIE
# (kickstart généré, sinon dérivée de la locale via langtable) en XL/XV, réutilisés
# plus bas (00-keyboard.conf pour SDDM/X ET la config Hyprland qui a son propre
# kb_layout). LOCALE : le locale choisi (ex. fr_CH.UTF-8) doit être GÉNÉRÉ —
# Anaconda vient de Fedora (locales pré-générées) et ne lance pas locale-gen →
# sans ça LANG casse et tout retombe en C.
XL=""; XV=""
XKB="$(sed -n "s/.*--xlayouts=//p" /root/anaconda-ks.cfg 2>/dev/null | head -1)"
XKB="${XKB#[\'\"]}"; XKB="${XKB%%[\'\"]*}"; XKB="${XKB%%,*}" # 1re dispo, ex. « ch (fr) »
if [ -z "$XKB" ]; then
_loc="$(. /etc/locale.conf 2>/dev/null; printf '%s' "${LANG%%.*}")" # fr_CH
_lng="${_loc%%_*}"; _terr="${_loc#*_}"; [ "$_terr" = "$_loc" ] && _terr=""
[ -n "$_terr" ] && XKB="$(python3 -c "import langtable; k=langtable.list_keyboards(languageId='$_lng', territoryId='$_terr'); print(k[0] if k else '')" 2>/dev/null)"
fi
if [ -n "$XKB" ]; then
XL="${XKB%%(*}"; XL="${XL%% *}" # ch
case "$XKB" in *'('*')') XV="${XKB#*(}"; XV="${XV%)}" ;; *) XV="" ;; esac # fr
install -d /etc/X11/xorg.conf.d
cat > /etc/X11/xorg.conf.d/00-keyboard.conf <<KBEOF
Section "InputClass"
Identifier "system-keyboard"
MatchIsKeyboard "on"
Option "XkbLayout" "$XL"
Option "XkbVariant" "$XV"
EndSection
KBEOF
fi
FWSLANG="$(. /etc/locale.conf 2>/dev/null; printf '%s' "${LANG:-}")"
if [ -n "$FWSLANG" ]; then
_cs="${FWSLANG##*.}"; [ "$_cs" = "$FWSLANG" ] && _cs="UTF-8"
grep -qE "^[[:space:]]*${FWSLANG}[[:space:]]+${_cs}\b" /etc/locale.gen 2>/dev/null \
|| printf '%s %s\n' "$FWSLANG" "$_cs" >> /etc/locale.gen
locale-gen || echo "[FWS] locale-gen a échoué pour $FWSLANG"
fi
# --- 4) Bureau choisi : pacman -S du DE (non bloquant si pas de réseau) -------
DESK="cli"
[ -f /tmp/fws-desktop ] && DESK="$(tr -d '[:space:]' < /tmp/fws-desktop)"
@@ -229,37 +267,54 @@ if [ -n "$PKGS" ]; then
install -d /etc/sddm.conf.d
printf '[General]\nNumlock=on\n' > /etc/sddm.conf.d/10-fws.conf
fi
# Hyprland en VM : sur GPU virtuel (VMware/VirtualBox) le compositeur
# crashe au lancement → SDDM « remet au login ». On le lance via un
# wrapper qui force le rendu LOGICIEL UNIQUEMENT en VM (systemd-detect-virt)
# ; sur un vrai GPU le rendu matériel est conservé.
if [ "$DESK" = "hyprland" ]; then
cat > /usr/local/bin/fws-hyprland <<'HYEOF'
#!/bin/sh
if systemd-detect-virt --quiet 2>/dev/null; then
# GPU virtuel (VMware vmwgfx…) : on FORCE le chemin d'affichage 100% logiciel.
# La PIÈCE MAÎTRESSE est MESA_LOADER_DRIVER_OVERRIDE=kms_swrast : elle force
# Mesa à allouer le GBM/EGL via kms_swrast (rendu logiciel dans les « dumb
# buffers » KMS) AU LIEU du pilote vmwgfx (qui ne fournit pas le GBM dont
# aquamarine a besoin → « CBackend::create() failed »). + llvmpipe pour le GL.
export MESA_LOADER_DRIVER_OVERRIDE=kms_swrast
export GALLIUM_DRIVER=llvmpipe LIBGL_ALWAYS_SOFTWARE=1
export WLR_RENDERER_ALLOW_SOFTWARE=1 WLR_NO_HARDWARE_CURSORS=1
export AQ_NO_ATOMIC=1
fi
exec Hyprland "$@"
HYEOF
chmod 755 /usr/local/bin/fws-hyprland
if [ -f /usr/share/wayland-sessions/hyprland.desktop ]; then
sed -i 's|^Exec=.*|Exec=/usr/local/bin/fws-hyprland|' \
/usr/share/wayland-sessions/hyprland.desktop
fi
fi
else
echo "[FWS] Bureau '$DESK' non installé (réseau ?) — à refaire après le 1er boot."
fi
fi
# --- Clavier X11 (SDDM + sessions graphiques) --------------------------------
# SDDM et les sessions X/Wayland (kwin lit aussi ce fichier) prennent leur
# disposition de /etc/X11/xorg.conf.d/00-keyboard.conf. Anaconda passe par localed
# qui ne l'écrit pas fiablement sur la CIBLE → écran SDDM en QWERTY US → le mot de
# passe (tapé sur le clavier choisi, ex. suisse QWERTZ) ne correspond pas. On
# l'écrit donc nous-mêmes, depuis la disposition X CHOISIE (kickstart généré),
# sinon dérivée de la locale via langtable. Cohérent avec le clavier du GUI.
XKB="$(sed -n "s/.*--xlayouts=//p" /root/anaconda-ks.cfg 2>/dev/null | head -1)"
XKB="${XKB#[\'\"]}"; XKB="${XKB%%[\'\"]*}"; XKB="${XKB%%,*}" # 1re dispo, ex. « ch (fr) »
if [ -z "$XKB" ]; then
_loc="$(. /etc/locale.conf 2>/dev/null; printf '%s' "${LANG%%.*}")" # fr_CH
_lng="${_loc%%_*}"; _terr="${_loc#*_}"; [ "$_terr" = "$_loc" ] && _terr=""
[ -n "$_terr" ] && XKB="$(python3 -c "import langtable; k=langtable.list_keyboards(languageId='$_lng', territoryId='$_terr'); print(k[0] if k else '')" 2>/dev/null)"
fi
if [ -n "$XKB" ]; then
XL="${XKB%%(*}"; XL="${XL%% *}" # ch
case "$XKB" in *'('*')') XV="${XKB#*(}"; XV="${XV%)}" ;; *) XV="" ;; esac # fr
install -d /etc/X11/xorg.conf.d
cat > /etc/X11/xorg.conf.d/00-keyboard.conf <<KBEOF
Section "InputClass"
Identifier "system-keyboard"
MatchIsKeyboard "on"
Option "XkbLayout" "$XL"
Option "XkbVariant" "$XV"
EndSection
KBEOF
# --- Config Hyprland (si choisi) : clavier + apps + waybar -------------------
# Hyprland (Wayland) NE lit PAS /etc/X11/xorg.conf.d/00-keyboard.conf : sa
# disposition est dans SA config (input { kb_layout }). Sans config il démarre nu
# (QWERTY US, aucune touche utile). On déploie une config FWS (template +
# clavier XL/XV injecté) dans /etc/skel ET le home de chaque utilisateur déjà
# créé par Anaconda (le %post tourne APRÈS la création de l'utilisateur).
if [ "$DESK" = "hyprland" ] && [ -f /usr/local/share/fws/hyprland.conf.tmpl ]; then
sed -e "s/__KB_LAYOUT__/${XL:-us}/" -e "s/__KB_VARIANT__/${XV}/" \
/usr/local/share/fws/hyprland.conf.tmpl > /tmp/fws-hyprland.conf
install -Dm644 /tmp/fws-hyprland.conf /etc/skel/.config/hypr/hyprland.conf
while IFS=: read -r _u _x _uid _g _gec _home _sh; do
[ "$_uid" -ge 1000 ] && [ "$_uid" -le 60000 ] && [ -d "$_home" ] || continue
install -Dm644 /tmp/fws-hyprland.conf "$_home/.config/hypr/hyprland.conf"
chown "$_u": "$_home/.config" 2>/dev/null || true
chown -R "$_u": "$_home/.config/hypr" 2>/dev/null || true
done < /etc/passwd
rm -f /tmp/fws-hyprland.conf
fi
# --- 4bis) Sudo : l'utilisateur créé doit pouvoir administrer -----------------