From 2afe810d73b0f2c48876211dd249eb84b793785a Mon Sep 17 00:00:00 2001 From: humocs-man <251756307+humocs-man@users.noreply.github.com> Date: Sun, 27 Sep 2026 20:02:45 +0200 Subject: [PATCH] xdg-user-dirs im Autostart, kanshi VM-Moduswahl --- configs/skel/.config/labwc/autostart | 6 +++ scripts/kanshi-autoconfig | 57 ++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/configs/skel/.config/labwc/autostart b/configs/skel/.config/labwc/autostart index 8d15129..5c355ed 100644 --- a/configs/skel/.config/labwc/autostart +++ b/configs/skel/.config/labwc/autostart @@ -1,6 +1,12 @@ # labwc-Autostart – fluffy-pancake (Noctalia-Zweig) # Tastatur/Locale stehen in ~/.config/labwc/environment. +# 0. XDG-Standardordner (Dokumente, Bilder, Videos, ...) anlegen bzw. +# bei Locale-Wechsel umbenennen. Laeuft unter labwc sonst nie +# (kein X-Session-Autostart); u.a. braucht Noctalias Wallpaper-Picker +# ~/Bilder. Idempotent - macht bei existierenden Ordnern nichts. +xdg-user-dirs-update >/dev/null 2>&1 || true + # 1. Output-Profile (gedockt/ungedockt). Schreibt die kanshi-Config nur, # wenn sie fehlt oder von kanshi-autoconfig verwaltet wird. # Eigene Hand-Edits bleiben unangetastet. diff --git a/scripts/kanshi-autoconfig b/scripts/kanshi-autoconfig index 7e5adc4..4a4f5b4 100755 --- a/scripts/kanshi-autoconfig +++ b/scripts/kanshi-autoconfig @@ -10,10 +10,18 @@ Verhalten: --print Vorschlag auf stdout, schreibt nichts. --apply Schreibt (mit Backup *.bak), fragt nicht. --apply-if-managed Schreibt nur, wenn die Config fehlt oder den Marker - '# kanshi-autoconfig: managed' enthaelt. - -> Hand-Edits bleiben unangetastet. Wird vom + '# kanshi-autoconfig: managed' enthaelt. Bei + unveraendertem Output-Set bleibt eine verwaltete Config + unangetastet (Modus-Tweaks inklusive). Wird vom labwc-Autostart bei jedem Login aufgerufen. +Moduswahl: Auf echter Hardware der EDID-preferred-Modus (meist nativ = +richtig). In VMs meldet die Firmware oft einen Kleinstmodus als preferred +(QEMU: 1280x800) - dort wird 1920x1080@60 genommen, wenn angeboten, sonst +preferred. Einmal geschrieben bleibt die Config bei gleichem Output-Set +erhalten (Modus-Tweaks inklusive); neu generiert wird nur bei geaendertem +Output-Set (Docking) oder per --apply. + Faellt die Erkennung fehl (kein Wayland, kein wlr-randr), wird eine reine Fallback-Config geschrieben, damit nie ein schwarzer Bildschirm ohne Layout dasteht. @@ -30,8 +38,39 @@ MARKER = "# kanshi-autoconfig: managed" CONFIG_PATH = Path.home() / ".config" / "kanshi" / "config" +def detect_vm(): + """True, wenn wir virtualisiert laufen (QEMU/Boxes-Test).""" + try: + proc = subprocess.run( + ["systemd-detect-virt", "--vm"], capture_output=True, timeout=10 + ) + except (FileNotFoundError, subprocess.TimeoutExpired): + return False + return proc.returncode == 0 + + +def norm_rate(value): + if isinstance(value, (int, float)) and value > 1000: + return value / 1000 # mHz -> Hz + return value + + +def choose_mode(modes, current, in_vm): + """Modus waehlen: VM-Heuristik, sonst preferred, sonst current/erster.""" + if in_vm: + for m in modes: + rate = norm_rate(m.get("refresh") or m.get("rate")) or 0 + if m.get("width") == 1920 and m.get("height") == 1080 and round(rate) == 60: + return m + for m in modes: + if m.get("preferred"): + return m + return current or (modes[0] if modes else None) + + def detect_outputs(): """Liste von Dicts: name, internal, width, height, rate, scale.""" + in_vm = detect_vm() try: proc = subprocess.run( ["wlr-randr", "--json"], capture_output=True, text=True, timeout=10 @@ -51,23 +90,17 @@ def detect_outputs(): if out.get("connected") is False: continue modes = out.get("modes", []) or [] - preferred = next((m for m in modes if m.get("preferred")), None) current = out.get("current_mode") or out.get("mode") - chosen = preferred or current or (modes[0] if modes else None) + chosen = choose_mode(modes, current, in_vm) if not chosen: continue - width = chosen.get("width") - height = chosen.get("height") - rate = chosen.get("refresh") or chosen.get("rate") - if isinstance(rate, (int, float)) and rate > 1000: - rate = rate / 1000 # mHz -> Hz outputs.append( { "name": name, "internal": name.startswith(("eDP-", "LVDS-", "DSI-")), - "width": width, - "height": height, - "rate": rate, + "width": chosen.get("width"), + "height": chosen.get("height"), + "rate": norm_rate(chosen.get("refresh") or chosen.get("rate")), "scale": out.get("scale", 1) or 1, } )