xdg-user-dirs im Autostart, kanshi VM-Moduswahl

This commit is contained in:
humocs-man
2026-09-27 20:04:00 +02:00
parent 2e7ea3e5b5
commit 2afe810d73
2 changed files with 51 additions and 12 deletions
+6
View File
@@ -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.
+45 -12
View File
@@ -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,
}
)