#!/usr/bin/env python3 # FWS — fenêtre de bienvenue au premier démarrage (pendant post-install de la # page récap de l'installateur). Boutons : mise à jour, codecs, VR, raccourcis, # Proton-GE. GTK3 : présent sur TOUS les bureaux FWS (Firefox le tire) ; # python-gobject est installé avec le bureau par le kickstart. # # Lancement : /etc/xdg/autostart (KDE/GNOME/XFCE) et exec des configs # Hyprland/i3, toujours avec --autostart : on se retire sans bruit si # l'utilisateur a coché « ne plus afficher » (~/.config/fws/hello-done). import os import shutil import subprocess import sys import gi gi.require_version("Gtk", "3.0") gi.require_version("Gdk", "3.0") # sinon gi charge Gdk 4.0 (conflit avec Gtk3) from gi.repository import Gdk, GLib, Gtk # noqa: E402 # WM_CLASS déterministe : les règles i3/Hyprland « fenêtre flottante » # ciblent cette classe. GLib.set_prgname("fws-hello") _FLAG = os.path.expanduser("~/.config/fws/hello-done") _CODECS = ("gst-plugins-base gst-plugins-good gst-plugins-bad " "gst-plugins-ugly gst-libav ffmpeg mpv") # (libellé, description, commande, en_terminal) _ACTIONS = [ ("Mettre à jour le système", "pacman -Syu + nettoyage du cache", "fws-update", True), ("Installer les codecs multimédia", "lecture vidéo/audio (GStreamer, ffmpeg, mpv)", f"sudo pacman -S --needed {_CODECS}", True), ("Proton-GE pour Steam", "meilleure compatibilité des jeux Windows", "fws-proton-ge", True), ("Configurer la VR", "drivers casque : HTC Vive, Index, Quest…", "fws-vr-setup", True), ] _TERMINALS = ["kitty", "konsole", "gnome-terminal", "xfce4-terminal", "xterm"] def _terminal(): for term in _TERMINALS: if shutil.which(term): return term return None def _run(command, in_terminal): if in_terminal: term = _terminal() if term is None: return if term == "gnome-terminal": argv = [term, "--", "sh", "-c", command] else: argv = [term, "-e", "sh", "-c", command] else: argv = ["sh", "-c", command] subprocess.Popen(argv) # noqa: S603 — commandes internes FWS class HelloWindow(Gtk.Window): def __init__(self): super().__init__(title="Bienvenue sur FWS") self.set_default_size(460, -1) self.set_position(Gtk.WindowPosition.CENTER) self.set_border_width(18) # DIALOGUE : les tuileurs (i3/Hyprland) laissent les dialogues en # flottant → la fenêtre garde sa taille naturelle au lieu d'être # étirée sur tout l'espace de travail (layout illisible sinon). self.set_type_hint(Gdk.WindowTypeHint.DIALOG) self.set_resizable(False) box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12) self.add(box) title = Gtk.Label() title.set_markup("Bienvenue sur FWS !") box.pack_start(title, False, False, 0) subtitle = Gtk.Label( label="Ton système est prêt. Quelques réglages utiles pour bien démarrer :") subtitle.set_line_wrap(True) subtitle.set_xalign(0) box.pack_start(subtitle, False, False, 0) actions = list(_ACTIONS) # Raccourcis clavier : uniquement sur les sessions qui ont fws-keys # (Hyprland/i3) — les autres bureaux ont leurs propres réglages. session = os.environ.get("XDG_CURRENT_DESKTOP", "").lower() if os.environ.get("HYPRLAND_INSTANCE_SIGNATURE") or "i3" in session: actions.append(("Voir les raccourcis clavier", "aussi disponible à tout moment : Super+K", "fws-keys", False)) for label, desc, command, in_term in actions: button = Gtk.Button() inner = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2) lab = Gtk.Label() lab.set_markup(f"{label}") lab.set_xalign(0) sub = Gtk.Label(label=desc) sub.set_xalign(0) sub.get_style_context().add_class("dim-label") inner.pack_start(lab, False, False, 0) inner.pack_start(sub, False, False, 0) button.add(inner) button.connect("clicked", lambda _b, c=command, t=in_term: _run(c, t)) box.pack_start(button, False, False, 0) self._again = Gtk.CheckButton(label="Afficher cette fenêtre au prochain démarrage") self._again.set_active(False) box.pack_start(self._again, False, False, 6) close = Gtk.Button(label="Fermer") close.connect("clicked", lambda _b: self.close()) box.pack_start(close, False, False, 0) self.connect("destroy", self._on_destroy) def _on_destroy(self, _win): if not self._again.get_active(): os.makedirs(os.path.dirname(_FLAG), exist_ok=True) with open(_FLAG, "w") as fh: fh.write("ok\n") else: try: os.unlink(_FLAG) except OSError: pass Gtk.main_quit() def main(): if "--autostart" in sys.argv and os.path.exists(_FLAG): return 0 # Pas d'affichage joignable (lancement hors session graphique) : on se # retire sans traceback plutôt que de crasher. if not Gtk.init_check()[0]: return 1 win = HelloWindow() win.show_all() Gtk.main() return 0 if __name__ == "__main__": sys.exit(main())