Maschinenraum

Die Rechner an Bord und selbstgebaute Werkzeuge.

Wie alles anfing

Mit meinem persönlichen ITler an meiner Seite und dem Wunsch, ein Game zu zocken, das es nicht für die Konsole gibt, entstand die Idee, einen eigenen Gaming-PC hochzuziehen. Wir machten uns auf die Suche und recherchierten nach geeigneten Komponenten. Viele Dinge davon wären bei mir untergegangen: Was muss das Motherboard können? Wie reagiert die CPU darauf, passt das zusammen? Was ist mit der GPU, verträgt die sich auch mit CPU und Motherboard? Welchen RAM braucht es? Auf welche Spezifikationen muss ich dabei achten? Wie viel Power braucht „der Gerät“ zum Schluss? Alles Dinge, die ich ohne ITler an meiner Seite nicht in Erwägung gezogen hätte. Und in Anbetracht der aktuellen PC-Lage haben wir keinen Deut zu spät damit begonnen, meinen PC zu konfigurieren.

Und dann: Welches OS soll drauf? Welches OS unterstützt das Zocken? Wo läuft Steam vernünftig? So viele Feinheiten, von denen ich keine Ahnung hatte, bis wir damit begonnen haben.

Übrigens: Das Spiel, um das es ging, habe ich immer noch nicht in meinem Besitz. Dafür unzählige andere ^.^, die so nie geplant waren :D

Schiffsregister

Die Rechner an Bord, eingetragen wie im Register der Sternenflotte.

  • Raumschiff der DG-Flotte

    flux

    Desktop

    RX 7600 XT 16 GB · 64 GB RAM · CachyOS + KDE

    Heimatwerft: Eigenbau – mein erster selbst gebauter PC

    Flaggschiff und Main

  • Raumschiff der DG-Flotte

    nx01

    Dell Latitude E5550

    Außeneinsätze

  • Raumschiff der DG-Flotte

    Defiant

    MacBook 2009

    Debian · 32-bit-EFI

    Heimatwerft: Utopia Planitia

    Aus Sentimentalität im Dienst

Eigenbau-Tools

Jetzt, knapp ein Jahr nach der Anschaffung, erkunde ich immer noch Linux mit Hilfe meiner hauseigenen IT und Claude. Ist die IT gerade nicht abkömmlich, muss Claude herhalten und so manches Mal meine stumpfen Nachfragen ertragen, weil ich wieder irgendwas nicht begriffen habe. Vor allem, wenn es um das Terminal (fish) geht: nach wie vor ein Buch mit sieben Siegeln für mich. Ohne Claude würde ich da nicht zwingend rangehen, oder es würde viel, viel länger dauern.

