mirror of
https://github.com/theupriser/steamify-cachyos.git
synced 2026-10-03 17:41:58 +02:00
Merge pull request #1 from theupriser/fix/review-cleanup
fix: Fix setup bugs, add SteamOS desktop look and LED driver, split i…
This commit is contained in:
11 files changed
+1148
-732
No files matched your search
@@ -0,0 +1,97 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
Guidance for AI coding agents working on this repository. See `README.md`
|
||||||
|
for what the script does from a user's point of view.
|
||||||
|
|
||||||
|
## Project overview
|
||||||
|
|
||||||
|
A bash wizard that makes CachyOS (KDE Plasma 6 + `plasma-login-manager`)
|
||||||
|
boot into a SteamOS-style gamescope session, with working switching between
|
||||||
|
gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
|
||||||
|
(DMI `Valve`/`Fremont`) running CachyOS Desktop edition.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
- `setup-gamescope-boot.sh` - the only entry point. Pre-flight checks,
|
||||||
|
sources `lib/*.sh`, then calls the steps in order. No step logic here.
|
||||||
|
- `lib/*.sh` - one file per responsibility, each defining functions only
|
||||||
|
(no top-level side effects). See the table in `README.md`. New
|
||||||
|
functionality goes in the module it belongs to, or a new module that is
|
||||||
|
added to the `source` loop in `setup-gamescope-boot.sh`.
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Bash, `set -uo pipefail` (no `-e`): check exit codes of steps that matter
|
||||||
|
explicitly (`|| { err ...; exit 1; }` or `|| return 1`).
|
||||||
|
- Use the helpers from `lib/common.sh` (`info`, `ok`, `warn`, `err`,
|
||||||
|
`ask_yn`, `backup_file`) for all output and prompts.
|
||||||
|
- Runs as the normal user; use `sudo` per command, never require root.
|
||||||
|
Per-user files go in `$HOME` of the invoking user (the script refuses to
|
||||||
|
configure another user).
|
||||||
|
- **Idempotent**: every step must be safe to re-run without duplicating
|
||||||
|
lines or settings. Back up system files with `backup_file` before the
|
||||||
|
first edit.
|
||||||
|
- Don't overwrite package-owned files in `/etc/xdg` or `/usr`. KDE settings
|
||||||
|
go into the user's config via `kwriteconfig6` (or `merge_kde_config` for
|
||||||
|
whole Valve ini files).
|
||||||
|
- Package installs after a user already confirmed use `--noconfirm`: a
|
||||||
|
second pacman prompt consumes the next scripted answer.
|
||||||
|
- Comments explain *why* (the CachyOS/Plasma quirk being worked around),
|
||||||
|
not what the next line does.
|
||||||
|
|
||||||
|
## Non-obvious behaviour to preserve
|
||||||
|
|
||||||
|
- `steam-set-session` only writes `/etc/plasmalogin.conf.d/zz-steamos-autologin.conf`;
|
||||||
|
the base `/etc/plasmalogin.conf` wins, hence the sync bridge. The sync
|
||||||
|
service needs `StartLimitIntervalSec=0`, or bursts of session switches
|
||||||
|
get it rate-limited and all later switches silently stop working.
|
||||||
|
- The sync script must only edit `Session=` inside `[Autologin]`.
|
||||||
|
- The Steam desktop autostart unit is guarded with
|
||||||
|
`ExecCondition=... XDG_CURRENT_DESKTOP = KDE`, so it doesn't start a
|
||||||
|
second Steam inside gamescope.
|
||||||
|
- Vapor theme: install Valve's files as shipped. Don't rewrite Valve's
|
||||||
|
`metadata.json`; the icon theme is `breeze-dark` (there is no "Vapor"
|
||||||
|
icon theme); wallpapers are flat JPGs in `usr/share/wallpapers`.
|
||||||
|
`lookandfeeltool` does not switch the color scheme, so
|
||||||
|
`plasma-apply-colorscheme Vapor` is applied explicitly.
|
||||||
|
- Plasma 6 has no separate systemtray containment: tray settings live on
|
||||||
|
the systemtray applet itself (Valve's setup script targets Plasma 5).
|
||||||
|
- Restart plasmashell via `systemctl --user` (`plasma-plasmashell.service`),
|
||||||
|
not `plasmashell --replace` from the script's shell: a shell without the
|
||||||
|
session environment yields a light-themed desktop (context menus, apps it
|
||||||
|
launches).
|
||||||
|
- Live Plasma changes (`qdbus6 ... evaluateScript`, `lookandfeeltool`) only
|
||||||
|
run when `plasmashell` is running; config-file fallbacks cover the rest.
|
||||||
|
- LED driver: `leds-valve-dkms-git`'s Makefile builds against `uname -r`,
|
||||||
|
so the script builds explicitly for the running kernel and installs
|
||||||
|
headers for every installed kernel first. The module creates
|
||||||
|
`/sys/class/leds/valve-leds*`.
|
||||||
|
- `Relogin=true` means a gamescope that fails to start is relaunched in a
|
||||||
|
tight loop; keep that in mind when changing session handling.
|
||||||
|
|
||||||
|
## Checking changes
|
||||||
|
|
||||||
|
There is no test suite. At minimum:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
for f in setup-gamescope-boot.sh lib/*.sh; do bash -n "$f"; done
|
||||||
|
shellcheck -S warning setup-gamescope-boot.sh lib/*.sh # if available
|
||||||
|
```
|
||||||
|
|
||||||
|
Behaviour is best verified in a CachyOS VM (QEMU/KVM, KDE Plasma install,
|
||||||
|
`plasma-login-manager`) with SSH access, reset from a disk snapshot between
|
||||||
|
runs. Notes from doing this:
|
||||||
|
|
||||||
|
- Run the script non-interactively by piping answers, e.g.
|
||||||
|
`printf "\ny\nn\n" | ./setup-gamescope-boot.sh` (user, theme, reboot).
|
||||||
|
The prompt order depends on what's already installed.
|
||||||
|
- Over SSH, export the session environment before running it so the live
|
||||||
|
Plasma steps work:
|
||||||
|
`XDG_RUNTIME_DIR=/run/user/$UID WAYLAND_DISPLAY=wayland-0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$UID/bus`.
|
||||||
|
- `spectacle -b -n -f -o shot.png` takes a screenshot to check the look.
|
||||||
|
Apps you launch over SSH lack the session's Qt platform theme and look
|
||||||
|
light; launch them with `systemd-run --user` to judge colors correctly.
|
||||||
|
- Gamescope usually won't render in a VM (no suitable Vulkan), so test the
|
||||||
|
session logic with `plasma.desktop` as the autologin session. The
|
||||||
|
gamescope boot itself and the LED driver can only be verified on real
|
||||||
|
hardware.
|
||||||
@@ -1,172 +1,273 @@
|
|||||||
# CachyOS Gamescope Boot Wizard
|
# CachyOS Gamescope Boot Wizard
|
||||||
|
|
||||||
A setup script that makes a CachyOS desktop install (running KDE Plasma +
|
Turn a CachyOS desktop PC into a SteamOS-style console: it boots straight
|
||||||
`plasma-login-manager`) always boot into a **Steam Deck-style gamescope
|
into Steam's Big Picture (gamescope), and you can switch to the KDE Plasma
|
||||||
session** - the same "always boots into Big Picture, switch to desktop and
|
desktop and back whenever you like - just like on a Steam Deck or Valve's
|
||||||
back on demand" experience SteamOS gives you on a real Deck or the Valve
|
|
||||||
Steam Machine.
|
Steam Machine.
|
||||||
|
|
||||||
It exists because, as of the CachyOS March 2026 release (which switched the
|
Out of the box, CachyOS doesn't quite manage this: the switch to the desktop
|
||||||
default login manager from SDDM to `plasma-login-manager`), the stock
|
can hang, and the PC doesn't reliably boot back into gaming mode. This
|
||||||
`gamescope-session-cachyos` tooling has a few gaps that stop this from
|
script fixes that and sets everything up for you.
|
||||||
working out of the box. This script patches around them.
|
|
||||||
|
|
||||||
## What's actually broken (and what this fixes)
|
## What you get
|
||||||
|
|
||||||
CachyOS's `gamescope-session-cachyos` package ships `steamos-session-select`,
|
- **Boots into gaming mode** automatically, without a login screen.
|
||||||
which is meant to work exactly like it does on real SteamOS. On a
|
- **Switch to Desktop** from Steam's power menu works, and so does going
|
||||||
`plasma-login-manager` system, three things get in the way:
|
back: use the **Return to Gaming Mode** icon on the desktop, or just log
|
||||||
|
out.
|
||||||
1. **No `User=` written to the autologin config.**
|
- **Back to gaming mode after a restart**, like SteamOS.
|
||||||
`steam-set-session` (the script `steamos-session-select` calls under the
|
- **Steam's on-screen keyboard** (Steam + X) also works on the desktop.
|
||||||
hood) only ever writes a `Session=` key to the autologin config file. On
|
- *Optional:* the **SteamOS desktop look** - Valve's own Vapor theme,
|
||||||
SDDM this is fine, because SDDM's `User=` is set once by the installer and
|
wallpaper, dark mode and taskbar.
|
||||||
never touched again. `plasma-login-manager` needs *both* `Session=` and
|
- *Optional, Steam Machine only:* a driver for the **front LED bar**.
|
||||||
`User=` present to autologin at all - without `User=`, it just falls back
|
|
||||||
to showing the greeter every boot.
|
|
||||||
|
|
||||||
2. **Missing `/etc/plasmalogin.conf.d` directory.**
|
|
||||||
If that directory doesn't exist, `steam-set-session` fails outright when
|
|
||||||
it tries to write to it. In practice this shows up as Steam's **"Switch to
|
|
||||||
Desktop"** hanging forever on a "Switching to Desktop" message with no way
|
|
||||||
back except a hard reset.
|
|
||||||
|
|
||||||
3. **The base `/etc/plasmalogin.conf` wins over conf.d, and CachyOS ships it
|
|
||||||
hardcoded to `Session=plasma`.**
|
|
||||||
Every CachyOS tool that changes sessions (`steamos-session-select`, Steam's
|
|
||||||
power menu, and the `cachyos-gamescope-autologin.service` that's supposed
|
|
||||||
to reset you back to gamescope after a desktop session) only ever writes
|
|
||||||
to `/etc/plasmalogin.conf.d/zz-steamos-autologin.conf`. But the *base*
|
|
||||||
`/etc/plasmalogin.conf` file takes priority over that fragment, and it
|
|
||||||
ships with `Session=plasma` baked in - so none of those session switches
|
|
||||||
ever actually stick, no matter what the fragment says.
|
|
||||||
|
|
||||||
This script fixes all three: it ensures the conf.d directory exists, sets the
|
|
||||||
base config's `Session=`, `User=`, and `Relogin=true` correctly, and installs
|
|
||||||
a small `systemd` path-watcher that keeps the base config in sync with
|
|
||||||
whatever CachyOS's own tools write to the conf.d fragment - so switching
|
|
||||||
sessions from inside Steam or the desktop actually works, in both
|
|
||||||
directions, and resets to gamescope on the next boot by default (matching
|
|
||||||
real Deck/SteamOS behavior).
|
|
||||||
|
|
||||||
It also optionally offers to install Valve's official **Vapor** KDE Plasma
|
|
||||||
theme - the same colors, icons, wallpapers, and Plasma look-and-feel package
|
|
||||||
used on real SteamOS - pulled directly from Valve's own SteamOS package
|
|
||||||
mirror, so your desktop session matches the gamescope side visually.
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- CachyOS (or an Arch-based system) with `pacman`
|
- CachyOS with the KDE Plasma desktop (the default CachyOS Desktop edition)
|
||||||
- KDE Plasma installed
|
- Your normal user account, with permission to use `sudo`
|
||||||
- `plasma-login-manager` as the active display manager
|
|
||||||
*(the script will warn and ask for confirmation if it detects SDDM or
|
|
||||||
something else instead - most of these workarounds are specific to
|
|
||||||
`plasma-login-manager`)*
|
|
||||||
- A regular user account with `sudo` access
|
|
||||||
|
|
||||||
## Usage
|
## Installation
|
||||||
|
|
||||||
|
Open **Konsole** on your Plasma desktop and run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone <this-repo-url>
|
git clone <this-repo-url>
|
||||||
cd <this-repo>
|
cd <this-repo>
|
||||||
chmod +x setup-gamescope-boot.sh
|
|
||||||
./setup-gamescope-boot.sh
|
./setup-gamescope-boot.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Run it as your normal user, **not** as root - it calls `sudo` internally for
|
Run it as yourself, not as root. It asks for your password once, then asks a
|
||||||
the specific commands that need it.
|
few yes/no questions (whether to install missing packages, the SteamOS look,
|
||||||
|
and the LED driver on a Steam Machine). At the end it offers to restart.
|
||||||
|
|
||||||
The script will:
|
Keep the whole folder: the script needs the files in `lib/` next to it.
|
||||||
|
|
||||||
1. Ask which user account should autologin into gamescope (defaults to
|
It's safe to run again later, for example after a CachyOS update.
|
||||||
whoever's running the script).
|
|
||||||
2. Check for and offer to install `gamescope-session-cachyos`, `steam`, and
|
|
||||||
`mangohud` if any are missing.
|
|
||||||
3. Create `/etc/plasmalogin.conf.d` if it doesn't exist.
|
|
||||||
4. Back up and rewrite `/etc/plasmalogin.conf`'s `[Autologin]` section.
|
|
||||||
5. Remove any stray manual override files from earlier troubleshooting
|
|
||||||
attempts (only files matching `zzz-steamos-autologin*.conf` - it never
|
|
||||||
touches `zz-steamos-autologin.conf`, which CachyOS's own tools own).
|
|
||||||
6. Install a sync script (`/usr/local/bin/sync-steamos-session.sh`) and a
|
|
||||||
`systemd` path unit that keeps the base config aligned with session
|
|
||||||
switches made through Steam or `steamos-session-select`.
|
|
||||||
7. Ask whether you'd also like to install Valve's **Vapor** (Steam Deck) KDE
|
|
||||||
theme. If you say yes, it downloads the official `steamdeck-kde-presets`
|
|
||||||
package straight from Valve's SteamOS mirror and installs the color
|
|
||||||
scheme, Plasma look-and-feel package, wallpapers, and icons into your
|
|
||||||
user's `~/.local/share`. This step only touches your home directory -
|
|
||||||
nothing system-wide - and installing `curl`/`zstd` first if either is
|
|
||||||
missing. Apply it afterwards from **System Settings > Appearance >
|
|
||||||
Global Theme > Vapor (Steam Deck)** the next time you're in a Plasma
|
|
||||||
session.
|
|
||||||
|
|
||||||
If you keep a folder named `icons/` next to the script (e.g. custom Steam
|
## Using it
|
||||||
Deck logo assets), it'll also copy those into the right Plasma icon
|
|
||||||
directories automatically. This is entirely optional - the theme installs
|
|
||||||
fine without it.
|
|
||||||
8. Ask whether to reboot immediately to test the gamescope setup.
|
|
||||||
|
|
||||||
It's **safe to re-run** - every step checks current state first, and any
|
- **To the desktop:** in gaming mode, open the Steam menu and choose
|
||||||
file it modifies gets backed up once with a `.bak-gamescope-wizard` suffix
|
**Power > Switch to Desktop**.
|
||||||
before the first change.
|
- **Back to gaming mode:** double-click **Return to Gaming Mode** on the
|
||||||
|
desktop, or log out.
|
||||||
|
- After a restart you always start in gaming mode.
|
||||||
|
|
||||||
## After running it
|
Prefer to decide yourself where your PC starts? Run one of these in Konsole:
|
||||||
|
|
||||||
Boot straight into gamescope: it should happen automatically. From inside
|
```bash
|
||||||
gamescope, Steam's **Power > Switch to Desktop** should now work. From the
|
steamos-session-select persistent # start where you left off last time
|
||||||
desktop, logging out should drop you back into gamescope automatically
|
steamos-session-select oneshot # always start in gaming mode (default)
|
||||||
(thanks to CachyOS's own `cachyos-gamescope-autologin.service`, which this
|
```
|
||||||
script doesn't replace - it just makes sure the setting it writes actually
|
|
||||||
takes effect).
|
|
||||||
|
|
||||||
You can also switch sessions manually at any time:
|
## If something goes wrong
|
||||||
|
|
||||||
|
**Gaming mode shows a black screen or keeps restarting.** Press
|
||||||
|
**Ctrl+Alt+F3**, log in with your username and password, and run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
steamos-session-select plasma && sudo systemctl restart plasmalogin
|
||||||
|
```
|
||||||
|
|
||||||
|
That takes you back to the desktop.
|
||||||
|
|
||||||
|
**The LED bar on the Steam Machine stays dark.** Restart the PC once more; a
|
||||||
|
freshly installed driver often needs a reboot. Still dark? See
|
||||||
|
[Front LED bar](#front-led-bar-steam-machine) under technical details.
|
||||||
|
|
||||||
|
**Undo the SteamOS look:** pick another theme under **System Settings >
|
||||||
|
Colors & Themes > Global Theme**.
|
||||||
|
|
||||||
|
To remove everything the script set up, see
|
||||||
|
[Removing everything](#removing-everything).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Technical details
|
||||||
|
|
||||||
|
### Why this is needed
|
||||||
|
|
||||||
|
CachyOS's `gamescope-session-cachyos` package ships `steamos-session-select`,
|
||||||
|
which is meant to work exactly like it does on real SteamOS. Since the March
|
||||||
|
2026 release, CachyOS uses `plasma-login-manager` instead of SDDM, and three
|
||||||
|
things get in the way:
|
||||||
|
|
||||||
|
1. **No `User=` written to the autologin config.**
|
||||||
|
`steam-set-session` (called by `steamos-session-select`) only writes a
|
||||||
|
`Session=` key. `plasma-login-manager` needs both `Session=` and `User=`
|
||||||
|
to autologin at all; without `User=` it shows the greeter every boot.
|
||||||
|
|
||||||
|
2. **Missing `/etc/plasmalogin.conf.d` directory.**
|
||||||
|
Without it, `steam-set-session` fails, and Steam's "Switch to Desktop"
|
||||||
|
hangs forever. *(Fixed upstream in `gamescope-session-cachyos` 1.1.6; the
|
||||||
|
script still creates the directory for older versions.)*
|
||||||
|
|
||||||
|
3. **The base `/etc/plasmalogin.conf` wins over conf.d, and CachyOS ships it
|
||||||
|
with `Session=plasma`.**
|
||||||
|
Every tool that changes sessions (`steamos-session-select`, Steam's power
|
||||||
|
menu, and `cachyos-gamescope-autologin.service`, which resets you to
|
||||||
|
gamescope after a desktop session) only writes
|
||||||
|
`/etc/plasmalogin.conf.d/zz-steamos-autologin.conf`. The base file takes
|
||||||
|
priority, so none of those switches stick.
|
||||||
|
|
||||||
|
The script sets `Session=`, `User=` and `Relogin=true` in the base config,
|
||||||
|
and installs a small systemd path watcher that copies whatever CachyOS's
|
||||||
|
tools write to the conf.d fragment into the base config.
|
||||||
|
|
||||||
|
### What the script changes
|
||||||
|
|
||||||
|
In order:
|
||||||
|
|
||||||
|
1. Checks the display manager (warns if it isn't `plasma-login-manager`) and
|
||||||
|
that it runs as the user that should autologin.
|
||||||
|
2. Installs missing packages: `gamescope-session-cachyos`, `steam`,
|
||||||
|
`mangohud`, `xterm`, `ttf-liberation`, `wqy-zenhei`, `plasma-keyboard`.
|
||||||
|
3. Creates `/etc/plasmalogin.conf.d`, backs up and rewrites the
|
||||||
|
`[Autologin]` section of `/etc/plasmalogin.conf`, and removes stray
|
||||||
|
`zzz-steamos-autologin*.conf` files from manual troubleshooting (never
|
||||||
|
`zz-steamos-autologin.conf`, which CachyOS's tools own).
|
||||||
|
4. Installs `/usr/local/bin/sync-steamos-session.sh` plus
|
||||||
|
`sync-steamos-session.path`/`.service`, which keep the base config in sync
|
||||||
|
with session switches.
|
||||||
|
5. Sets up Steam for the desktop: `STEAM_GAMEPADUI_ARGS="-gamepadui -steamos3"`
|
||||||
|
(gamepad UI with Steam Deck glyphs), `KWIN_IM_SHOW_ALWAYS=1` for the
|
||||||
|
virtual keyboard, and a `steam-desktop-autostart` systemd user service
|
||||||
|
that starts Steam silently in Plasma only.
|
||||||
|
6. *(Steam Machine, optional)* the LED driver - see below.
|
||||||
|
7. *(Optional)* the SteamOS desktop look - see below.
|
||||||
|
8. Creates the **Return to Gaming Mode** shortcut, with a narrow sudoers rule
|
||||||
|
(`/etc/sudoers.d/gamescope-session-switch`) so it can restart the login
|
||||||
|
manager without a password prompt.
|
||||||
|
|
||||||
|
Re-running doesn't duplicate any settings. Every system file it modifies is
|
||||||
|
backed up once, next to the original, with a `.bak-gamescope-wizard` suffix.
|
||||||
|
|
||||||
|
### SteamOS desktop look
|
||||||
|
|
||||||
|
Downloads Valve's official `steamdeck-kde-presets` package from Valve's
|
||||||
|
SteamOS mirror and installs it into `~/.local/share` - nothing system-wide:
|
||||||
|
|
||||||
|
- the Vapor global theme, color scheme, Plasma style, wallpapers and icons;
|
||||||
|
- the Vapor GTK theme, Konsole profile and user avatars;
|
||||||
|
- Valve's SteamOS desktop defaults, merged into your own config: Noto Sans
|
||||||
|
fonts, no Xwayland input-permission prompt for Steam Input, the window
|
||||||
|
rule that keeps the Steam keyboard on top and out of the taskbar, no
|
||||||
|
screen locking, no welcome screen, light file indexing;
|
||||||
|
- the SteamOS panel: solid (not floating), full width, 44 px high, tray icons
|
||||||
|
scaled to fit, date below the time, and the SteamOS launcher icon;
|
||||||
|
- dark mode for GTK, libadwaita and portal-aware apps (Firefox, Flatpaks).
|
||||||
|
|
||||||
|
Run inside a Plasma session, it applies everything live; otherwise it takes
|
||||||
|
effect at the next desktop login.
|
||||||
|
|
||||||
|
**Package version.** The script always takes the newest
|
||||||
|
`steamdeck-kde-presets` from the highest-numbered SteamOS release repository
|
||||||
|
on the mirror (`jupiter-3.9`, `jupiter-3.10`, ...). That repository's pacman
|
||||||
|
database gives the exact file name and SHA-256 checksum, which is verified
|
||||||
|
after downloading. If the lookup fails, it falls back to the known-good
|
||||||
|
3.9.4 (see `install_vapor_theme()` in `lib/vapor-theme.sh`). To check the
|
||||||
|
current version yourself:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
m=https://steamdeck-packages.steamos.cloud/archlinux-mirror
|
||||||
|
r=$(curl -fsL $m/ | grep -oE 'jupiter-[0-9]+\.[0-9]+/' | tr -d / | sort -V | tail -n 1)
|
||||||
|
curl -fsL $m/$r/os/x86_64/$r.db | bsdtar -tf - | grep -o '^steamdeck-kde-presets-[^/]*' | sort -u
|
||||||
|
```
|
||||||
|
|
||||||
|
### Front LED bar (Steam Machine)
|
||||||
|
|
||||||
|
Standard desktop kernels, including CachyOS's, lack Valve's `leds-valve`
|
||||||
|
driver, so the Steam Machine's front LED bar goes dark or "breathes". On
|
||||||
|
Fremont hardware (DMI `Valve`/`Fremont`) the script offers to:
|
||||||
|
|
||||||
|
- install an AUR helper (`yay`) if neither `yay` nor `paru` is present;
|
||||||
|
- install the kernel headers for every installed kernel;
|
||||||
|
- install `leds-valve-dkms-git` from the AUR, build it for the running
|
||||||
|
kernel, and load it at every boot (`/etc/modules-load.d/leds-valve.conf`);
|
||||||
|
- optionally install the experimental `openrgb-git`, which can drive the bar.
|
||||||
|
|
||||||
|
The LEDs appear as `/sys/class/leds/valve-leds*`. Steam itself only drives
|
||||||
|
the bar (e.g. download progress) in real SteamOS Game Mode.
|
||||||
|
|
||||||
|
The driver's Makefile builds against the running kernel, so after a kernel
|
||||||
|
update, boot the new kernel and re-run the script (or
|
||||||
|
`sudo dkms install leds-valve-dkms/0.1 -k "$(uname -r)"`).
|
||||||
|
|
||||||
|
Troubleshooting:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dkms status
|
||||||
|
ls /sys/class/leds | grep valve
|
||||||
|
sudo dmesg | grep -i valve
|
||||||
|
cat /var/lib/dkms/leds-valve-dkms/0.1/build/make.log
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual session control
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
steamos-session-select gamescope # switch to gamescope right now
|
steamos-session-select gamescope # switch to gamescope right now
|
||||||
steamos-session-select plasma # switch to desktop right now
|
steamos-session-select plasma # switch to desktop right now
|
||||||
steamos-session-select persistent # remember whichever session you used last, across reboots
|
steamos-session-select persistent # remember the last-used session across reboots
|
||||||
steamos-session-select oneshot # always start in gamescope regardless of what you used last (the default Deck-like behavior)
|
steamos-session-select oneshot # always start in gamescope (default, like a Deck)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Restoring the originals
|
With `Relogin=true`, a gamescope session that fails to start is restarted
|
||||||
|
immediately, which can turn into a loop - hence the Ctrl+Alt+F3 escape above.
|
||||||
|
|
||||||
Every file the script modifies is backed up next to itself:
|
### Removing everything
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# restore the original login config
|
||||||
sudo cp /etc/plasmalogin.conf.bak-gamescope-wizard /etc/plasmalogin.conf
|
sudo cp /etc/plasmalogin.conf.bak-gamescope-wizard /etc/plasmalogin.conf
|
||||||
```
|
|
||||||
|
|
||||||
To fully remove the sync watcher this script adds:
|
# session sync watcher
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo systemctl disable --now sync-steamos-session.path
|
sudo systemctl disable --now sync-steamos-session.path
|
||||||
sudo rm /etc/systemd/system/sync-steamos-session.path
|
sudo rm /etc/systemd/system/sync-steamos-session.path
|
||||||
sudo rm /etc/systemd/system/sync-steamos-session.service
|
sudo rm /etc/systemd/system/sync-steamos-session.service
|
||||||
sudo rm /usr/local/bin/sync-steamos-session.sh
|
sudo rm /usr/local/bin/sync-steamos-session.sh
|
||||||
sudo systemctl daemon-reload
|
sudo systemctl daemon-reload
|
||||||
|
|
||||||
|
# shortcut and its sudoers rule
|
||||||
|
sudo rm /etc/sudoers.d/gamescope-session-switch
|
||||||
|
rm ~/Desktop/"Return to Gaming Mode.desktop"
|
||||||
|
|
||||||
|
# Steam desktop autostart and environment
|
||||||
|
systemctl --user disable --now steam-desktop-autostart.service
|
||||||
|
rm ~/.config/systemd/user/steam-desktop-autostart.service
|
||||||
|
rm ~/.config/environment.d/99-gamescope-steam-glyphs.conf \
|
||||||
|
~/.config/environment.d/99-kde-virtual-keyboard.conf
|
||||||
|
|
||||||
|
# LED driver (Steam Machine)
|
||||||
|
sudo rm /etc/modules-load.d/leds-valve.conf
|
||||||
|
sudo pacman -R leds-valve-dkms-git
|
||||||
```
|
```
|
||||||
|
|
||||||
## Caveats
|
### Project layout
|
||||||
|
|
||||||
- This works around current CachyOS/`plasma-login-manager` behavior as of
|
| File | Responsibility |
|
||||||
September 2026. If CachyOS fixes `steam-set-session` upstream to write
|
|---|---|
|
||||||
`User=` and to target whichever base config the login manager actually
|
| `setup-gamescope-boot.sh` | Entry point: user and sudo checks, step order, summary, reboot |
|
||||||
reads, this script becomes unnecessary - check for updates before running
|
| `lib/common.sh` | Output helpers, yes/no prompts, backups |
|
||||||
it on a freshly reinstalled system.
|
| `lib/packages.sh` | Required packages, AUR helper (yay/paru) |
|
||||||
- Tested on a Valve Steam Machine (desktop AMD APU + discrete GPU) running
|
| `lib/login-manager.sh` | plasmalogin autologin, session sync bridge and its systemd units |
|
||||||
CachyOS Desktop edition. Should apply to any CachyOS desktop install using
|
| `lib/steam-desktop.sh` | Steam in the Plasma session: gamepad UI flags, virtual keyboard, autostart |
|
||||||
`plasma-login-manager`, but hasn't been tested on Steam Deck/Legion Go
|
| `lib/led-driver.sh` | Fremont detection, kernel headers, LED driver, OpenRGB |
|
||||||
hardware, which typically ship with SDDM instead.
|
| `lib/vapor-theme.sh` | Vapor theme, Valve's SteamOS defaults, panel, dark mode |
|
||||||
- If you find CachyOS has patched the underlying issue, please open an issue
|
| `lib/desktop-shortcut.sh` | Return to Gaming Mode shortcut and its sudoers rule |
|
||||||
or PR here so the script can detect that and skip the workaround.
|
|
||||||
- The Vapor theme step depends on Valve's `steamdeck-kde-presets` package
|
|
||||||
staying available at its current URL and version
|
|
||||||
(`steamdeck-kde-presets-0.29-1-any.pkg.tar.zst` on
|
|
||||||
`steamdeck-packages.steamos.cloud`). If Valve ships a newer version or
|
|
||||||
changes the mirror layout, update `pkg_ver` near the top of
|
|
||||||
`install_vapor_theme()` in the script.
|
|
||||||
|
|
||||||
## Related upstream reports
|
Notes for contributors and AI coding agents are in [`AGENTS.md`](AGENTS.md).
|
||||||
|
|
||||||
|
### Caveats
|
||||||
|
|
||||||
|
- This works around CachyOS/`plasma-login-manager` behavior as of September
|
||||||
|
2026. If CachyOS fixes `steam-set-session` upstream, parts of this script
|
||||||
|
become unnecessary - please open an issue or PR if you notice that.
|
||||||
|
- Tested on a Valve Steam Machine running CachyOS Desktop edition. It should
|
||||||
|
work on any CachyOS desktop install using `plasma-login-manager`, but
|
||||||
|
hasn't been tested on Steam Deck/Legion Go hardware, which typically use
|
||||||
|
SDDM. With another display manager the script warns and asks before
|
||||||
|
continuing.
|
||||||
|
|
||||||
|
### Related upstream reports
|
||||||
|
|
||||||
- [CachyOS/gamescope-session#9](https://github.com/CachyOS/gamescope-session/issues/9) - "Switch to Desktop" hang due to missing `/etc/plasmalogin.conf.d`
|
- [CachyOS/gamescope-session#9](https://github.com/CachyOS/gamescope-session/issues/9) - "Switch to Desktop" hang due to missing `/etc/plasmalogin.conf.d`
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
<svg id="svg2" height="64" style="" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg" sodipodi:docname="deck_icon.svg" inkscape:version="1.2-dev (d2dd25d878, 2022-02-01, custom)" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<path id="path42220" d="m 32 4 v 10 a 18 18 0 0 1 18 18 a 18 18 0 0 1 -18 18 v 10 a 28 28 0 0 0 28 -28 a 28 28 0 0 0 -28 -28 z" style="fill:#fff;fill-rule:evenodd"/>
|
|
||||||
<circle id="path43518" cx="32" cy="32" r="14" style="fill:#1a9fff;fill-rule:evenodd"/>
|
|
||||||
<path id="path52048" d="m 32 22 a 2 2 0 0 0 -1.4140625 .5859375 l -8 8 a 2.0002 2.0002 0 0 0 0 2.828125 l 8 8 a 2 2 0 0 0 2.828125 0 a 2 2 0 0 0 0 -2.828125 l -4.5859375 -4.5859375 h 11.171875 a 2 2 0 0 0 2 -2 a 2 2 0 0 0 -2 -2 h -11.171875 l 4.5859375 -4.5859375 a 2 2 0 0 0 0 -2.828125 a 2 2 0 0 0 -1.4140625 -.5859375 z" style="fill:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0"/>
|
|
||||||
<g id="path89696" style=""/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Output helpers, prompts and small shared utilities.
|
||||||
|
# Sourced by setup-gamescope-boot.sh; not meant to be run on its own.
|
||||||
|
|
||||||
|
c_reset="\033[0m"; c_bold="\033[1m"; c_green="\033[32m"; c_yellow="\033[33m"; c_red="\033[31m"; c_cyan="\033[36m"
|
||||||
|
|
||||||
|
info() { echo -e "${c_cyan}[INFO]${c_reset} $*"; }
|
||||||
|
ok() { echo -e "${c_green}[OK]${c_reset} $*"; }
|
||||||
|
warn() { echo -e "${c_yellow}[WARN]${c_reset} $*"; }
|
||||||
|
err() { echo -e "${c_red}[ERROR] $*${c_reset}" >&2; }
|
||||||
|
ask_yn() {
|
||||||
|
local prompt="$1" default="${2:-y}" reply
|
||||||
|
local hint="[Y/n]"; [[ "$default" == "n" ]] && hint="[y/N]"
|
||||||
|
read -rp "$(echo -e "${c_bold}${prompt}${c_reset} ${hint} ")" reply
|
||||||
|
reply="${reply:-$default}"
|
||||||
|
[[ "$reply" =~ ^[Yy]$ ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
require_root_helper() {
|
||||||
|
# Re-exec any privileged step through sudo rather than requiring the
|
||||||
|
# whole script to run as root, so $HOME/whoami stay correct for the
|
||||||
|
# target user detection below.
|
||||||
|
if [[ $EUID -eq 0 && -z "${SUDO_USER:-}" ]]; then
|
||||||
|
err "Please run this script as your normal user (it will call sudo itself), not directly as root."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
backup_file() {
|
||||||
|
local f="$1"
|
||||||
|
if [[ -f "$f" && ! -f "${f}.bak-gamescope-wizard" ]]; then
|
||||||
|
sudo cp -a "$f" "${f}.bak-gamescope-wizard"
|
||||||
|
info "Backed up $f -> ${f}.bak-gamescope-wizard"
|
||||||
|
fi
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# "Return to Gaming Mode" desktop shortcut and the sudoers rule it needs.
|
||||||
|
# Sourced by setup-gamescope-boot.sh; not meant to be run on its own.
|
||||||
|
|
||||||
|
create_desktop_shortcut() {
|
||||||
|
# Determine the home directory of the target user
|
||||||
|
local user_home
|
||||||
|
user_home="$(getent passwd "$TARGET_USER" | cut -d: -f6)"
|
||||||
|
|
||||||
|
# Locate the correct Desktop directory
|
||||||
|
local desktop_dir
|
||||||
|
if [[ -f "$user_home/.config/user-dirs.dirs" ]]; then
|
||||||
|
desktop_dir=$(grep '^XDG_DESKTOP_DIR=' "$user_home/.config/user-dirs.dirs" | cut -d '"' -f 2)
|
||||||
|
desktop_dir="${desktop_dir/\$HOME/$user_home}"
|
||||||
|
fi
|
||||||
|
desktop_dir="${desktop_dir:-$user_home/Desktop}"
|
||||||
|
|
||||||
|
mkdir -p "$desktop_dir"
|
||||||
|
|
||||||
|
# Let the shortcut restart the login manager without a password prompt
|
||||||
|
# (it runs with Terminal=false, so sudo can't ask). Scoped to exactly
|
||||||
|
# the two commands the shortcut needs, for this user only.
|
||||||
|
local sudoers_tmp
|
||||||
|
sudoers_tmp="$(mktemp)"
|
||||||
|
cat > "$sudoers_tmp" << EOF
|
||||||
|
$TARGET_USER ALL=(root) NOPASSWD: /usr/bin/systemctl start sync-steamos-session.service, /usr/bin/systemctl restart plasmalogin
|
||||||
|
EOF
|
||||||
|
if sudo visudo -cf "$sudoers_tmp" >/dev/null; then
|
||||||
|
sudo install -m 0440 -o root -g root "$sudoers_tmp" /etc/sudoers.d/gamescope-session-switch
|
||||||
|
ok "Installed /etc/sudoers.d/gamescope-session-switch for the shortcut."
|
||||||
|
else
|
||||||
|
warn "Generated sudoers rule failed validation; the shortcut will not be able to restart plasmalogin."
|
||||||
|
fi
|
||||||
|
rm -f "$sudoers_tmp"
|
||||||
|
|
||||||
|
# SteamOS itself uses Valve's "gaming-return" icon (Steam logo with a
|
||||||
|
# return arrow; the Deck-style arrow is only used on Steam Deck
|
||||||
|
# hardware). It comes with the Vapor theme; without it, use Steam's icon.
|
||||||
|
local shortcut_icon="steam"
|
||||||
|
[[ -f "$user_home/.local/share/icons/hicolor/scalable/actions/gaming-return.svg" ]] &&
|
||||||
|
shortcut_icon="gaming-return"
|
||||||
|
|
||||||
|
# 2. Generate the .desktop shortcut with instant session switcher strings
|
||||||
|
local shortcut_path="$desktop_dir/Return to Gaming Mode.desktop"
|
||||||
|
info "Creating 'Return to Gaming Mode' desktop shortcut at: $shortcut_path"
|
||||||
|
|
||||||
|
cat << EOF > "$shortcut_path"
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Return to Gaming Mode
|
||||||
|
Comment=Switch session back to Gamescope
|
||||||
|
Exec=sh -c 'steamos-session-select gamescope && sudo -n /usr/bin/systemctl start sync-steamos-session.service && sudo -n /usr/bin/systemctl restart plasmalogin'
|
||||||
|
Icon=$shortcut_icon
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=System;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Fix permissions for the target user and KDE Plasma desktop ecosystem
|
||||||
|
chmod +x "$shortcut_path"
|
||||||
|
|
||||||
|
ok "Desktop shortcut created successfully."
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Valve Fremont (Steam Machine) front LED bar driver.
|
||||||
|
# Sourced by setup-gamescope-boot.sh; not meant to be run on its own.
|
||||||
|
|
||||||
|
detect_valve_fremont() {
|
||||||
|
# Valve Steam Machine (Fremont) boards. The leds-valve driver's own DMI
|
||||||
|
# table also matches the OEM/F7F strings some early units report, so
|
||||||
|
# accept both -- otherwise we'd skip hardware the driver supports.
|
||||||
|
local vendor product
|
||||||
|
vendor="$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null || true)"
|
||||||
|
product="$(cat /sys/class/dmi/id/product_name 2>/dev/null || true)"
|
||||||
|
[[ "$vendor" == "Valve" && "$product" == "Fremont" ]] ||
|
||||||
|
[[ "$vendor" == "OEM" && "$product" == "F7F" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
install_kernel_headers() {
|
||||||
|
# DKMS can only build leds-valve against kernels whose headers are
|
||||||
|
# installed. CachyOS ships several kernels (linux-cachyos, -lts, -bore,
|
||||||
|
# ...); install the matching -headers package for every one present.
|
||||||
|
local -a kernels headers=()
|
||||||
|
mapfile -t kernels < <(pacman -Qqo /usr/lib/modules/*/pkgbase 2>/dev/null | sort -u)
|
||||||
|
local k
|
||||||
|
for k in "${kernels[@]}"; do
|
||||||
|
pacman -Si "${k}-headers" >/dev/null 2>&1 && headers+=("${k}-headers")
|
||||||
|
done
|
||||||
|
if [[ ${#headers[@]} -eq 0 ]]; then
|
||||||
|
warn "Couldn't work out which kernel headers package you need."
|
||||||
|
warn "Install the -headers package for your kernel (e.g. linux-cachyos-headers) yourself."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
info "Making sure kernel headers are installed: ${headers[*]}"
|
||||||
|
sudo pacman -S --needed --noconfirm "${headers[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_valve_led_driver() {
|
||||||
|
# Installs the leds-valve DKMS driver from the AUR so the front LED
|
||||||
|
# bar is exposed under /sys/class/leds/valve-leds[N].
|
||||||
|
local aur_helper
|
||||||
|
aur_helper="$(find_aur_helper)"
|
||||||
|
if [[ -z "$aur_helper" ]]; then
|
||||||
|
warn "No AUR helper available - can't install leds-valve-dkms-git."
|
||||||
|
warn "Install one yourself, then run: yay -S leds-valve-dkms-git"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local -a flags
|
||||||
|
read -ra flags <<< "$(aur_noninteractive_flags "$aur_helper")"
|
||||||
|
|
||||||
|
# Headers first: without them the package installs fine but DKMS
|
||||||
|
# silently builds nothing, so modprobe later finds no module.
|
||||||
|
install_kernel_headers || return 1
|
||||||
|
|
||||||
|
if ! pacman -Qi leds-valve-dkms-git >/dev/null 2>&1; then
|
||||||
|
info "Installing leds-valve-dkms-git from the AUR via $aur_helper (non-interactive)..."
|
||||||
|
if ! "$aur_helper" -S "${flags[@]}" leds-valve-dkms-git; then
|
||||||
|
err "Installing leds-valve-dkms-git failed."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
ok "leds-valve-dkms-git already installed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build for the running kernel explicitly. The upstream Makefile uses
|
||||||
|
# `uname -r` rather than DKMS's target kernel, so building for the
|
||||||
|
# running kernel is the one case that reliably works.
|
||||||
|
local kver
|
||||||
|
kver="$(uname -r)"
|
||||||
|
if ! dkms status -k "$kver" leds-valve-dkms 2>/dev/null | grep -q installed; then
|
||||||
|
info "Building leds-valve for running kernel $kver..."
|
||||||
|
if ! sudo dkms install leds-valve-dkms/0.1 -k "$kver"; then
|
||||||
|
err "DKMS build failed. See the build log:"
|
||||||
|
err " /var/lib/dkms/leds-valve-dkms/0.1/build/make.log"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Load now, and on every boot.
|
||||||
|
echo leds-valve | sudo tee /etc/modules-load.d/leds-valve.conf >/dev/null
|
||||||
|
|
||||||
|
info "Loading the leds-valve kernel module..."
|
||||||
|
if sudo modprobe leds-valve; then
|
||||||
|
ok "Module loaded."
|
||||||
|
else
|
||||||
|
warn "modprobe leds-valve failed. Kernel messages:"
|
||||||
|
sudo dmesg | grep -i 'valve' | tail -n 10
|
||||||
|
fi
|
||||||
|
|
||||||
|
if compgen -G "/sys/class/leds/valve-leds*" >/dev/null; then
|
||||||
|
ok "LED bar nodes detected: $(cd /sys/class/leds && echo valve-leds*)"
|
||||||
|
else
|
||||||
|
warn "No valve-leds nodes under /sys/class/leds/ yet. Reboot, then check with:"
|
||||||
|
warn " ls /sys/class/leds/ | grep valve ; sudo dmesg | grep -i valve"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
info "Steam only pushes download progress to the LED bar in real SteamOS Game Mode."
|
||||||
|
if ask_yn "Also install the experimental OpenRGB build (openrgb-git), which can drive the LED bar?" n; then
|
||||||
|
"$aur_helper" -S "${flags[@]}" openrgb-git &&
|
||||||
|
ok "openrgb-git installed. Launch OpenRGB to detect and configure the front panel."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_led_driver() {
|
||||||
|
# Step 8c: only on Fremont hardware, and only if the user wants it.
|
||||||
|
if detect_valve_fremont; then
|
||||||
|
info "Detected Valve Fremont hardware (Steam Machine)."
|
||||||
|
if ask_yn "Set up the front-panel LED bar driver (leds-valve) so it isn't stuck dark/breathing?" y; then
|
||||||
|
ensure_aur_helper || warn "Couldn't set up an AUR helper automatically. You can install one yourself later and run: yay -S leds-valve-dkms-git"
|
||||||
|
install_valve_led_driver || warn "LED driver setup ran into a problem - see errors above. Your gamescope boot setup above is unaffected."
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# plasma-login-manager autologin into gamescope, and the session sync bridge.
|
||||||
|
# Sourced by setup-gamescope-boot.sh; not meant to be run on its own.
|
||||||
|
|
||||||
|
BASE_CONF="/etc/plasmalogin.conf"
|
||||||
|
|
||||||
|
check_display_manager() {
|
||||||
|
# Step 1: warn when the login manager is not plasma-login-manager.
|
||||||
|
local DM
|
||||||
|
DM="$(systemctl show -p Id --value display-manager 2>/dev/null | sed 's/\.service$//')"
|
||||||
|
info "Detected display manager: ${DM:-none}"
|
||||||
|
|
||||||
|
if [[ "$DM" != "plasmalogin" ]]; then
|
||||||
|
warn "This wizard was built and tested against plasma-login-manager (plasmalogin)."
|
||||||
|
warn "Detected display manager is '${DM:-unknown}'. SDDM setups don't need"
|
||||||
|
warn "most of these workarounds (SDDM's own Autologin works out of the box);"
|
||||||
|
warn "this script will still try, but review the output carefully."
|
||||||
|
ask_yn "Continue anyway?" n || exit 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_autologin() {
|
||||||
|
# Steps 3-5: plasmalogin.conf.d, the base [Autologin] section, stray fragments.
|
||||||
|
# 3. Ensure plasmalogin.conf.d exists (fixes Switch-to-Desktop crash)
|
||||||
|
info "Ensuring /etc/plasmalogin.conf.d exists (fixes the 'Switching to Desktop' hang bug)"
|
||||||
|
sudo mkdir -p /etc/plasmalogin.conf.d
|
||||||
|
ok "Directory present."
|
||||||
|
echo
|
||||||
|
|
||||||
|
# 4. Fix the base /etc/plasmalogin.conf
|
||||||
|
info "Configuring $BASE_CONF (Session=gamescope-session.desktop, User=$TARGET_USER, Relogin=true)"
|
||||||
|
backup_file "$BASE_CONF"
|
||||||
|
|
||||||
|
sudo touch "$BASE_CONF"
|
||||||
|
|
||||||
|
sudo awk '
|
||||||
|
BEGIN { in_autologin=0 }
|
||||||
|
/^\[Autologin\]/ { in_autologin=1; next }
|
||||||
|
/^\[/ { in_autologin=0 }
|
||||||
|
!in_autologin { print }
|
||||||
|
' "$BASE_CONF" | sudo tee "${BASE_CONF}.tmp" > /dev/null || { err "Failed to rewrite $BASE_CONF."; exit 1; }
|
||||||
|
|
||||||
|
sudo mv "${BASE_CONF}.tmp" "$BASE_CONF"
|
||||||
|
|
||||||
|
sudo tee -a "$BASE_CONF" > /dev/null << EOF
|
||||||
|
[Autologin]
|
||||||
|
Session=gamescope-session.desktop
|
||||||
|
User=$TARGET_USER
|
||||||
|
Relogin=true
|
||||||
|
EOF
|
||||||
|
|
||||||
|
ok "Base autologin config written:"
|
||||||
|
sudo sed -n '/^\[Autologin\]/,$p' "$BASE_CONF"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# 5. Clean up any stray conf.d autologin fragments from manual attempts
|
||||||
|
info "Removing any leftover manual conf.d autologin overrides (base config now handles it)"
|
||||||
|
sudo rm -f /etc/plasmalogin.conf.d/zzz-steamos-autologin*.conf
|
||||||
|
ok "Cleaned."
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
install_session_sync() {
|
||||||
|
# Steps 6-8: sync bridge conf.d -> base config, its systemd units, first run.
|
||||||
|
# 6. Install the sync bridge: conf.d -> base config
|
||||||
|
local SYNC_SCRIPT="/usr/local/bin/sync-steamos-session.sh"
|
||||||
|
info "Installing session sync bridge at $SYNC_SCRIPT"
|
||||||
|
|
||||||
|
sudo tee "$SYNC_SCRIPT" > /dev/null << 'EOF'
|
||||||
|
#!/bin/bash
|
||||||
|
SRC="/etc/plasmalogin.conf.d/zz-steamos-autologin.conf"
|
||||||
|
DEST="/etc/plasmalogin.conf"
|
||||||
|
|
||||||
|
[[ -f "$SRC" ]] || exit 0
|
||||||
|
SESSION=$(grep -oP '^Session=\K.*' "$SRC")
|
||||||
|
[[ -z "$SESSION" ]] && exit 0
|
||||||
|
|
||||||
|
# Only touch Session= inside [Autologin]; other sections may have their own.
|
||||||
|
if sed -n '/^\[Autologin\]/,/^\[/p' "$DEST" | grep -q '^Session='; then
|
||||||
|
sed -i "/^\[Autologin\]/,/^\[/ s|^Session=.*|Session=$SESSION|" "$DEST"
|
||||||
|
elif grep -q '^\[Autologin\]' "$DEST"; then
|
||||||
|
sed -i "/^\[Autologin\]/a Session=$SESSION" "$DEST"
|
||||||
|
else
|
||||||
|
printf '\n[Autologin]\nSession=%s\n' "$SESSION" >> "$DEST"
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo chmod +x "$SYNC_SCRIPT"
|
||||||
|
ok "Sync script installed."
|
||||||
|
echo
|
||||||
|
|
||||||
|
# 7. systemd path watcher + service
|
||||||
|
info "Installing systemd path watcher so session switches take effect immediately"
|
||||||
|
|
||||||
|
sudo tee /etc/systemd/system/sync-steamos-session.path > /dev/null << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Watch for steamos session changes
|
||||||
|
|
||||||
|
[Path]
|
||||||
|
PathModified=/etc/plasmalogin.conf.d/zz-steamos-autologin.conf
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo tee /etc/systemd/system/sync-steamos-session.service > /dev/null << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Sync steamos session selection into plasmalogin.conf
|
||||||
|
# Session switches can come in bursts (switch + autologin reset); never
|
||||||
|
# let systemd's start rate limit silently stop the bridge.
|
||||||
|
StartLimitIntervalSec=0
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/bin/sync-steamos-session.sh
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now sync-steamos-session.path
|
||||||
|
ok "Path watcher enabled."
|
||||||
|
echo
|
||||||
|
|
||||||
|
# 8. Run it once now so current state is in sync
|
||||||
|
info "Running the sync once now to align current state"
|
||||||
|
sudo systemctl start sync-steamos-session.service
|
||||||
|
ok "Done. Current base config:"
|
||||||
|
sudo cat "$BASE_CONF"
|
||||||
|
echo
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Required packages and AUR helper handling.
|
||||||
|
# Sourced by setup-gamescope-boot.sh; not meant to be run on its own.
|
||||||
|
|
||||||
|
aur_noninteractive_flags() {
|
||||||
|
# Fully non-interactive install flags for the given AUR helper: no
|
||||||
|
# PKGBUILD diff/edit/cleanbuild prompts, no provider-selection prompts
|
||||||
|
# (e.g. picking kernel headers for DKMS), and makepkg itself silenced.
|
||||||
|
case "$1" in
|
||||||
|
yay)
|
||||||
|
echo --needed --noconfirm --answerclean None --answerdiff None \
|
||||||
|
--answeredit None --mflags "--noconfirm"
|
||||||
|
;;
|
||||||
|
paru)
|
||||||
|
echo --needed --noconfirm --skipreview --mflags "--noconfirm"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
find_aur_helper() {
|
||||||
|
if command -v yay >/dev/null 2>&1; then
|
||||||
|
echo yay
|
||||||
|
elif command -v paru >/dev/null 2>&1; then
|
||||||
|
echo paru
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
bootstrap_yay() {
|
||||||
|
# Builds and installs yay from the AUR using only makepkg + base-devel
|
||||||
|
# (both from the official repos), so we have an AUR helper available
|
||||||
|
# without assuming the user already set one up.
|
||||||
|
info "Installing base-devel and git (needed to build an AUR helper)..."
|
||||||
|
sudo pacman -S --needed --noconfirm base-devel git || return 1
|
||||||
|
|
||||||
|
local tmp_dir
|
||||||
|
tmp_dir="$(mktemp -d)"
|
||||||
|
info "Cloning yay-bin from the AUR..."
|
||||||
|
if ! git clone --depth 1 https://aur.archlinux.org/yay-bin.git "$tmp_dir/yay-bin"; then
|
||||||
|
err "Failed to clone yay-bin from the AUR."
|
||||||
|
rm -rf "$tmp_dir"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Building and installing yay (this runs makepkg as your user, not root)..."
|
||||||
|
if (cd "$tmp_dir/yay-bin" && makepkg -si --noconfirm); then
|
||||||
|
ok "yay installed."
|
||||||
|
rm -rf "$tmp_dir"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
err "Building yay failed. See errors above."
|
||||||
|
rm -rf "$tmp_dir"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_required_packages() {
|
||||||
|
# Step 2: gamescope/Steam and the desktop helpers the rest of the setup uses.
|
||||||
|
local -a MISSING
|
||||||
|
info "Checking required packages: gamescope-session-cachyos, steam, mangohud, xterm, ttf-liberation, wqy-zenhei, plasma-keyboard"
|
||||||
|
mapfile -t MISSING < <(pacman -T gamescope-session-cachyos steam mangohud xterm ttf-liberation wqy-zenhei plasma-keyboard)
|
||||||
|
|
||||||
|
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
||||||
|
info "Missing packages: ${MISSING[*]}"
|
||||||
|
if ask_yn "Install them now?"; then
|
||||||
|
sudo pacman -S --needed --noconfirm "${MISSING[@]}" || { err "Package installation failed."; exit 1; }
|
||||||
|
else
|
||||||
|
err "Cannot continue without these packages."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
ok "All required packages already installed."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_aur_helper() {
|
||||||
|
# yay or paru, bootstrapping yay from the AUR when neither is installed.
|
||||||
|
if [[ -n "$(find_aur_helper)" ]]; then
|
||||||
|
ok "AUR helper already present."
|
||||||
|
else
|
||||||
|
info "No AUR helper (yay/paru) found. Installing yay..."
|
||||||
|
bootstrap_yay
|
||||||
|
fi
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Steam in the Plasma desktop session: gamepad UI args, virtual keyboard, autostart.
|
||||||
|
# Sourced by setup-gamescope-boot.sh; not meant to be run on its own.
|
||||||
|
|
||||||
|
setup_steam_desktop() {
|
||||||
|
# Step 8b: always runs.
|
||||||
|
info "Applying non-optional SteamOS environment & keyboard fixes..."
|
||||||
|
local steam_env_dir gs_env systemd_user_dir
|
||||||
|
steam_env_dir="$HOME/.config/environment.d"
|
||||||
|
mkdir -p "$steam_env_dir"
|
||||||
|
|
||||||
|
# 1. Force Gamescope Steam to boot into Deck mode and load Deck glyphs
|
||||||
|
echo "STEAM_GAMEPADUI_ARGS=\"-gamepadui -steamos3\"" > "$steam_env_dir/99-gamescope-steam-glyphs.conf"
|
||||||
|
gs_env="$HOME/.config/gamescope-session/environment"
|
||||||
|
if [[ -d "$HOME/.config/gamescope-session" ]]; then
|
||||||
|
touch "$gs_env"
|
||||||
|
sed -i '/^STEAM_GAMEPADUI_ARGS=/d' "$gs_env"
|
||||||
|
echo "STEAM_GAMEPADUI_ARGS=\"-gamepadui -steamos3\"" >> "$gs_env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Prevent KDE Wayland from blocking the virtual keyboard overlay
|
||||||
|
echo "KWIN_IM_SHOW_ALWAYS=1" > "$steam_env_dir/99-kde-virtual-keyboard.conf"
|
||||||
|
|
||||||
|
# 3. Setup robust background systemd service for Steam autostart on Desktop Mode
|
||||||
|
systemd_user_dir="$HOME/.config/systemd/user"
|
||||||
|
mkdir -p "$systemd_user_dir"
|
||||||
|
|
||||||
|
cat << 'EOF' > "$systemd_user_dir/steam-desktop-autostart.service"
|
||||||
|
[Unit]
|
||||||
|
Description=Steam Background Autostart for Virtual Keyboard
|
||||||
|
After=graphical-session.target
|
||||||
|
PartOf=graphical-session.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
# Only in the Plasma desktop session; gamescope-session starts its own Steam.
|
||||||
|
ExecCondition=/bin/sh -c '[ "$XDG_CURRENT_DESKTOP" = KDE ]'
|
||||||
|
ExecStart=/usr/bin/steam -silent
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=graphical-session.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Clean out old .desktop shortcut so they don't fight
|
||||||
|
rm -f "$HOME/.config/autostart/steam.desktop"
|
||||||
|
|
||||||
|
# Reload user systemd context and activate the background loop
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
systemctl --user enable --now steam-desktop-autostart.service
|
||||||
|
|
||||||
|
ok "Steam UI parameters and keyboard autostart deployed successfully."
|
||||||
|
}
|
||||||
@@ -0,0 +1,323 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Valve's SteamOS Vapor desktop theme and SteamOS desktop defaults.
|
||||||
|
# Sourced by setup-gamescope-boot.sh; not meant to be run on its own.
|
||||||
|
|
||||||
|
merge_kde_config() {
|
||||||
|
# Merge a KDE-style ini file (e.g. one of Valve's /etc/xdg defaults) into
|
||||||
|
# the user's own config with kwriteconfig6, so SteamOS defaults win over
|
||||||
|
# the distro's without touching package-owned files in /etc/xdg.
|
||||||
|
# Nested groups ("[A][B]") are supported; immutable "[$i]" groups and
|
||||||
|
# comments are skipped.
|
||||||
|
local src="$1" target="$2" line key value
|
||||||
|
local -a groups=()
|
||||||
|
local skip=0
|
||||||
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||||
|
line="${line%$'\r'}"
|
||||||
|
[[ -z "$line" || "$line" == \#* ]] && continue
|
||||||
|
if [[ "$line" == \[* ]]; then
|
||||||
|
skip=0; groups=()
|
||||||
|
[[ "$line" == *'[$'* ]] && { skip=1; continue; }
|
||||||
|
local rest="$line"
|
||||||
|
while [[ "$rest" =~ ^\[([^]]*)\](.*)$ ]]; do
|
||||||
|
groups+=("--group" "${BASH_REMATCH[1]}")
|
||||||
|
rest="${BASH_REMATCH[2]}"
|
||||||
|
done
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
(( skip )) && continue
|
||||||
|
[[ "$line" == *=* ]] || continue
|
||||||
|
key="${line%%=*}"; value="${line#*=}"
|
||||||
|
kwriteconfig6 --file "$target" "${groups[@]}" --key "$key" "$value"
|
||||||
|
done < "$src"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_vapor_theme() {
|
||||||
|
# Installs Valve's official SteamOS "Vapor" Plasma theme (color scheme,
|
||||||
|
# Plasma look-and-feel package, wallpapers, icons) straight from Valve's
|
||||||
|
# own SteamOS package mirror, into the current user's ~/.local/share.
|
||||||
|
# This only touches the invoking user's home directory, never system
|
||||||
|
# files, so it's independent from everything else this script does.
|
||||||
|
local mirror="https://steamdeck-packages.steamos.cloud/archlinux-mirror"
|
||||||
|
local repo file_name sha256 tmp_dir
|
||||||
|
tmp_dir="$(mktemp -d)"
|
||||||
|
|
||||||
|
# Take the package from the newest SteamOS release repo (jupiter-3.9,
|
||||||
|
# jupiter-3.10, ...), read from its pacman database: that gives the
|
||||||
|
# exact file name and checksum. Fall back to a known-good version.
|
||||||
|
info "Looking up the current SteamOS Vapor presets..."
|
||||||
|
repo="$(curl -fsL "$mirror/" | grep -oE 'jupiter-[0-9]+\.[0-9]+/' | tr -d / | sort -V | tail -n 1)"
|
||||||
|
if [[ -n "$repo" ]] && curl -fsL "$mirror/$repo/os/x86_64/$repo.db" -o "$tmp_dir/repo.db"; then
|
||||||
|
local desc
|
||||||
|
desc="$(tar -tf "$tmp_dir/repo.db" 2>/dev/null | grep -E '^steamdeck-kde-presets-[0-9][^/]*/desc$' | head -n 1)"
|
||||||
|
if [[ -n "$desc" ]]; then
|
||||||
|
file_name="$(tar -xOf "$tmp_dir/repo.db" "$desc" | awk '/^%FILENAME%$/ { getline; print }')"
|
||||||
|
sha256="$(tar -xOf "$tmp_dir/repo.db" "$desc" | awk '/^%SHA256SUM%$/ { getline; print }')"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ -z "${file_name:-}" ]]; then
|
||||||
|
warn "Couldn't read Valve's package index; using the known-good version."
|
||||||
|
repo="jupiter-3.9"
|
||||||
|
file_name="steamdeck-kde-presets-3.9.4-2-any.pkg.tar.zst"
|
||||||
|
sha256=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Downloading $file_name ($repo)..."
|
||||||
|
if ! curl -fL "$mirror/$repo/os/x86_64/$file_name" -o "${tmp_dir}/presets.tar.zst"; then
|
||||||
|
err "Download failed. Valve may have moved/renamed this package;"
|
||||||
|
err "check $mirror for the current version."
|
||||||
|
rm -rf "$tmp_dir"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [[ -n "$sha256" ]] && ! echo "$sha256 ${tmp_dir}/presets.tar.zst" | sha256sum -c --quiet -; then
|
||||||
|
err "Checksum mismatch for $file_name; not installing it."
|
||||||
|
rm -rf "$tmp_dir"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Extracting package contents..."
|
||||||
|
if ! tar -I unzstd -xf "${tmp_dir}/presets.tar.zst" -C "$tmp_dir"; then
|
||||||
|
err "Extraction failed (is 'zstd' installed? try: sudo pacman -S --needed zstd)"
|
||||||
|
rm -rf "$tmp_dir"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Creating local configuration directories..."
|
||||||
|
mkdir -p ~/.local/share/color-schemes \
|
||||||
|
~/.local/share/plasma/desktoptheme \
|
||||||
|
~/.local/share/plasma/look-and-feel \
|
||||||
|
~/.local/share/wallpapers \
|
||||||
|
~/.local/share/icons/hicolor
|
||||||
|
|
||||||
|
info "Installing Steam Deck theme assets..."
|
||||||
|
[[ -d "${tmp_dir}/usr/share/color-schemes" ]] && cp -r "${tmp_dir}/usr/share/color-schemes/"* ~/.local/share/color-schemes/
|
||||||
|
[[ -d "${tmp_dir}/usr/share/plasma/desktoptheme/Vapor" ]] && cp -r "${tmp_dir}/usr/share/plasma/desktoptheme/Vapor" ~/.local/share/plasma/desktoptheme/
|
||||||
|
[[ -d "${tmp_dir}/usr/share/plasma/look-and-feel/com.valve.vapor.desktop" ]] && cp -r "${tmp_dir}/usr/share/plasma/look-and-feel/com.valve.vapor.desktop" ~/.local/share/plasma/look-and-feel/
|
||||||
|
[[ -d "${tmp_dir}/usr/share/wallpapers" ]] && cp -r "${tmp_dir}/usr/share/wallpapers/"* ~/.local/share/wallpapers/
|
||||||
|
[[ -d "${tmp_dir}/usr/share/icons/hicolor" ]] && cp -r "${tmp_dir}/usr/share/icons/hicolor/"* ~/.local/share/icons/hicolor/
|
||||||
|
|
||||||
|
# The rest of what SteamOS ships: GTK theme (Steam, Firefox, ...), Konsole
|
||||||
|
# profile and user avatars -- the same files the AUR package installs.
|
||||||
|
mkdir -p ~/.local/share/themes ~/.local/share/konsole ~/.local/share/plasma/avatars
|
||||||
|
[[ -d "${tmp_dir}/usr/share/themes/Vapor" ]] && cp -r "${tmp_dir}/usr/share/themes/Vapor" ~/.local/share/themes/
|
||||||
|
[[ -d "${tmp_dir}/usr/share/konsole" ]] && cp -r "${tmp_dir}/usr/share/konsole/"* ~/.local/share/konsole/
|
||||||
|
[[ -d "${tmp_dir}/usr/share/plasma/avatars" ]] && cp -r "${tmp_dir}/usr/share/plasma/avatars/"* ~/.local/share/plasma/avatars/
|
||||||
|
|
||||||
|
# Valve's SteamOS desktop defaults (fonts, Steam keyboard window rule,
|
||||||
|
# no screen locking, no welcome screen, light file indexing, GTK theme).
|
||||||
|
# Left out on purpose: autostart entries (Steam is started by our user
|
||||||
|
# unit), sddm/profile.d, and files hardcoding /home/deck or SteamOS tools.
|
||||||
|
info "Applying SteamOS desktop defaults..."
|
||||||
|
local f
|
||||||
|
for f in kdeglobals kwinrc kwinrulesrc kscreenlockerrc kded5rc baloofilerc kcminputrc; do
|
||||||
|
[[ -f "${tmp_dir}/etc/xdg/$f" ]] && merge_kde_config "${tmp_dir}/etc/xdg/$f" "$f"
|
||||||
|
done
|
||||||
|
[[ -f "${tmp_dir}/etc/xdg/kded5rc" ]] && merge_kde_config "${tmp_dir}/etc/xdg/kded5rc" kded6rc
|
||||||
|
kwriteconfig6 --file konsolerc --group "Desktop Entry" --key DefaultProfile Vapor.profile
|
||||||
|
mkdir -p ~/.config/gtk-3.0 ~/.config/gtk-4.0
|
||||||
|
kwriteconfig6 --file ~/.config/gtk-3.0/settings.ini --group Settings --key gtk-theme-name Vapor
|
||||||
|
kwriteconfig6 --file ~/.config/gtk-4.0/settings.ini --group Settings --key gtk-theme-name Vapor
|
||||||
|
# Vapor is a dark theme: tell GTK, libadwaita and portal-aware apps
|
||||||
|
# (Firefox, Steam's web views, Flatpaks) to use their dark variants too.
|
||||||
|
kwriteconfig6 --file ~/.config/gtk-3.0/settings.ini --group Settings --key gtk-application-prefer-dark-theme true
|
||||||
|
kwriteconfig6 --file ~/.config/gtk-4.0/settings.ini --group Settings --key gtk-application-prefer-dark-theme true
|
||||||
|
if command -v gsettings >/dev/null 2>&1; then
|
||||||
|
gsettings set org.gnome.desktop.interface color-scheme prefer-dark 2>/dev/null || true
|
||||||
|
gsettings set org.gnome.desktop.interface gtk-theme Vapor 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
[[ -f "${tmp_dir}/etc/xdg/gtk-2.0/gtkrc" ]] && cp "${tmp_dir}/etc/xdg/gtk-2.0/gtkrc" ~/.gtkrc-2.0
|
||||||
|
|
||||||
|
info "Cleaning up temporary files..."
|
||||||
|
rm -rf "$tmp_dir"
|
||||||
|
|
||||||
|
# Launcher icon
|
||||||
|
# Same launcher icon SteamOS sets (Vapor Deck plasmoid setup script).
|
||||||
|
local icon_name="distributor-logo-steamdeck"
|
||||||
|
local conf_file="$HOME/.config/plasma-org.kde.plasma.desktop-appletsrc"
|
||||||
|
|
||||||
|
if ! find ~/.local/share/icons /usr/share/icons -iname "${icon_name}.*" 2>/dev/null | grep -q .; then
|
||||||
|
warn "Could not find '${icon_name}' installed anywhere under ~/.local/share/icons or /usr/share/icons."
|
||||||
|
warn "The launcher icon will be set anyway, but it may show as a broken icon until the file is installed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$conf_file" ]]; then
|
||||||
|
info "Looking for the Application Launcher applet (Kickoff/Kicker) to set the custom icon..."
|
||||||
|
local matches=()
|
||||||
|
local current_section=""
|
||||||
|
local current_containment=""
|
||||||
|
local current_applet=""
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if [[ "$line" =~ ^\[Containments\]\[([0-9]+)\]\[Applets\]\[([0-9]+)\]$ ]]; then
|
||||||
|
current_containment="${BASH_REMATCH[1]}"
|
||||||
|
current_applet="${BASH_REMATCH[2]}"
|
||||||
|
current_section="applet_root"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [[ "$line" =~ ^\[ ]]; then
|
||||||
|
current_section=""
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [[ "$current_section" == "applet_root" && "$line" =~ ^plugin=(org\.kde\.plasma\.(kickoff|kicker|simplemenu|homerun|application-menu))$ ]]; then
|
||||||
|
matches+=( "${current_containment}:${current_applet}:${BASH_REMATCH[1]}" )
|
||||||
|
current_section=""
|
||||||
|
fi
|
||||||
|
done < "$conf_file"
|
||||||
|
|
||||||
|
if [[ ${#matches[@]} -gt 0 ]]; then
|
||||||
|
for m in "${matches[@]}"; do
|
||||||
|
IFS=':' read -r containment applet plugin <<< "$m"
|
||||||
|
info "Setting launcher icon on Containment $containment / Applet $applet ($plugin)..."
|
||||||
|
kwriteconfig6 \
|
||||||
|
--file "$conf_file" \
|
||||||
|
--group Containments --group "$containment" \
|
||||||
|
--group Applets --group "$applet" \
|
||||||
|
--group Configuration --group General \
|
||||||
|
--key icon "$icon_name"
|
||||||
|
ok "Icon set to '$icon_name'."
|
||||||
|
done
|
||||||
|
else
|
||||||
|
warn "No compatible Application Launcher applet found in panel config. Skipping icon assignment."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "$conf_file not found. Skipping menu icon configuration."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SteamOS scales system tray icons to the panel height. Valve's setup
|
||||||
|
# script targets Plasma 5's separate tray containment; in Plasma 6 the
|
||||||
|
# setting lives on the systemtray applet itself.
|
||||||
|
if [[ -f "$conf_file" ]]; then
|
||||||
|
local tray
|
||||||
|
for tray in $(awk '
|
||||||
|
/^\[Containments\]\[[0-9]+\]\[Applets\]\[[0-9]+\]$/ { split($0, p, /[][]+/); sect = p[3] ":" p[5] }
|
||||||
|
/^\[/ && !/\]\[Applets\]\[[0-9]+\]$/ { sect = "" }
|
||||||
|
/^plugin=org\.kde\.plasma\.systemtray$/ && sect != "" { print sect }
|
||||||
|
' "$conf_file"); do
|
||||||
|
kwriteconfig6 --file "$conf_file" --group Containments --group "${tray%%:*}" \
|
||||||
|
--group Applets --group "${tray#*:}" --group General \
|
||||||
|
--key scaleIconsToFit true
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# SteamOS shows the date below the time in the panel clock.
|
||||||
|
if [[ -f "$conf_file" ]]; then
|
||||||
|
local clock
|
||||||
|
for clock in $(awk '
|
||||||
|
/^\[Containments\]\[[0-9]+\]\[Applets\]\[[0-9]+\]$/ { split($0, p, /[][]+/); sect = p[3] ":" p[5] }
|
||||||
|
/^\[/ && !/\]\[Applets\]\[[0-9]+\]$/ { sect = "" }
|
||||||
|
/^plugin=org\.kde\.plasma\.digitalclock$/ && sect != "" { print sect }
|
||||||
|
' "$conf_file"); do
|
||||||
|
kwriteconfig6 --file "$conf_file" --group Containments --group "${clock%%:*}" \
|
||||||
|
--group Applets --group "${clock#*:}" --group Configuration --group Appearance \
|
||||||
|
--key dateDisplayFormat BelowTime
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Wallpaper
|
||||||
|
# Valve ships the wallpapers as flat JPGs in usr/share/wallpapers.
|
||||||
|
local wallpaper_path="$HOME/.local/share/wallpapers/Steam Deck Logo Default.jpg"
|
||||||
|
|
||||||
|
if [[ -f "$wallpaper_path" ]]; then
|
||||||
|
info "Applying official Steam Deck Vapor wallpaper via D-Bus script..."
|
||||||
|
local dbus_cmd="
|
||||||
|
var allDesktops = desktops();
|
||||||
|
for (var i = 0; i < allDesktops.length; i++) {
|
||||||
|
var d = allDesktops[i];
|
||||||
|
d.currentConfigGroup = ['Wallpaper', 'org.kde.image', 'General'];
|
||||||
|
d.writeConfig('Image', 'file://${wallpaper_path}');
|
||||||
|
}
|
||||||
|
"
|
||||||
|
if ! pgrep -u "$USER" -x plasmashell >/dev/null; then
|
||||||
|
:
|
||||||
|
elif command -v qdbus6 >/dev/null 2>&1; then
|
||||||
|
qdbus6 org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "$dbus_cmd" >/dev/null 2>&1 || true
|
||||||
|
else
|
||||||
|
qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "$dbus_cmd" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$conf_file" ]]; then
|
||||||
|
local desktop_sections=$(grep -E '^\[Containments\]\[[0-9]+\]$' "$conf_file" || true)
|
||||||
|
while read -r section; do
|
||||||
|
if [[ -n "$section" ]]; then
|
||||||
|
local clean_sec=$(echo "$section" | tr -d '[]')
|
||||||
|
kwriteconfig6 --file "$conf_file" --group "$clean_sec" --group Wallpaper --group org.kde.image --group General --key Image "file://${wallpaper_path}"
|
||||||
|
fi
|
||||||
|
done <<< "$desktop_sections"
|
||||||
|
fi
|
||||||
|
ok "Wallpaper path pushed to session config."
|
||||||
|
else
|
||||||
|
warn "Could not find extracted Vapor wallpaper file. Skipping."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Activate the Vapor global theme and color scheme, then restart
|
||||||
|
# plasmashell once so it picks everything up (restarting first races
|
||||||
|
# with the settings being written). The theme's own defaults use
|
||||||
|
# breeze-dark icons; there is no "Vapor" icon theme.
|
||||||
|
kwriteconfig6 --file kdeglobals --group Icons --key Theme "breeze-dark"
|
||||||
|
kwriteconfig6 --file kdeglobals --group General --key ColorScheme "Vapor"
|
||||||
|
kwriteconfig6 --file plasmarc --group Theme --key name "Vapor"
|
||||||
|
|
||||||
|
# Same panel change for the next login, in case Plasma isn't running now.
|
||||||
|
local panel
|
||||||
|
for panel in $(grep -oP '^\[PlasmaViews\]\[Panel \K[0-9]+(?=\]$)' ~/.config/plasmashellrc 2>/dev/null); do
|
||||||
|
kwriteconfig6 --file plasmashellrc --group PlasmaViews --group "Panel $panel" --key floating 0
|
||||||
|
kwriteconfig6 --file plasmashellrc --group PlasmaViews --group "Panel $panel" --group Defaults --key thickness 44
|
||||||
|
done
|
||||||
|
|
||||||
|
gtk-update-icon-cache -f -t ~/.local/share/icons/hicolor 2>/dev/null || true
|
||||||
|
kbuildsycoca6 --noincremental 2>/dev/null || true
|
||||||
|
|
||||||
|
# Live changes need a running Plasma session; otherwise they are picked
|
||||||
|
# up from the config files above at the next Plasma login.
|
||||||
|
if pgrep -u "$USER" -x plasmashell >/dev/null; then
|
||||||
|
info "Applying the theme to the running Plasma session..."
|
||||||
|
lookandfeeltool -a com.valve.vapor.desktop >/dev/null 2>&1 || true
|
||||||
|
# lookandfeeltool leaves the distro's color scheme active; apply it explicitly.
|
||||||
|
plasma-apply-colorscheme Vapor >/dev/null 2>&1 || true
|
||||||
|
qdbus6 org.kde.kded6 /modules/gtkconfig org.kde.gtkconfig.setGtkTheme Vapor >/dev/null 2>&1 || true
|
||||||
|
qdbus6 org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript \
|
||||||
|
'panels().forEach(function (p) {
|
||||||
|
p.widgets("org.kde.plasma.systemtray").forEach(function (w) { w.currentConfigGroup = ["General"]; w.writeConfig("scaleIconsToFit", true); });
|
||||||
|
p.widgets("org.kde.plasma.digitalclock").forEach(function (w) { w.currentConfigGroup = ["Appearance"]; w.writeConfig("dateDisplayFormat", "BelowTime"); });
|
||||||
|
})' \
|
||||||
|
>/dev/null 2>&1 || true
|
||||||
|
# SteamOS uses a solid, full-width bottom panel at Plasma's stock
|
||||||
|
# 44px height (CachyOS ships a floating 30px one).
|
||||||
|
qdbus6 org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript \
|
||||||
|
'panels().forEach(function (p) { p.floating = false; p.lengthMode = "fill"; p.height = 44; })' \
|
||||||
|
>/dev/null 2>&1 || true
|
||||||
|
sleep 2 # let plasmashell flush the scripted changes before replacing it
|
||||||
|
rm -rf ~/.cache/plasmashell* ~/.cache/org.kde.dirmodel-qml.kcache
|
||||||
|
qdbus6 org.kde.KWin /KWin org.kde.KWin.reconfigure >/dev/null 2>&1 || true
|
||||||
|
# Restart through systemd so plasmashell keeps the session's environment
|
||||||
|
# (platform theme etc.); a plain --replace from this shell may not.
|
||||||
|
if systemctl --user cat plasma-plasmashell.service >/dev/null 2>&1; then
|
||||||
|
# Also takes over from a stray instance started by an earlier --replace.
|
||||||
|
systemctl --user stop plasma-plasmashell.service
|
||||||
|
pkill -u "$USER" -x plasmashell && sleep 2
|
||||||
|
systemctl --user start plasma-plasmashell.service
|
||||||
|
else
|
||||||
|
setsid plasmashell --replace >/dev/null 2>&1 &
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
info "No running Plasma session; the theme applies at your next desktop login."
|
||||||
|
fi
|
||||||
|
|
||||||
|
ok "Vapor theme assets installed. Apply it under System Settings > Appearance"
|
||||||
|
ok "> Global Theme > Vapor (Steam Deck), next time you're in a Plasma session."
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_vapor_theme() {
|
||||||
|
# Step 9 (optional): ask, make sure curl/zstd exist, then install.
|
||||||
|
echo
|
||||||
|
if ask_yn "Also install Valve's official Vapor (Steam Deck) KDE theme for your desktop session?" n; then
|
||||||
|
if ! command -v curl >/dev/null 2>&1; then
|
||||||
|
warn "curl not found, installing it first..."
|
||||||
|
sudo pacman -S --needed --noconfirm curl
|
||||||
|
fi
|
||||||
|
if ! command -v unzstd >/dev/null 2>&1; then
|
||||||
|
warn "zstd not found, installing it first..."
|
||||||
|
sudo pacman -S --needed --noconfirm zstd
|
||||||
|
fi
|
||||||
|
install_vapor_theme || warn "Vapor theme install ran into a problem - see errors above. Your gamescope boot setup above is unaffected."
|
||||||
|
fi
|
||||||
|
}
|
||||||
+26
-600
@@ -31,7 +31,7 @@
|
|||||||
# desktop side matches the gamescope side visually.
|
# desktop side matches the gamescope side visually.
|
||||||
#
|
#
|
||||||
# On Valve Fremont hardware (DMI sys_vendor=Valve, product_name=Fremont --
|
# On Valve Fremont hardware (DMI sys_vendor=Valve, product_name=Fremont --
|
||||||
# i.e. Steam Machine / BC-250-class boards), also offers to install the
|
# i.e. the Steam Machine), also offers to install the
|
||||||
# leds-valve DKMS driver from the AUR so the front LED bar is exposed under
|
# leds-valve DKMS driver from the AUR so the front LED bar is exposed under
|
||||||
# /sys/class/leds instead of sitting dark or "breathing" under a standard
|
# /sys/class/leds instead of sitting dark or "breathing" under a standard
|
||||||
# desktop kernel, plus the option to pull in an experimental OpenRGB build
|
# desktop kernel, plus the option to pull in an experimental OpenRGB build
|
||||||
@@ -39,385 +39,12 @@
|
|||||||
|
|
||||||
set -uo pipefail
|
set -uo pipefail
|
||||||
|
|
||||||
# ---------- helpers ----------
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
c_reset="\033[0m"; c_bold="\033[1m"; c_green="\033[32m"; c_yellow="\033[33m"; c_red="\033[31m"; c_cyan="\033[36m"
|
for lib in common packages login-manager steam-desktop led-driver vapor-theme desktop-shortcut; do
|
||||||
|
# shellcheck source=/dev/null
|
||||||
info() { echo -e "${c_cyan}[INFO]${c_reset} $*"; }
|
source "$SCRIPT_DIR/lib/$lib.sh"
|
||||||
ok() { echo -e "${c_green}[OK]${c_reset} $*"; }
|
done
|
||||||
warn() { echo -e "${c_yellow}[WARN]${c_reset} $*"; }
|
|
||||||
err() { echo -e "${c_red}[ERROR] $*${c_reset}" >&2; }
|
|
||||||
ask_yn() {
|
|
||||||
local prompt="$1" default="${2:-y}" reply
|
|
||||||
local hint="[Y/n]"; [[ "$default" == "n" ]] && hint="[y/N]"
|
|
||||||
read -rp "$(echo -e "${c_bold}${prompt}${c_reset} ${hint} ")" reply
|
|
||||||
reply="${reply:-$default}"
|
|
||||||
[[ "$reply" =~ ^[Yy]$ ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
require_root_helper() {
|
|
||||||
# Re-exec any privileged step through sudo rather than requiring the
|
|
||||||
# whole script to run as root, so $HOME/whoami stay correct for the
|
|
||||||
# target user detection below.
|
|
||||||
if [[ $EUID -eq 0 && -z "${SUDO_USER:-}" ]]; then
|
|
||||||
err "Please run this script as your normal user (it will call sudo itself), not directly as root."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
backup_file() {
|
|
||||||
local f="$1"
|
|
||||||
if [[ -f "$f" && ! -f "${f}.bak-gamescope-wizard" ]]; then
|
|
||||||
sudo cp -a "$f" "${f}.bak-gamescope-wizard"
|
|
||||||
info "Backed up $f -> ${f}.bak-gamescope-wizard"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
create_desktop_shortcut() {
|
|
||||||
# Determine the home directory of the target user
|
|
||||||
local user_home
|
|
||||||
user_home=$(eval echo "~$TARGET_USER")
|
|
||||||
|
|
||||||
# Locate the correct Desktop directory
|
|
||||||
local desktop_dir
|
|
||||||
if [[ -f "$user_home/.config/user-dirs.dirs" ]]; then
|
|
||||||
desktop_dir=$(grep '^XDG_DESKTOP_DIR=' "$user_home/.config/user-dirs.dirs" | cut -d '"' -f 2)
|
|
||||||
desktop_dir="${desktop_dir/\$HOME/$user_home}"
|
|
||||||
fi
|
|
||||||
desktop_dir="${desktop_dir:-$user_home/Desktop}"
|
|
||||||
|
|
||||||
# Ensure secure icon path and desktop directories exist
|
|
||||||
local secure_icon_dir="$user_home/.local/share/icons/hicolor/scalable/apps"
|
|
||||||
mkdir -p "$secure_icon_dir"
|
|
||||||
mkdir -p "$desktop_dir"
|
|
||||||
|
|
||||||
# 1. Safely copy the icon to the user's permanent theme directory
|
|
||||||
local script_dir
|
|
||||||
script_dir="$(cd "$(dirname "${BASH_SOURCE}")" && pwd)"
|
|
||||||
|
|
||||||
if [[ -f "$script_dir/icons/steamdeck-gaming-return.svg" ]]; then
|
|
||||||
info "Copying icon asset to permanent system theme path..."
|
|
||||||
cp "$script_dir/icons/steamdeck-gaming-return.svg" "$secure_icon_dir/steamdeck-gaming-return.svg"
|
|
||||||
chown "$TARGET_USER:$TARGET_USER" "$secure_icon_dir/steamdeck-gaming-return.svg"
|
|
||||||
else
|
|
||||||
warn "Icon asset not found at $script_dir/icons/steamdeck-gaming-return.svg - Shortcut will use fallback fallback."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. Generate the .desktop shortcut with instant session switcher strings
|
|
||||||
local shortcut_path="$desktop_dir/Return to Gaming Mode.desktop"
|
|
||||||
info "Creating 'Return to Gaming Mode' desktop shortcut at: $shortcut_path"
|
|
||||||
|
|
||||||
cat << EOF > "$shortcut_path"
|
|
||||||
[Desktop Entry]
|
|
||||||
Name=Return to Gaming Mode
|
|
||||||
Comment=Switch session back to Gamescope
|
|
||||||
Exec=steamos-session-select gamescope && sudo systemctl start sync-steamos-session.service && sudo systemctl restart plasmalogin
|
|
||||||
Icon=steamdeck-gaming-return
|
|
||||||
Terminal=false
|
|
||||||
Type=Application
|
|
||||||
Categories=System;
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Fix permissions for the target user and KDE Plasma desktop ecosystem
|
|
||||||
chmod +x "$shortcut_path"
|
|
||||||
chown "$TARGET_USER:$TARGET_USER" "$shortcut_path"
|
|
||||||
|
|
||||||
# Refresh the system icon cache so Plasma detects the standalone asset immediately
|
|
||||||
gtk-update-icon-cache -f -t "$user_home/.local/share/icons/hicolor" 2>/dev/null || true
|
|
||||||
|
|
||||||
ok "Desktop shortcut created successfully."
|
|
||||||
}
|
|
||||||
|
|
||||||
install_vapor_theme() {
|
|
||||||
# Installs Valve's official SteamOS "Vapor" Plasma theme (color scheme,
|
|
||||||
# Plasma look-and-feel package, wallpapers, icons) straight from Valve's
|
|
||||||
# own SteamOS package mirror, into the current user's ~/.local/share.
|
|
||||||
# This only touches the invoking user's home directory, never system
|
|
||||||
# files, so it's independent from everything else this script does.
|
|
||||||
local pkg_ver="0.29"
|
|
||||||
local domain="https://steamdeck-packages.steamos.cloud"
|
|
||||||
local path_dir="archlinux-mirror/jupiter-main/os/x86_64"
|
|
||||||
local file_name="steamdeck-kde-presets-${pkg_ver}-1-any.pkg.tar.zst"
|
|
||||||
local url="${domain}/${path_dir}/${file_name}"
|
|
||||||
local tmp_dir
|
|
||||||
tmp_dir="$(mktemp -d)"
|
|
||||||
|
|
||||||
info "Downloading official SteamOS Vapor presets (v${pkg_ver})..."
|
|
||||||
if ! curl -fL "$url" -o "${tmp_dir}/presets.tar.zst"; then
|
|
||||||
err "Download failed. Valve may have moved/renamed this package;"
|
|
||||||
err "check ${domain} for the current version and update pkg_ver in the script."
|
|
||||||
rm -rf "$tmp_dir"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
info "Extracting package contents..."
|
|
||||||
if ! tar -I unzstd -xf "${tmp_dir}/presets.tar.zst" -C "$tmp_dir"; then
|
|
||||||
err "Extraction failed (is 'zstd' installed? try: sudo pacman -S --needed zstd)"
|
|
||||||
rm -rf "$tmp_dir"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
info "Creating local configuration directories..."
|
|
||||||
mkdir -p ~/.local/share/color-schemes ~/.local/share/plasma/desktoptheme ~/.local/share/plasma/look-and-feel ~/.local/share/wallpapers ~/.local/share/icons/hicolor/scalable/apps ~/.local/share/icons/hicolor/48x48/apps
|
|
||||||
|
|
||||||
info "Installing Steam Deck theme assets..."
|
|
||||||
[[ -d "${tmp_dir}/usr/share/color-schemes" ]] && cp -r "${tmp_dir}/usr/share/color-schemes/"* ~/.local/share/color-schemes/
|
|
||||||
[[ -d "${tmp_dir}/usr/share/plasma/desktoptheme/Vapor" ]] && cp -r "${tmp_dir}/usr/share/plasma/desktoptheme/Vapor" ~/.local/share/plasma/desktoptheme/
|
|
||||||
[[ -d "${tmp_dir}/usr/share/plasma/look-and-feel/com.valve.vapor.desktop" ]] && cp -r "${tmp_dir}/usr/share/plasma/look-and-feel/com.valve.vapor.desktop" ~/.local/share/look-and-feel/
|
|
||||||
[[ -d "${tmp_dir}/usr/share/wallpapers" ]] && cp -r "${tmp_dir}/usr/share/wallpapers/"* ~/.local/share/wallpapers/
|
|
||||||
[[ -d "${tmp_dir}/usr/share/icons/hicolor" ]] && cp -r "${tmp_dir}/usr/share/icons/hicolor/"* ~/.local/share/icons/hicolor/
|
|
||||||
|
|
||||||
if [[ -d "./icons" ]]; then
|
|
||||||
info "Copying local Steam Deck logo assets from ./icons into structured icon paths..."
|
|
||||||
cp -r ./icons/* ~/.local/share/icons/hicolor/scalable/apps/ 2>/dev/null || true
|
|
||||||
cp -r ./icons/* ~/.local/share/icons/hicolor/48x48/apps/ 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
local metadata_dir="$HOME/.local/share/plasma/look-and-feel/com.valve.vapor.desktop"
|
|
||||||
if [[ -d "$metadata_dir" ]]; then
|
|
||||||
info "Patching look-and-feel metadata for Plasma 6 compatibility..."
|
|
||||||
mkdir -p "$metadata_dir/contents"
|
|
||||||
echo '{"KPlugin": {"Id": "com.valve.vapor.desktop", "Name": "Vapor (Steam Deck)", "ServiceTypes": ["Plasma/LookAndFeel"]}}' > "$metadata_dir/metadata.json"
|
|
||||||
fi
|
|
||||||
|
|
||||||
info "Cleaning up temporary files..."
|
|
||||||
rm -rf "$tmp_dir"
|
|
||||||
|
|
||||||
# Installs Valve's official SteamOS "Vapor" Plasma theme automatically
|
|
||||||
# from the AUR without requiring user interactions or prompts.
|
|
||||||
info "Installing official SteamOS Vapor theme via yay (non-interactive)..."
|
|
||||||
|
|
||||||
if ! yay -S --noconfirm --needed --answerclean None --answerdiff None --answeredit None plasma6-themes-vapor-steamos; then
|
|
||||||
err "Failed to install plasma6-themes-vapor-steamos package from the AUR."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ---------- Integrated: Update Launcher Icon ----------
|
|
||||||
local icon_name="steamdeck-gaming-return"
|
|
||||||
local conf_file="$HOME/.config/plasma-org.kde.plasma.desktop-appletsrc"
|
|
||||||
|
|
||||||
if ! find ~/.local/share/icons /usr/share/icons -iname "${icon_name}.*" 2>/dev/null | grep -q .; then
|
|
||||||
warn "Could not find '${icon_name}' installed anywhere under ~/.local/share/icons or /usr/share/icons."
|
|
||||||
warn "The launcher icon will be set anyway, but it may show as a broken icon until the file is installed."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -f "$conf_file" ]]; then
|
|
||||||
info "Looking for the Application Launcher applet (Kickoff/Kicker) to set the custom icon..."
|
|
||||||
local matches=()
|
|
||||||
local current_section=""
|
|
||||||
local current_containment=""
|
|
||||||
local current_applet=""
|
|
||||||
|
|
||||||
while IFS= read -r line; do
|
|
||||||
if [[ "$line" =~ ^\[Containments\]\[([0-9]+)\]\[Applets\]\[([0-9]+)\]$ ]]; then
|
|
||||||
current_containment="${BASH_REMATCH[1]}"
|
|
||||||
current_applet="${BASH_REMATCH[2]}"
|
|
||||||
current_section="applet_root"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if [[ "$line" =~ ^\[ ]]; then
|
|
||||||
current_section=""
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if [[ "$current_section" == "applet_root" && "$line" =~ ^plugin=(org\.kde\.plasma\.(kickoff|kicker|simplemenu|homerun|application-menu))$ ]]; then
|
|
||||||
matches+=( "${current_containment}:${current_applet}:${BASH_REMATCH[1]}" )
|
|
||||||
current_section=""
|
|
||||||
fi
|
|
||||||
done < "$conf_file"
|
|
||||||
|
|
||||||
if [[ ${#matches[@]} -gt 0 ]]; then
|
|
||||||
for m in "${matches[@]}"; do
|
|
||||||
IFS=':' read -r containment applet plugin <<< "$m"
|
|
||||||
info "Setting launcher icon on Containment $containment / Applet $applet ($plugin)..."
|
|
||||||
kwriteconfig6 \
|
|
||||||
--file "$conf_file" \
|
|
||||||
--group Containments --group "$containment" \
|
|
||||||
--group Applets --group "$applet" \
|
|
||||||
--group Configuration --group General \
|
|
||||||
--key icon "$icon_name"
|
|
||||||
ok "Icon set to '$icon_name'."
|
|
||||||
done
|
|
||||||
else
|
|
||||||
warn "No compatible Application Launcher applet found in panel config. Skipping icon assignment."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
warn "$conf_file not found. Skipping menu icon configuration."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ---------- Integrated: Set Default Vapor Wallpaper (Fixed for Plasma 6) ----------
|
|
||||||
local wallpaper_path="$HOME/.local/share/wallpapers/Vapor/contents/images/2560x1600.png"
|
|
||||||
|
|
||||||
if [[ ! -f "$wallpaper_path" ]]; then
|
|
||||||
wallpaper_path=$(find "$HOME/.local/share/wallpapers/Vapor/contents/images" -type f \( -name "*.png" -o -name "*.jpg" \) | head -n 1)
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -f "$wallpaper_path" ]]; then
|
|
||||||
info "Applying official Steam Deck Vapor wallpaper via D-Bus script..."
|
|
||||||
local dbus_cmd="
|
|
||||||
var allDesktops = desktops();
|
|
||||||
for (var i = 0; i < allDesktops.length; i++) {
|
|
||||||
var d = allDesktops[i];
|
|
||||||
d.currentConfigGroup = ['Wallpaper', 'org.kde.image', 'General'];
|
|
||||||
d.writeConfig('Image', 'file://${wallpaper_path}');
|
|
||||||
}
|
|
||||||
"
|
|
||||||
if command -v qdbus6 >/dev/null 2>&1; then
|
|
||||||
qdbus6 org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "$dbus_cmd" >/dev/null 2>&1 || true
|
|
||||||
else
|
|
||||||
qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "$dbus_cmd" >/dev/null 2>&1 || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -f "$conf_file" ]]; then
|
|
||||||
local desktop_sections=$(grep -E '^\[Containments\]\[[0-9]+\]$' "$conf_file" || true)
|
|
||||||
while read -r section; do
|
|
||||||
if [[ -n "$section" ]]; then
|
|
||||||
local clean_sec=$(echo "$section" | tr -d '[]')
|
|
||||||
kwriteconfig6 --file "$conf_file" --group "$clean_sec" --group Wallpaper --group org.kde.image --group General --key Image "file://${wallpaper_path}"
|
|
||||||
fi
|
|
||||||
done <<< "$desktop_sections"
|
|
||||||
fi
|
|
||||||
ok "Wallpaper path pushed to session config."
|
|
||||||
else
|
|
||||||
warn "Could not find extracted Vapor wallpaper file. Skipping."
|
|
||||||
fi
|
|
||||||
|
|
||||||
info "Refreshing Plasma environment and icon caches..."
|
|
||||||
gtk-update-icon-cache -f -t ~/.local/share/icons/hicolor 2>/dev/null || true
|
|
||||||
kbuildsycoca6 --noincremental 2>/dev/null || true
|
|
||||||
rm -rf ~/.cache/plasmashell* ~/.cache/org.kde.dirmodel-qml.kcache
|
|
||||||
setsid plasmashell --replace >/dev/null 2>&1 &
|
|
||||||
|
|
||||||
# ---------- Automatisch het Vapor thema activeren ----------
|
|
||||||
# info "Vapor-thema direct toepassen op de huidige desktop..."
|
|
||||||
|
|
||||||
# Activeer het globale Plasma look-and-feel thema
|
|
||||||
if command -v lookandfeeltool >/dev/null 2>&1; then
|
|
||||||
lookandfeeltool -a com.valve.vapor.desktop || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Zorg dat de iconen en kleurschema's expliciet naar Vapor overschakelen
|
|
||||||
kwriteconfig6 --file kdeglobals --group Icons --key Theme "Vapor"
|
|
||||||
kwriteconfig6 --file kdeglobals --group General --key ColorScheme "Vapor"
|
|
||||||
|
|
||||||
# Forceer Plasma om de nieuwe instellingen direct in te laden
|
|
||||||
qdbus6 org.kde.KWin /KWin org.kde.KWin.reconfigure >/dev/null 2>&1 || true
|
|
||||||
|
|
||||||
ok "Vapor theme assets installed. Apply it under System Settings > Appearance"
|
|
||||||
ok "> Global Theme > Vapor (Steam Deck), next time you're in a Plasma session."
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
detect_valve_fremont() {
|
|
||||||
# Valve Steam Machine / BC-250-class boards report these DMI strings.
|
|
||||||
# Standard desktop kernels (including CachyOS's) lack the leds-valve
|
|
||||||
# driver, so the front LED bar just goes dark or breathes on idle.
|
|
||||||
local vendor product
|
|
||||||
vendor="$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null || true)"
|
|
||||||
product="$(cat /sys/class/dmi/id/product_name 2>/dev/null || true)"
|
|
||||||
[[ "$vendor" == "Valve" && "$product" == "Fremont" ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
aur_noninteractive_flags() {
|
|
||||||
# Fully non-interactive install flags for the given AUR helper: no
|
|
||||||
# PKGBUILD diff/edit/cleanbuild prompts, no provider-selection prompts
|
|
||||||
# (e.g. picking kernel headers for DKMS), and makepkg itself silenced.
|
|
||||||
case "$1" in
|
|
||||||
yay)
|
|
||||||
echo --needed --noconfirm --answerclean None --answerdiff None \
|
|
||||||
--answeredit None --mflags "--noconfirm"
|
|
||||||
;;
|
|
||||||
paru)
|
|
||||||
echo --needed --noconfirm --skipreview --mflags "--noconfirm"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
bootstrap_yay() {
|
|
||||||
# Builds and installs yay from the AUR using only makepkg + base-devel
|
|
||||||
# (both from the official repos), so we have an AUR helper available
|
|
||||||
# without assuming the user already set one up.
|
|
||||||
info "Installing base-devel and git (needed to build an AUR helper)..."
|
|
||||||
sudo pacman -S --needed --noconfirm base-devel git || return 1
|
|
||||||
|
|
||||||
local tmp_dir
|
|
||||||
tmp_dir="$(mktemp -d)"
|
|
||||||
info "Cloning yay-bin from the AUR..."
|
|
||||||
if ! git clone --depth 1 https://aur.archlinux.org/yay-bin.git "$tmp_dir/yay-bin"; then
|
|
||||||
err "Failed to clone yay-bin from the AUR."
|
|
||||||
rm -rf "$tmp_dir"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
info "Building and installing yay (this runs makepkg as your user, not root)..."
|
|
||||||
if (cd "$tmp_dir/yay-bin" && makepkg -si --noconfirm); then
|
|
||||||
ok "yay installed."
|
|
||||||
rm -rf "$tmp_dir"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
err "Building yay failed. See errors above."
|
|
||||||
rm -rf "$tmp_dir"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
install_valve_led_driver() {
|
|
||||||
# Installs the leds-valve DKMS driver from the AUR so the front LED
|
|
||||||
# bar is exposed under /sys/class/leds, then offers the two known
|
|
||||||
# ways to get Steam to actually drive it (gamepadui, which this
|
|
||||||
# script already forces via STEAM_GAMEPADUI_ARGS, or OpenRGB's
|
|
||||||
# experimental build which has native support for the panel).
|
|
||||||
# Assumes an AUR helper was already ensured back in step 2.
|
|
||||||
local aur_helper=""
|
|
||||||
if command -v yay >/dev/null 2>&1; then
|
|
||||||
aur_helper="yay"
|
|
||||||
elif command -v paru >/dev/null 2>&1; then
|
|
||||||
aur_helper="paru"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "$aur_helper" ]]; then
|
|
||||||
warn "No AUR helper available - can't install leds-valve-dkms-git."
|
|
||||||
warn "Install one yourself, then run: yay -S leds-valve-dkms-git"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! pacman -Qi leds-valve-dkms-git >/dev/null 2>&1; then
|
|
||||||
info "Installing leds-valve-dkms-git from the AUR via $aur_helper (non-interactive)..."
|
|
||||||
local -a flags
|
|
||||||
read -ra flags <<< "$(aur_noninteractive_flags "$aur_helper")"
|
|
||||||
"$aur_helper" -S "${flags[@]}" leds-valve-dkms-git
|
|
||||||
else
|
|
||||||
ok "leds-valve-dkms-git already installed."
|
|
||||||
fi
|
|
||||||
|
|
||||||
info "Loading the leds-valve kernel module..."
|
|
||||||
if sudo modprobe leds-valve 2>/dev/null; then
|
|
||||||
ok "Module loaded."
|
|
||||||
else
|
|
||||||
warn "modprobe leds-valve failed - a reboot is often needed to pick up a freshly built DKMS module."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ls /sys/class/leds/ 2>/dev/null | grep -qi valve; then
|
|
||||||
ok "LED bar nodes detected: $(ls /sys/class/leds/ | grep -i valve | tr '\n' ' ')"
|
|
||||||
else
|
|
||||||
warn "No valve-led nodes under /sys/class/leds/ yet. Reboot, then check with:"
|
|
||||||
warn " ls /sys/class/leds/ | grep -i valve"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
info "Steam only pushes download progress to the LED bar in real SteamOS Game Mode."
|
|
||||||
# info "On a desktop install you have two options:"
|
|
||||||
# info " 1) Launch Steam's Big Picture UI (this script's -gamepadui -steamos3 flag already covers this)"
|
|
||||||
# info " 2) Install an experimental/git OpenRGB build from the AUR, which natively detects this panel"
|
|
||||||
# if ask_yn "Also install the experimental OpenRGB build from the AUR now?" n; then
|
|
||||||
local -a flags
|
|
||||||
read -ra flags <<< "$(aur_noninteractive_flags "$aur_helper")"
|
|
||||||
"$aur_helper" -S "${flags[@]}" openrgb-git
|
|
||||||
# ok "openrgb-git installed. Launch OpenRGB to detect and configure the front panel."
|
|
||||||
# fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# ---------- start ----------
|
|
||||||
|
|
||||||
require_root_helper
|
require_root_helper
|
||||||
|
|
||||||
@@ -431,6 +58,11 @@ if ! command -v pacman >/dev/null 2>&1; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Ask for the sudo password once up front and keep it fresh, instead of
|
||||||
|
# prompting at random points during the run.
|
||||||
|
sudo -n true 2>/dev/null || sudo -v || exit 1
|
||||||
|
while true; do sudo -n true; sleep 50; kill -0 "$$" 2>/dev/null || exit; done 2>/dev/null &
|
||||||
|
|
||||||
TARGET_USER="${SUDO_USER:-$USER}"
|
TARGET_USER="${SUDO_USER:-$USER}"
|
||||||
read -rp "$(echo -e "${c_bold}Which user should autologin into gamescope?${c_reset} [${TARGET_USER}] ")" input_user
|
read -rp "$(echo -e "${c_bold}Which user should autologin into gamescope?${c_reset} [${TARGET_USER}] ")" input_user
|
||||||
TARGET_USER="${input_user:-$TARGET_USER}"
|
TARGET_USER="${input_user:-$TARGET_USER}"
|
||||||
@@ -439,247 +71,40 @@ if ! id "$TARGET_USER" >/dev/null 2>&1; then
|
|||||||
err "User '$TARGET_USER' does not exist on this system."
|
err "User '$TARGET_USER' does not exist on this system."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if [[ "$TARGET_USER" != "$(id -un)" ]]; then
|
||||||
|
# Environment, systemd user units, theme and shortcut are all written
|
||||||
|
# into the invoking user's home and user session.
|
||||||
|
err "Run this script as '$TARGET_USER' itself so per-user settings land in the right home."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
ok "Using user: $TARGET_USER"
|
ok "Using user: $TARGET_USER"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# ---------- 1. Login manager check ----------
|
check_display_manager
|
||||||
|
|
||||||
DM="$(systemctl show -p Id --value display-manager 2>/dev/null | sed 's/\.service$//')"
|
|
||||||
info "Detected display manager: ${DM:-none}"
|
|
||||||
|
|
||||||
if [[ "$DM" != "plasmalogin" ]]; then
|
|
||||||
warn "This wizard was built and tested against plasma-login-manager (plasmalogin)."
|
|
||||||
warn "Detected display manager is '${DM:-unknown}'. SDDM setups don't need"
|
|
||||||
warn "most of these workarounds (SDDM's own Autologin works out of the box);"
|
|
||||||
warn "this script will still try, but review the output carefully."
|
|
||||||
ask_yn "Continue anyway?" n || exit 0
|
|
||||||
fi
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# ---------- 2. Install packages (Always Runs) ----------
|
install_required_packages
|
||||||
|
|
||||||
info "Checking required packages: gamescope-session-cachyos, steam, mangohud, xterm, ttf-liberation, wqy-zenhei, plasma-keyboard"
|
|
||||||
MISSING=()
|
|
||||||
for pkg in gamescope-session-cachyos steam mangohud xterm ttf-liberation wqy-zenhei plasma-keyboard; do
|
|
||||||
pacman -Qi "$pkg" >/dev/null 2>&1 || MISSING+=("$pkg")
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ ${#MISSING[@]} -gt 0 ]]; then
|
|
||||||
info "Missing packages: ${MISSING[*]}"
|
|
||||||
if ask_yn "Install them now?"; then
|
|
||||||
sudo pacman -S --needed "${MISSING[@]}"
|
|
||||||
else
|
|
||||||
err "Cannot continue without these packages."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
ok "All required packages already installed."
|
|
||||||
fi
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
if detect_valve_fremont; then
|
configure_autologin
|
||||||
info "Detected Valve Fremont hardware - checking for an AUR helper (needed for leds-valve-dkms-git)"
|
install_session_sync
|
||||||
if command -v yay >/dev/null 2>&1 || command -v paru >/dev/null 2>&1; then
|
|
||||||
ok "AUR helper already present."
|
|
||||||
else
|
|
||||||
info "No AUR helper (yay/paru) found. Installing yay..."
|
|
||||||
bootstrap_yay || warn "Couldn't set up an AUR helper automatically. You can install one yourself later and run: yay -S leds-valve-dkms-git"
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ---------- 3. Ensure plasmalogin.conf.d exists (fixes Switch-to-Desktop crash) ----------
|
setup_steam_desktop
|
||||||
|
|
||||||
info "Ensuring /etc/plasmalogin.conf.d exists (fixes the 'Switching to Desktop' hang bug)"
|
|
||||||
sudo mkdir -p /etc/plasmalogin.conf.d
|
|
||||||
ok "Directory present."
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# ---------- 4. Fix the base /etc/plasmalogin.conf ----------
|
setup_led_driver
|
||||||
|
|
||||||
BASE_CONF="/etc/plasmalogin.conf"
|
setup_vapor_theme
|
||||||
info "Configuring $BASE_CONF (Session=gamescope-session.desktop, User=$TARGET_USER, Relogin=true)"
|
|
||||||
backup_file "$BASE_CONF"
|
|
||||||
|
|
||||||
sudo touch "$BASE_CONF"
|
|
||||||
|
|
||||||
sudo awk '
|
|
||||||
BEGIN { in_autologin=0 }
|
|
||||||
/^\[Autologin\]/ { in_autologin=1; next }
|
|
||||||
/^\[/ { in_autologin=0 }
|
|
||||||
!in_autologin { print }
|
|
||||||
' "$BASE_CONF" | sudo tee "${BASE_CONF}.tmp" > /dev/null
|
|
||||||
|
|
||||||
sudo mv "${BASE_CONF}.tmp" "$BASE_CONF"
|
|
||||||
|
|
||||||
sudo tee -a "$BASE_CONF" > /dev/null << EOF
|
|
||||||
[Autologin]
|
|
||||||
Session=gamescope-session.desktop
|
|
||||||
User=$TARGET_USER
|
|
||||||
Relogin=true
|
|
||||||
EOF
|
|
||||||
|
|
||||||
ok "Base autologin config written:"
|
|
||||||
sudo sed -n '/\[Autologin\]/,/^\[/p' "$BASE_CONF" | head -n -1 2>/dev/null || sudo cat "$BASE_CONF"
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# ---------- 5. Clean up any stray conf.d autologin fragments from manual attempts ----------
|
|
||||||
|
|
||||||
info "Removing any leftover manual conf.d autologin overrides (base config now handles it)"
|
|
||||||
sudo rm -f /etc/plasmalogin.conf.d/zzz-steamos-autologin*.conf
|
|
||||||
ok "Cleaned."
|
|
||||||
echo
|
|
||||||
|
|
||||||
# ---------- 6. Install the sync bridge: conf.d -> base config ----------
|
|
||||||
|
|
||||||
SYNC_SCRIPT="/usr/local/bin/sync-steamos-session.sh"
|
|
||||||
info "Installing session sync bridge at $SYNC_SCRIPT"
|
|
||||||
|
|
||||||
sudo tee "$SYNC_SCRIPT" > /dev/null << 'EOF'
|
|
||||||
#!/bin/bash
|
|
||||||
SRC="/etc/plasmalogin.conf.d/zz-steamos-autologin.conf"
|
|
||||||
DEST="/etc/plasmalogin.conf"
|
|
||||||
|
|
||||||
[[ -f "$SRC" ]] || exit 0
|
|
||||||
SESSION=$(grep -oP '^Session=\K.*' "$SRC")
|
|
||||||
[[ -z "$SESSION" ]] && exit 0
|
|
||||||
|
|
||||||
if grep -q '^Session=' "$DEST"; then
|
|
||||||
sed -i "s|^Session=.*|Session=$SESSION|" "$DEST"
|
|
||||||
else
|
|
||||||
echo "Session=$SESSION" >> "$DEST"
|
|
||||||
fi
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sudo chmod +x "$SYNC_SCRIPT"
|
|
||||||
ok "Sync script installed."
|
|
||||||
echo
|
|
||||||
|
|
||||||
# ---------- 7. systemd path watcher + service ----------
|
|
||||||
|
|
||||||
info "Installing systemd path watcher so session switches take effect immediately"
|
|
||||||
|
|
||||||
sudo tee /etc/systemd/system/sync-steamos-session.path > /dev/null << 'EOF'
|
|
||||||
[Unit]
|
|
||||||
Description=Watch for steamos session changes
|
|
||||||
|
|
||||||
[Path]
|
|
||||||
PathModified=/etc/plasmalogin.conf.d/zz-steamos-autologin.conf
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sudo tee /etc/systemd/system/sync-steamos-session.service > /dev/null << 'EOF'
|
|
||||||
[Unit]
|
|
||||||
Description=Sync steamos session selection into plasmalogin.conf
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart=/usr/local/bin/sync-steamos-session.sh
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
sudo systemctl enable --now sync-steamos-session.path
|
|
||||||
ok "Path watcher enabled."
|
|
||||||
echo
|
|
||||||
|
|
||||||
# ---------- 8. Run it once now so current state is in sync ----------
|
|
||||||
|
|
||||||
info "Running the sync once now to align current state"
|
|
||||||
sudo systemctl start sync-steamos-session.service
|
|
||||||
ok "Done. Current base config:"
|
|
||||||
sudo cat "$BASE_CONF"
|
|
||||||
echo
|
|
||||||
|
|
||||||
|
|
||||||
# ---------- 8b. Core SteamOS Keyboard & Glyphs Fix (Always runs) ----------
|
|
||||||
|
|
||||||
info "Applying non-optional SteamOS environment & keyboard fixes..."
|
|
||||||
steam_env_dir="$HOME/.config/environment.d"
|
|
||||||
mkdir -p "$steam_env_dir"
|
|
||||||
|
|
||||||
# 1. Force Gamescope Steam to boot into Deck mode and load Deck glyphs
|
|
||||||
echo "STEAM_GAMEPADUI_ARGS=\"-gamepadui -steamos3\"" > "$steam_env_dir/99-gamescope-steam-glyphs.conf"
|
|
||||||
if [[ -d "$HOME/.config/gamescope-session" ]]; then
|
|
||||||
echo "STEAM_GAMEPADUI_ARGS=\"-gamepadui -steamos3\"" >> "$HOME/.config/gamescope-session/environment"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. Prevent KDE Wayland from blocking the virtual keyboard overlay
|
|
||||||
echo "KWIN_IM_SHOW_ALWAYS=1" > "$steam_env_dir/99-kde-virtual-keyboard.conf"
|
|
||||||
|
|
||||||
# 3. Setup robust background systemd service for Steam autostart on Desktop Mode
|
|
||||||
systemd_user_dir="$HOME/.config/systemd/user"
|
|
||||||
mkdir -p "$systemd_user_dir"
|
|
||||||
|
|
||||||
cat << 'EOF' > "$systemd_user_dir/steam-desktop-autostart.service"
|
|
||||||
[Unit]
|
|
||||||
Description=Steam Background Autostart for Virtual Keyboard
|
|
||||||
After=graphical-session.target
|
|
||||||
PartOf=graphical-session.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
ExecStart=/usr/bin/steam -silent
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=graphical-session.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Clean out old .desktop shortcut so they don't fight
|
|
||||||
rm -f "$HOME/.config/autostart/steam.desktop"
|
|
||||||
|
|
||||||
# Reload user systemd context and activate the background loop
|
|
||||||
systemctl --user daemon-reload
|
|
||||||
systemctl --user enable steam-desktop-autostart.service
|
|
||||||
systemctl --user start steam-desktop-autostart.service
|
|
||||||
|
|
||||||
ok "Steam UI parameters and keyboard autostart deployed successfully."
|
|
||||||
echo
|
|
||||||
|
|
||||||
|
|
||||||
# ---------- 8c. Valve Fremont hardware: front LED bar driver ----------
|
|
||||||
|
|
||||||
# if detect_valve_fremont; then
|
|
||||||
# echo
|
|
||||||
# info "Detected Valve Fremont hardware (Steam Machine / BC-250-class board)."
|
|
||||||
# if ask_yn "Set up the front-panel LED bar driver (leds-valve) so it isn't stuck dark/breathing?" y; then
|
|
||||||
# install_valve_led_driver || warn "LED driver setup ran into a problem - see errors above. Your gamescope boot setup above is unaffected."
|
|
||||||
# fi
|
|
||||||
# echo
|
|
||||||
# fi
|
|
||||||
|
|
||||||
|
|
||||||
# ---------- 9. Optional: Vapor (Steam Deck) KDE theme ----------
|
|
||||||
|
|
||||||
echo
|
|
||||||
if ask_yn "Also install Valve's official Vapor (Steam Deck) KDE theme for your desktop session?" n; then
|
|
||||||
if ! command -v curl >/dev/null 2>&1; then
|
|
||||||
warn "curl not found, installing it first..."
|
|
||||||
sudo pacman -S --needed curl
|
|
||||||
fi
|
|
||||||
if ! command -v unzstd >/dev/null 2>&1; then
|
|
||||||
warn "zstd not found, installing it first..."
|
|
||||||
sudo pacman -S --needed zstd
|
|
||||||
fi
|
|
||||||
install_vapor_theme || warn "Vapor theme install ran into a problem - see errors above. Your gamescope boot setup above is unaffected."
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
|
|
||||||
|
|
||||||
# ---------- 10. Create Return to Gaming Mode Desktop Shortcut ----------
|
|
||||||
|
|
||||||
create_desktop_shortcut
|
create_desktop_shortcut
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
|
||||||
# ---------- 11. Summary + reboot ----------
|
# ---------- 11. Summary + reboot ----------
|
||||||
|
|
||||||
echo -e "${c_bold}Setup complete.${c_reset}"
|
echo -e "${c_bold}Setup complete.${c_reset}"
|
||||||
echo "What this did:"
|
echo "What this did:"
|
||||||
echo " - Installed gamescope-session-cachyos, steam, mangohud (if missing)"
|
echo " - Installed gamescope-session-cachyos, steam, mangohud and friends (if missing)"
|
||||||
echo " - Created /etc/plasmalogin.conf.d (fixes Switch-to-Desktop crash)"
|
echo " - Created /etc/plasmalogin.conf.d (fixes Switch-to-Desktop crash)"
|
||||||
echo " - Set $BASE_CONF to autologin '$TARGET_USER' into gamescope, with Relogin=true"
|
echo " - Set $BASE_CONF to autologin '$TARGET_USER' into gamescope, with Relogin=true"
|
||||||
echo " - Installed a sync bridge + systemd watcher so Steam's Switch-to-Desktop"
|
echo " - Installed a sync bridge + systemd watcher so Steam's Switch-to-Desktop"
|
||||||
@@ -689,6 +114,7 @@ echo " - Configured permanent silent Steam autostart so Steam+X works everywher
|
|||||||
echo " - Injected -steamos3 flag to force original Steam Deck overlay glyphs"
|
echo " - Injected -steamos3 flag to force original Steam Deck overlay glyphs"
|
||||||
echo " - Optionally installed Valve's Vapor (Steam Deck) KDE theme, if you chose to"
|
echo " - Optionally installed Valve's Vapor (Steam Deck) KDE theme, if you chose to"
|
||||||
echo " - On Valve Fremont hardware, optionally set up the leds-valve front LED bar driver"
|
echo " - On Valve Fremont hardware, optionally set up the leds-valve front LED bar driver"
|
||||||
|
echo " - Added /etc/sudoers.d/gamescope-session-switch so the desktop shortcut works"
|
||||||
echo
|
echo
|
||||||
echo "Backups of any files this script modified were saved with a"
|
echo "Backups of any files this script modified were saved with a"
|
||||||
echo ".bak-gamescope-wizard suffix next to the original."
|
echo ".bak-gamescope-wizard suffix next to the original."
|
||||||
|
|||||||
Reference in new issue
Block a user