So ist es nun, dass ich mit Hilfe von Claude kleinere Skripte habe, die Dinge zum Laufen und Leuchten bringen. Die totale Schischiness!

  • newsboard

    Lokales Wetter- und News-Dashboard, alle 15 Minuten neu gebaut, ohne Konten und ohne API-Schlüssel.

    Fürs Kopieren zu groß, deshalb als Paket. Eigenen Ort, Wetter und Quellen in sources.ini eintragen, dann ./install.sh.

    newsboard.zip herunterladen ↓
  • Ripple

    Reaktiver Tastatur-Welleneffekt über OpenRGB, läuft als systemd-Dienst.

    ripple.py211 Zeilen

    Gebaut für die Turtle Beach Vulcan. Braucht OpenRGB mit eingeschaltetem SDK-Server sowie openrgb-python und evdev. Farben und Tempo stehen oben im Skript.

    #!/usr/bin/env python3
    """Ripple-FX fuer die Turtle Beach Vulcan ueber OpenRGB.
    
    Fassung 2.1 (2026-09-18)
    - Regenbogen: jeder Tastenanschlag erzeugt eine eigene Farbe
    - weichere, langsamere Welle
    - Workaround fuer KeyError: '' bei der Plugin-Abfrage (openrgb-python 0.3.6)
    - wartet beim Start auf den OpenRGB-SDK-Server und verbindet sich nach
      einem Absturz/Neustart von OpenRGB selbst neu (autostart-taugliche Fassung)
    """
    import colorsys
    import math
    import selectors
    import string
    import time
    
    from openrgb import OpenRGBClient
    from openrgb.utils import RGBColor
    from evdev import InputDevice, list_devices, ecodes
    
    # --- Workaround ---------------------------------------------------------
    # OpenRGB 1.0 meldet fuer eines der installierten Plugins einen leeren
    # Namen; openrgb-python 0.3.6 scheitert daran mit "KeyError: ''", noch
    # bevor man an die Geraete kommt. Die Plugin-Liste brauchen wir nicht,
    # also Abfrage stilllegen.
    try:
        from openrgb import orgb as _orgb
        _orgb.OpenRGBClient.update_plugins = lambda self: None
    except Exception:
        pass
    # -----------------------------------------------------------------------
    
    # ==== Zum Spielen: hier die Optik anpassen ====
    BASE     = (8, 0, 16)    # Ruhefarbe (dunkles Violett). (0,0,0) = aus
    RAINBOW  = True          # True = jede Taste eine andere Farbe
    RIPPLE   = (0, 200, 255) # Farbe des Tropfens, nur wenn RAINBOW = False
    SPEED    = 7.0           # Ausbreitungsgeschwindigkeit (Zellen/Sek.)
    WIDTH    = 1.0           # Dicke des Rings
    LIFETIME = 1.1           # Lebensdauer eines Tropfens (Sek.)
    FPS      = 60
    # ==== Verbindung / Autostart ====
    KEYBOARD  = "vulcan"     # Suchbegriff im Geraetenamen
    RETRY_SEC = 3.0          # Wartezeit zwischen Verbindungsversuchen
    # ==============================================
    
    HUE_STEP = 0.618033988749895  # goldener Schnitt -> gut unterscheidbare Farben
    
    
    def log(msg):
        print(msg, flush=True)
    
    
    # --- evdev-Taste -> OpenRGB-Tastenname ---
    EV = {}
    for ch in string.ascii_uppercase: EV[f"KEY_{ch}"] = ch
    for d in "1234567890":            EV[f"KEY_{d}"]  = d
    for n in range(1, 13):            EV[f"KEY_F{n}"] = f"F{n}"
    EV.update({
        "KEY_ESC":"Escape","KEY_GRAVE":"`","KEY_TAB":"Tab","KEY_CAPSLOCK":"Caps Lock",
        "KEY_LEFTSHIFT":"Left Shift","KEY_LEFTCTRL":"Left Control","KEY_LEFTMETA":"Left Windows",
        "KEY_LEFTALT":"Left Alt","KEY_SPACE":"Space","KEY_RIGHTALT":"Right Alt","KEY_COMPOSE":"Menu",
        "KEY_MINUS":"-","KEY_EQUAL":"=","KEY_LEFTBRACE":"[","KEY_RIGHTBRACE":"]","KEY_SEMICOLON":";",
        "KEY_APOSTROPHE":"'","KEY_COMMA":",","KEY_DOT":".","KEY_SLASH":"/","KEY_BACKSPACE":"Backspace",
        "KEY_ENTER":"Enter (ISO)","KEY_RIGHTSHIFT":"Right Shift","KEY_RIGHTCTRL":"Right Control",
        "KEY_102ND":"\\ (ISO)","KEY_BACKSLASH":"#","KEY_NUMLOCK":"Num Lock","KEY_INSERT":"Insert",
        "KEY_DELETE":"Delete","KEY_HOME":"Home","KEY_END":"End","KEY_PAGEUP":"Page Up",
        "KEY_PAGEDOWN":"Page Down","KEY_UP":"Up Arrow","KEY_DOWN":"Down Arrow","KEY_LEFT":"Left Arrow",
        "KEY_RIGHT":"Right Arrow","KEY_SYSRQ":"Print Screen","KEY_SCROLLLOCK":"Scroll Lock",
        "KEY_PAUSE":"Pause/Break","KEY_KP7":"Number Pad 7","KEY_KP8":"Number Pad 8","KEY_KP9":"Number Pad 9",
        "KEY_KP4":"Number Pad 4","KEY_KP5":"Number Pad 5","KEY_KP6":"Number Pad 6","KEY_KP1":"Number Pad 1",
        "KEY_KP2":"Number Pad 2","KEY_KP3":"Number Pad 3","KEY_KP0":"Number Pad 0","KEY_KPDOT":"Number Pad .",
        "KEY_KPSLASH":"Number Pad /","KEY_KPASTERISK":"Number Pad *","KEY_KPMINUS":"Number Pad -",
        "KEY_KPPLUS":"Number Pad +","KEY_KPENTER":"Number Pad Enter","KEY_PREVIOUSSONG":"Media Previous",
        "KEY_PLAYPAUSE":"Media Play/Pause","KEY_NEXTSONG":"Media Next",
    })
    
    
    def connect():
        """Wartet auf OpenRGB, schaltet in Direct-Mode und liefert die Rasterkarte."""
        while True:
            try:
                cli = OpenRGBClient(name="ripple")
                kb = next((d for d in cli.devices if KEYBOARD in d.name.lower()), None)
                if kb is None:
                    log("OpenRGB erreichbar, aber keine Vulcan im Geraetebaum - warte ...")
                else:
                    for m in kb.modes:
                        if m.name.lower() == "direct":
                            kb.set_mode(m)
                            break
                    zone = next(z for z in kb.zones if z.matrix_map)
                    pos = {}
                    for r, row in enumerate(zone.matrix_map):
                        for c, idx in enumerate(row):
                            if idx is not None:
                                pos[idx] = (r, c)
                    name_to_idx = {led.name.replace("Key: ", ""): i
                                   for i, led in enumerate(kb.leds)}
                    log(f"Verbunden mit '{kb.name}' ({len(kb.leds)} LEDs).")
                    return cli, kb, pos, name_to_idx
            except Exception as exc:
                log(f"Warte auf OpenRGB-SDK-Server ({type(exc).__name__}: {exc}) ...")
            time.sleep(RETRY_SEC)
    
    
    def open_inputs():
        """Liefert die lesbaren Tastatur-Eingabegeraete."""
        devs = []
        denied = False
        for path in list_devices():
            try:
                devs.append(InputDevice(path))
            except PermissionError:
                denied = True
        kbs = [d for d in devs if ecodes.EV_KEY in d.capabilities()
               and KEYBOARD in d.name.lower()]
        if not kbs:  # Fallback: irgendeine echte Tastatur
            kbs = [d for d in devs
                   if ecodes.KEY_A in d.capabilities().get(ecodes.EV_KEY, [])]
        if not kbs:
            if denied:
                raise SystemExit(
                    "Keine Tastatur lesbar - fehlt die Mitgliedschaft in der Gruppe 'input'?\n"
                    "  sudo usermod -aG input $USER   (danach ab-/anmelden)")
            raise SystemExit("Kein Tastatur-Eingabegeraet gefunden.")
        return kbs
    
    
    def main():
        cli, kb, pos, name_to_idx = connect()
        devs = open_inputs()
        log("Tastatur(en): " + ", ".join(d.name for d in devs))
    
        sel = selectors.DefaultSelector()
        for d in devs:
            sel.register(d, selectors.EVENT_READ)
    
        def resolve(code):
            names = ecodes.KEY.get(code)
            for n in (names if isinstance(names, list) else [names]):
                suf = EV.get(n)
                if suf in name_to_idx:
                    return name_to_idx[suf]
            return None
    
        n_leds = len(kb.leds)
        ripples = []          # [zeile, spalte, startzeit, (r,g,b)]
        hue = 0.0
        frame_dt = 1.0 / FPS
    
        def next_color():
            nonlocal hue
            if not RAINBOW:
                return RIPPLE
            hue = (hue + HUE_STEP) % 1.0
            r, g, b = colorsys.hsv_to_rgb(hue, 1.0, 1.0)
            return (r * 255.0, g * 255.0, b * 255.0)
    
        def render(now):
            cols = []
            for i in range(n_leds):
                r, c = pos.get(i, (None, None))
                cr, cg, cb = BASE
                if r is not None:
                    for orow, ocol, t0, col in ripples:
                        age = now - t0
                        d = math.hypot(r - orow, c - ocol) - age * SPEED
                        a = math.exp(-(d * d) / (2 * WIDTH * WIDTH)) * max(0.0, 1 - age / LIFETIME)
                        cr += col[0] * a; cg += col[1] * a; cb += col[2] * a
                cols.append(RGBColor(min(255, int(cr)), min(255, int(cg)), min(255, int(cb))))
            kb.set_colors(cols, fast=True)
    
        log("Ripple laeuft - tippen zum Testen, Strg+C zum Beenden.")
        render(time.time())
        prev_active = False
        while True:
            for key, _ in sel.select(timeout=frame_dt):
                try:
                    for ev in key.fileobj.read():
                        if ev.type == ecodes.EV_KEY and ev.value == 1:
                            led = resolve(ev.code)
                            if led in pos:
                                ripples.append([pos[led][0], pos[led][1],
                                                time.time(), next_color()])
                except (BlockingIOError, OSError):
                    pass
            now = time.time()
            ripples[:] = [rp for rp in ripples if now - rp[2] < LIFETIME]
            active = bool(ripples)
            if active or prev_active:
                try:
                    render(now)
                except Exception as exc:
                    # OpenRGB weg (beendet/neu gestartet) -> neu verbinden
                    log(f"Verbindung zu OpenRGB verloren ({type(exc).__name__}) - verbinde neu ...")
                    try:
                        cli.disconnect()
                    except Exception:
                        pass
                    time.sleep(RETRY_SEC)
                    cli, kb, pos, name_to_idx = connect()
                    n_leds = len(kb.leds)
                    ripples.clear()
            prev_active = active
    
    
    if __name__ == "__main__":
        try:
            main()
        except KeyboardInterrupt:
            log("\nBeendet.")
    ripple.service14 Zeilen

    Als Benutzerdienst nach ~/.config/systemd/user/ legen, dann: systemctl --user enable --now ripple

    [Unit]
    Description=Ripple-Tastatureffekt (OpenRGB / Turtle Beach Vulcan)
    After=graphical-session.target
    
    [Service]
    Type=simple
    # Pfad anpassen: dorthin, wo ripple.py bei dir liegt (%h = dein Home-Ordner)
    ExecStart=/usr/bin/python3 -u %h/.local/bin/ripple.py
    Restart=always
    RestartSec=5
    Nice=5
    
    [Install]
    WantedBy=default.target
    ripple_discover.py37 Zeilen

    Helfer für andere Tastaturen: zeigt Geräte, Zonen und LED-Namen, die OpenRGB kennt.

    #!/usr/bin/env python3
    from openrgb import OpenRGBClient
    from openrgb.utils import DeviceType
    
    cli = OpenRGBClient(name="ripple-discover")
    
    print("== Alle Geräte ==")
    for i, d in enumerate(cli.devices):
        print(f"  [{i}] {d.name}  ({len(d.leds)} LEDs)")
    
    kb = None
    for d in cli.devices:
        if "vulcan" in d.name.lower():
            kb = d
            break
    if kb is None:
        kbs = cli.get_devices_by_type(DeviceType.KEYBOARD)
        kb = kbs[0] if kbs else None
    
    if kb is None:
        print("\n!! Keine Tastatur gefunden.")
        raise SystemExit
    
    print(f"\n== Tastatur: {kb.name} ({len(kb.leds)} LEDs) ==")
    
    print("\n-- Zonen & Matrix --")
    for z in kb.zones:
        print(f"Zone '{z.name}'  type={z.type.name}  mat={z.mat_width}x{z.mat_height}")
        if z.matrix_map:
            for row in z.matrix_map:
                print("   ", row)
        else:
            print("    (keine Matrix-Karte)")
    
    print("\n-- LED-Namen --")
    for i, led in enumerate(kb.leds):
        print(f"{i:3d}: {led.name}")
  • Noctalia-Dashboard

    Der Caelestia-Look unter KDE Plasma.

    noctalia-plasma-setup.sh209 Zeilen

    Einrichtungsskript für CachyOS/Arch. Mit --lite als Sparvariante für schwache Grafik.

    #!/usr/bin/env bash
    #
    # noctalia-plasma-setup.sh
    # Setzt eine Quickshell-artige Desktop-Shell (Noctalia) neben KDE Plasma 6 / KWin Wayland auf,
    # als KWin-taugliche Annaeherung an den Caelestia-Look (Hyprland).
    #
    # Fassung 1.1 - 2026-09-04
    # Aenderung ggue. 1.0: pipewire / pipewire-pulse aus REPO_PKGS entfernt.
    #   Grund: auf CachyOS ist das ein CachyOS-eigener Build (z.B. 1:1.6.8-1.2),
    #   den gst-plugin-pipewire fest voraussetzt. Die Standard-[extra]-Version
    #   (z.B. 1:1.6.8-1) ist aelter -> pacman verweigert den Downgrade-Konflikt.
    #   Beide Pakete sind auf einem laufenden Plasma/CachyOS-System ohnehin
    #   schon vorhanden, Noctalia braucht sie nicht neu installiert.
    # Zielsysteme: CachyOS / Arch (flux = full, nx01 = lite)
    #
    # Das Skript installiert NUR. Es aendert von sich aus KEINE Plasma-Konfiguration,
    # entfernt keine Panels und aktiviert keinen Autostart, solange du es nicht sagst.
    
    set -euo pipefail
    
    MODE="full"
    DO_AUTOSTART=0
    DRY_RUN=0
    
    usage() {
        cat <<'USAGE'
    Verwendung: ./noctalia-plasma-setup.sh [OPTIONEN]
    
      --lite         Sparvariante fuer schwache GPUs (nx01): kein cava/Visualizer,
                     keine Blur-Extras, keine schweren Schriftpakete.
      --autostart    Legt zusaetzlich einen Autostart-Eintrag an (~/.config/autostart).
                     Standard: aus. Erst manuell testen, dann aktivieren.
      --dry-run      Zeigt nur, was passieren wuerde.
      -h, --help     Diese Hilfe.
    USAGE
    }
    
    while [[ $# -gt 0 ]]; do
        case "$1" in
            --lite)      MODE="lite"; shift ;;
            --autostart) DO_AUTOSTART=1; shift ;;
            --dry-run)   DRY_RUN=1; shift ;;
            -h|--help)   usage; exit 0 ;;
            *) echo "Unbekannte Option: $1" >&2; usage; exit 1 ;;
        esac
    done
    
    say()  { printf '\n\033[1;35m==>\033[0m %s\n' "$*"; }
    warn() { printf '\033[1;33m[!]\033[0m %s\n' "$*" >&2; }
    die()  { printf '\033[1;31m[x]\033[0m %s\n' "$*" >&2; exit 1; }
    
    run() {
        if [[ $DRY_RUN -eq 1 ]]; then
            printf '    (dry-run) %s\n' "$*"
        else
            "$@"
        fi
    }
    
    # ---------------------------------------------------------------- Vorpruefung
    
    say "Vorpruefung"
    
    command -v pacman >/dev/null 2>&1 || die "Kein pacman gefunden. Das Skript ist fuer Arch/CachyOS."
    
    if [[ $EUID -eq 0 ]]; then
        die "Bitte NICHT als root starten. Das Skript ruft sudo selbst auf, wo noetig."
    fi
    
    PLASMA_VER="$(plasmashell --version 2>/dev/null | awk '{print $NF}' || true)"
    if [[ -z "$PLASMA_VER" ]]; then
        warn "plasmashell nicht gefunden - laeuft hier wirklich Plasma?"
    else
        echo "    Plasma: $PLASMA_VER"
        case "$PLASMA_VER" in
            6.*) ;;
            *) warn "Noctalia braucht Plasma 6. Gefunden: $PLASMA_VER" ;;
        esac
    fi
    
    if [[ "${XDG_SESSION_TYPE:-}" != "wayland" ]]; then
        warn "Aktuelle Session ist '${XDG_SESSION_TYPE:-unbekannt}', nicht wayland."
        warn "Die Shell braucht wlr-layer-shell und laeuft nur unter Plasma (Wayland)."
        warn "Installieren geht trotzdem - vor dem Start in die Wayland-Session wechseln."
    fi
    
    echo "    Modus: $MODE"
    
    # ------------------------------------------------------------- AUR-Helfer
    
    AUR=""
    for h in paru yay; do
        if command -v "$h" >/dev/null 2>&1; then AUR="$h"; break; fi
    done
    [[ -n "$AUR" ]] || die "Kein AUR-Helfer (paru/yay) gefunden. CachyOS hat normalerweise paru:  sudo pacman -S paru"
    echo "    AUR-Helfer: $AUR"
    
    # ------------------------------------------------------- Pakete aus den Repos
    
    say "Repo-Pakete installieren"
    
    # quickshell liegt seit 0.3.x in [extra] - kein AUR noetig.
    # pipewire/pipewire-pulse bewusst NICHT hier drin (siehe Kommentar im Kopf).
    REPO_PKGS=(
        quickshell
        networkmanager
        upower
        brightnessctl
        wl-clipboard
        qt6-tools
        python
    )
    
    if [[ "$MODE" == "full" ]]; then
        REPO_PKGS+=( cava ddcutil libqalculate inter-font ttf-jetbrains-mono-nerd )
    fi
    
    run sudo pacman -S --needed --noconfirm "${REPO_PKGS[@]}"
    
    # -------------------------------------------------------------- Noctalia (AUR)
    
    say "Noctalia aus dem AUR installieren (noctalia-git, upstream-gepflegt)"
    run "$AUR" -S --needed --noconfirm noctalia-git
    
    # ---------------------------------------------------- Binary ermitteln, nicht raten
    
    say "Startbefehl ermitteln"
    NOCTALIA_BIN=""
    if [[ $DRY_RUN -eq 0 ]]; then
        while IFS= read -r p; do
            [[ -x "$p" ]] && { NOCTALIA_BIN="$p"; break; }
        done < <(pacman -Qlq noctalia-git 2>/dev/null | grep -E '^/usr/bin/' || true)
    fi
    
    if [[ -z "$NOCTALIA_BIN" && $DRY_RUN -eq 0 ]]; then
        warn "Konnte den Startbefehl nicht automatisch finden."
        warn "Selbst nachsehen:  pacman -Qlq noctalia-git | grep /usr/bin/"
        NOCTALIA_BIN="noctalia-shell"   # Rueckfallname, bitte pruefen
    else
        echo "    Startbefehl: ${NOCTALIA_BIN:-<dry-run>}"
    fi
    
    # ------------------------------------------------------------------ Autostart
    
    if [[ $DO_AUTOSTART -eq 1 ]]; then
        say "Autostart-Eintrag anlegen"
        AUTOSTART_DIR="$HOME/.config/autostart"
        run mkdir -p "$AUTOSTART_DIR"
        if [[ $DRY_RUN -eq 0 ]]; then
            cat > "$AUTOSTART_DIR/noctalia.desktop" <<DESKTOP
    [Desktop Entry]
    Type=Application
    Name=Noctalia Shell
    Comment=Quickshell-Shell neben Plasma (Caelestia-Annaeherung)
    Exec=$NOCTALIA_BIN
    X-KDE-autostart-phase=2
    X-GNOME-Autostart-enabled=true
    DESKTOP
            echo "    geschrieben: $AUTOSTART_DIR/noctalia.desktop"
        else
            printf '    (dry-run) schreibe %s/noctalia.desktop\n' "$AUTOSTART_DIR"
        fi
    else
        say "Autostart uebersprungen (kein --autostart)"
    fi
    
    # --------------------------------------------------------------------- Ausgabe
    
    say "Fertig. Naechste Schritte von Hand:"
    cat <<NEXT
    
      1) TESTEN, bevor irgendetwas dauerhaft wird:
            $NOCTALIA_BIN
         In einem Terminal starten, anschauen, mit Strg+C wieder beenden.
    
      2) Plasma-Panel loswerden (reversibel, KEIN plasmashell killen):
            Rechtsklick aufs Panel -> "Kontrollleiste anzeigen" -> "Kontrollleiste entfernen"
         Zurueck: Rechtsklick auf den Desktop -> "Kontrollleiste hinzufuegen" -> "Standard-Kontrollleiste"
    
      3) Farben: Noctalia erzeugt das Farbschema aus dem Wallpaper (Material Design 3).
         Genau daher kommt der Pastell-Ton im Caelestia-Video - nicht aus einem festen Theme.
         Also: erst Wallpaper setzen, dann Palette generieren lassen.
            Generator "tonal-spot" oder "soft" kommt dem Video am naechsten.
    
      4) Was Plasma weiter uebernimmt (unter KWin fehlen die noetigen wlroots-Protokolle):
            Screenshots      -> Spectacle
            Zwischenablage   -> Klipper
            Nachtfarben      -> Systemeinstellungen
            Sperrbildschirm  -> Plasma-Sperrbildschirm
    
      5) Rueckbau komplett:
            rm -f ~/.config/autostart/noctalia.desktop
            $AUR -Rns noctalia-git
            Plasma-Panel wie unter 2) wieder hinzufuegen
    
    NEXT
    
    if [[ "$MODE" == "lite" ]]; then
        cat <<'LITE'
      nx01-Hinweise (Broadwell-iGPU):
        - In den Systemeinstellungen -> Fensterverhalten -> Arbeitsflaecheneffekte:
          "Weichzeichnen" und "Hintergrundkontrast" AUS.
        - Systemeinstellungen -> Barrierefreiheit bzw. Animationsgeschwindigkeit:
          Animationen auf "Sofort" oder stark verkuerzt.
        - In Noctalia: Visualizer/cava aus, Desktop-Widgets sparsam,
          Wallpaper statisch (kein Video/Slideshow), Blur in der Shell reduzieren.
    
    LITE
    fi
  • LCD-Display

    Die kleine Thermalright-Anzeige unter Linux zum Leben erweckt. Eher exotisch: Für Linux gibt es keine Herstellersoftware, es läuft über ein Community-Tool.

Datenschutz