feat: "Gaming on NVIDIA" replaces the SteamOS conversion on NVIDIA PCs

gamescope's gaming mode shows a corrupted picture on NVIDIA (NVIDIA bug 5240452), also nested in KDE and in a KWin-only
session. With an NVIDIA GPU the conversion (gaming, boot, single, glyphs) is hidden unless already on, and nvidia takes its
place: Steam installed when missing and started at login on the Plasma desktop (user unit), with the sub-option bigpicture
for Big Picture or the normal window. The kernel parameters and early NVIDIA modules (RTX 20 series or newer) are kept as
part of it. tests/nvidia-test.sh covers the component and the menu rules against a fake GPU.
This commit is contained in:
theupriser committed 2026-10-01 19:04:58 +02:00
1 parent 76cf1b4adb
commit 948dc1f587
13 files changed
+281 -88

No files matched your search

+5 -7
View File
@@ -48,13 +48,11 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
`<id>_available` is checked via `component_available` (e.g. `machine` `<id>_available` is checked via `component_available` (e.g. `machine`
only on Fremont). Turn-on order is `COMPONENTS` order, turn-off reverse; only on Fremont). Turn-on order is `COMPONENTS` order, turn-off reverse;
`gaming` must stay first. Dependencies live in `toggle_component`. `gaming` must stay first. Dependencies live in `toggle_component`.
- **Hardware-specific fixes** that belong to a component but aren't a menu - **NVIDIA** (`lib/nvidia.sh`): gamescope's session is broken on NVIDIA, so the SteamOS conversion (`gaming`, `boot`, `single`,
row (e.g. `lib/nvidia.sh`: NVIDIA's kernel parameters and early modules `glyphs`) is hidden there (unless already on) and `nvidia` + its sub-option `bigpicture` ("Gaming on NVIDIA") replace it:
for gaming mode, called from `gaming_enable`/`gaming_disable`) detect the Steam on the Plasma desktop, started at login. Never reintroduce a gamescope session for NVIDIA without re-testing on the
hardware themselves, change only what's missing, and undo it on disable. hardware (notes: steamify-cachyos-dev, `nvidia/`). It can't be tested without the hardware: keep the branch behind
Add them to the source loop in `steamify.sh` and the table in `.no-release-yet` until it was.
`TECHNICAL.md`. They can't be tested without the hardware: say so in the
changelog and keep the branch behind `.no-release-yet` until it was.
- **Feature versions.** Set `FEATURE_VERSION[<id>]` (`lib/menu.sh`) to the new - **Feature versions.** Set `FEATURE_VERSION[<id>]` (`lib/menu.sh`) to the new
`VERSION` whenever what `<id>_enable` sets up changes (a new component gets `VERSION` whenever what `<id>_enable` sets up changes (a new component gets
one too): installs recorded with an older version one too): installs recorded with an older version
+2 -7
View File
@@ -7,13 +7,8 @@ one per merged pull request.
## 2.9.7 - 2026-10-01 ## 2.9.7 - 2026-10-01
- **feat: the SteamOS conversion fixes a corrupted gaming mode screen with an NVIDIA GPU: nvidia-drm.modeset=1 and fbdev=1 on the kernel command line, NVIDIA modules in the initramfs (lib/nvidia.sh)** - **feat: "Gaming on NVIDIA" (nvidia) replaces the SteamOS conversion on PCs with an NVIDIA GPU, where gamescope's gaming mode shows a corrupted picture (NVIDIA bug 5240452): Steam is installed when missing and starts at login on the Plasma desktop; the sub-option "Steam starts in Big Picture" (bigpicture, ticked along with it) starts it in Big Picture, unticked in its normal window (lib/nvidia.sh, services/steamify-steam-autostart.service). On a supported card (RTX 20 series or newer, chwd's legacy lists like the VRAM booster) it also puts nvidia-drm.modeset=1 and fbdev=1 on the kernel command line (Limine incl. its `+=` line, systemd-boot, GRUB) and the NVIDIA modules in the initramfs while every installed kernel has them (a pacman hook decides at every kernel change). The conversion and its options are hidden there unless already on**
- **test: tests/nvidia-test.sh runs the NVIDIA fix against a fake RTX 5080 beside an iGPU, a stub modinfo and temp copies of the Limine, systemd-boot and GRUB files (no root, VM or hardware); NVIDIA_DRM_DIR points detection at a fake sysfs tree** - **test: tests/nvidia-test.sh runs it against a fake RTX 5080 beside an iGPU, a stub pacman and systemctl, and a temp home (no root, VM or hardware); verified on a real RTX 5080: gamescope's session, a nested gamescope and a KWin-only session all showed artifacts or stutter, Big Picture on the Plasma desktop did not**
- **fix: NVIDIA fix on Limine edits the KERNEL_CMDLINE[default] line (an appended += line ended up as literal text on the kernel command line, found in a VM); the modules are only loaded early when every installed kernel has them, and a Limine boot entry without the parameters is an error**
- **test: tests/nvidia-hardware-test.sh for a real NVIDIA PC: check (read-only state of the detection, the live nvidia_drm modeset/fbdev, versions), apply, and visual (was the gaming mode picture clean), with a report file to paste**
- **fix: the NVIDIA modules are loaded early only while every installed kernel has them, decided again at every kernel or driver change by a pacman hook (steamify-nvidia-initramfs): a later kernel without the modules (another kernel, a failed DKMS build, a downgrade) no longer makes its initramfs and Limine boot entry fail**
- **feat: the NVIDIA fix is only for RTX 20 series or newer, decided like the VRAM booster does (vram_nvidia_legacy_id: chwd's legacy card lists); older cards are left alone**
- **fix: the NVIDIA fix also edits Limine's `KERNEL_CMDLINE[default]+="..."` line (CachyOS writes that form; the fix found no line to edit and stopped) and counts `nvidia_drm.modeset=1` (underscore) as already set; tests/nvidia-hardware-test.sh sets `SCRIPT_DIR` (the hook script was read from `/patches`)**
## 2.9.6 - 2026-09-30 ## 2.9.6 - 2026-09-30
+6
View File
@@ -23,6 +23,12 @@ Steam Machine.
as OS Version (e.g. `steamos-3.9`), `steam-machine` as OS Codename and as OS Version (e.g. `steamos-3.9`), `steam-machine` as OS Codename and
Steamify's version as OS Variant. The OS name stays CachyOS Steamify's version as OS Variant. The OS name stays CachyOS
([details](TECHNICAL.md#what-steams-system-settings-show)). ([details](TECHNICAL.md#what-steams-system-settings-show)).
- **NVIDIA graphics cards:** gamescope's gaming mode shows a corrupted
picture there (an open NVIDIA driver bug), so the conversion isn't
offered. **Gaming on NVIDIA** takes its place: Steam on the desktop,
installed if it's missing and started at login, in **Big Picture** or its
normal window as you choose
([details](TECHNICAL.md#gaming-on-nvidia)).
2. **SteamOS theme** - the Vapor look of SteamOS for the desktop, with 2. **SteamOS theme** - the Vapor look of SteamOS for the desktop, with
**Add to Steam** in right-click menus **Add to Steam** in right-click menus
([details](TECHNICAL.md#steamos-desktop-look)). ([details](TECHNICAL.md#steamos-desktop-look)).
+33 -27
View File
@@ -206,33 +206,39 @@ or upgraded. A newly added kernel doesn't come with its headers, so
`ensure-kernel-headers.service` checks at every boot and installs any `ensure-kernel-headers.service` checks at every boot and installs any
missing `-headers` package, which makes DKMS build the driver for it. missing `-headers` package, which makes DKMS build the driver for it.
## NVIDIA fix for gaming mode ## Gaming on NVIDIA
gamescope drives the display itself through DRM/KMS, which with NVIDIA needs gamescope's own gaming mode shows a corrupted picture on NVIDIA graphics cards: NVIDIA's open bug 5240452 (flicker and
kernel modesetting and the framebuffer driver, and the driver loaded early; artifacts in the DRM session at modes above 2560x1440@120, seen up to driver 595 and on RTX 3070 Ti, 4090, 5090 and 5080;
without them gaming mode can show a corrupted image. With a supported NVIDIA GPU (RTX 20 series or newer, decided like the VRAM no fix known). The kernel parameters `nvidia-drm.modeset=1`/`fbdev=1` and loading the NVIDIA modules early don't change it
booster does: a card on chwd's legacy lists `/var/lib/chwd/ids/nvidia-*.ids` (the driver already reports both `Y`), and gamescope started nested inside KDE artifacts too when KWin hands its fullscreen
is older and left alone, `vram_nvidia_legacy_id`; without those lists every window straight to the display. What does work on an RTX 5080: Steam's Big Picture (`steam -gamepadui`) as a normal window of
card counts) and its driver installed (`lib/nvidia.sh`), the SteamOS conversion adds the Plasma desktop session, smooth and clean.
`nvidia-drm.modeset=1 nvidia-drm.fbdev=1` to the kernel command line (Limine,
systemd-boot or GRUB; the file is backed up first) and So with an NVIDIA GPU (PCI vendor 0x10de, display class, its driver providing `nvidia_drm`: `nvidia_present`) the SteamOS
`/etc/mkinitcpio.conf.d/90-steamify-nvidia.conf` (`MODULES+=(nvidia conversion (`gaming`, and its options `boot`, `single`, `glyphs`) isn't offered, unless it is already on (so it can be turned
nvidia_modeset nvidia_uvm nvidia_drm)`), then rebuilds the initramfs and boot off). `nvidia` ("Gaming on NVIDIA", `lib/nvidia.sh`) takes its place, hidden while the conversion is on (both would start
entries. The early-load drop-in is only there while every installed kernel has the Steam at login): it installs `steam` when missing (recorded in state `nvidia`, removed again only then) and enables the user
NVIDIA modules (mkinitcpio fails on a missing module, and `limine-mkinitcpio` unit `steamify-steam-autostart.service` (`services/`, `ExecStart=/usr/bin/steam @ARGS@`, Plasma only). Its sub-option
then skips that kernel's boot entry, parameters included). That is decided again `bigpicture` ("Steam starts in Big Picture", ticked along with it) rewrites the unit with `-gamepadui`; unticked, Steam
at every kernel or driver change by a pacman hook starts in its normal window. The PC always boots into the desktop: there is no gamescope session. Takes effect at the next
(`/etc/pacman.d/hooks/85-steamify-nvidia-initramfs.hook`, after DKMS builds, login.
before the initramfs is built) running `/usr/local/libexec/steamify-nvidia-initramfs`:
another kernel without the modules, a failed DKMS build or a downgrade removes On a supported card (RTX 20 series or newer: not on chwd's legacy lists `/var/lib/chwd/ids/nvidia-*.ids`, the VRAM booster's
the drop-in, and it comes back once every kernel has them again. check, `vram_nvidia_legacy_id`; `nvidia_supported`) enabling it also does what NVIDIA's DRM stack wants, though it didn't cure
On Limine the parameters go into the existing `KERNEL_CMDLINE[default]="..."` gamescope: `nvidia-drm.modeset=1 nvidia-drm.fbdev=1` on the kernel command line (Limine, systemd-boot or GRUB; the file is
line: an extra appended `+=` line is pasted into the command line as text. backed up first; on Limine into the existing `KERNEL_CMDLINE[default]="..."` or `+="..."` line, never an extra appended line,
Only what's missing is changed; it applies after a reboot. Turning which ends up as text; the kernel treats `nvidia_drm` and `nvidia-drm` alike) and
the conversion off removes both, the hook and its script. `tests/nvidia-test.sh` tests it against a fake GPU `/etc/mkinitcpio.conf.d/90-steamify-nvidia.conf` (`MODULES+=(nvidia nvidia_modeset nvidia_uvm nvidia_drm)`), then the initramfs
and fake boot loader files; `tests/nvidia-hardware-test.sh check|apply|visual` is for a and boot entries are rebuilt and checked for the parameters. The early-load drop-in is only there while every installed kernel
real NVIDIA PC (read-only check, the real apply, and a prompt for whether the picture has the NVIDIA modules (mkinitcpio fails on a missing module, and `limine-mkinitcpio` then skips that kernel's boot entry):
was clean), and writes `~/steamify-nvidia-report.txt`. a pacman hook (`/etc/pacman.d/hooks/85-steamify-nvidia-initramfs.hook`, after DKMS, before the initramfs is built) runs
`/usr/local/libexec/steamify-nvidia-initramfs` at every kernel or driver change and decides again. Turning it off removes
all of it. `tests/nvidia-hardware-test.sh check|apply|visual` is for a real NVIDIA PC (writes `~/steamify-nvidia-report.txt`). `tests/nvidia-test.sh` tests it against a fake GPU, a stub `pacman` and `systemctl`, and a temp home.
Tried and dropped (notes in steamify-cachyos-dev, `nvidia/HARDWARE-RESULTS.md`): a gamescope session that opens Big Picture in Plasma (it needed the `start-gamescope-session`
command shadowed in `/usr/local/bin`, and showed the desktop for a few seconds, then a Steam window with a black border);
a KWin session without Plasma (the mouse stuttered every second or two).
## HDMI-CEC ## HDMI-CEC
@@ -538,7 +544,7 @@ immediately, which can turn into a loop - see
| `lib/steam-game.sh` | Add as non-Steam game: Steamify in the Steam library (`patches/steam-shortcuts.py`) | | `lib/steam-game.sh` | Add as non-Steam game: Steamify in the Steam library (`patches/steam-shortcuts.py`) |
| `lib/update-notifier.sh` | Update notifications: the notifier from `patches/` and its user timer | | `lib/update-notifier.sh` | Update notifications: the notifier from `patches/` and its user timer |
| `lib/first-login.sh` | `--defaults` without a session (the Steam Machine ISO's installer): the one-time first-login step that sets up single user's launcher on Plasma's new layout and opens the app | | `lib/first-login.sh` | `--defaults` without a session (the Steam Machine ISO's installer): the one-time first-login step that sets up single user's launcher on Plasma's new layout and opens the app |
| `lib/nvidia.sh` | NVIDIA fix for gaming mode: kernel parameters and early modules (part of the SteamOS conversion) | | `lib/nvidia.sh` | Gaming on NVIDIA: Steam on the desktop, started at login, optionally in Big Picture (replaces the SteamOS conversion there) |
| `lib/vram-booster.sh` | VRAM booster (`dmemcg-booster`, `plasma-foreground-booster`) | | `lib/vram-booster.sh` | VRAM booster (`dmemcg-booster`, `plasma-foreground-booster`) |
| `services/` | The systemd units the scripts install (`service_file`, `@KEY@` placeholders); see its README | | `services/` | The systemd units the scripts install (`service_file`, `@KEY@` placeholders); see its README |
| `patches/` | Module sources and patches the scripts build or apply (`patch_file`); see its README | | `patches/` | Module sources and patches the scripts build or apply (`patch_file`); see its README |
+2
View File
@@ -148,6 +148,8 @@ backend_apply() {
# The same rules as the menu's toggles. # The same rules as the menu's toggles.
[[ "${WANTED[single]:-0}" == 1 ]] && WANTED[gaming]=1 [[ "${WANTED[single]:-0}" == 1 ]] && WANTED[gaming]=1
[[ "${WANTED[gaming]:-0}" == 0 ]] && { WANTED[single]=0; WANTED[boot]=0; } [[ "${WANTED[gaming]:-0}" == 0 ]] && { WANTED[single]=0; WANTED[boot]=0; }
[[ "${WANTED[bigpicture]:-0}" == 1 ]] && WANTED[nvidia]=1
[[ "${WANTED[nvidia]:-0}" == 0 ]] && WANTED[bigpicture]=0
[[ "${WANTED[poweroff]:-0}" == 1 ]] && WANTED[machine]=1 [[ "${WANTED[poweroff]:-0}" == 1 ]] && WANTED[machine]=1
[[ "${WANTED[machine]:-0}" == 0 ]] && WANTED[poweroff]=0 [[ "${WANTED[machine]:-0}" == 0 ]] && WANTED[poweroff]=0
[[ "${WANTED[kpin]:-0}" == 1 ]] && WANTED[machine]=1 [[ "${WANTED[kpin]:-0}" == 1 ]] && WANTED[machine]=1
-2
View File
@@ -109,7 +109,6 @@ gaming_enable() {
esac esac
create_desktop_shortcut create_desktop_shortcut
steam_enable steam_enable
nvidia_enable || return 1
os_name_enable || return 1 os_name_enable || return 1
} }
@@ -125,7 +124,6 @@ gaming_disable() {
steam_disable steam_disable
krevert gaming krevert gaming
os_name_disable os_name_disable
nvidia_disable
ok "The PC boots to the normal login screen again (from the next boot)." ok "The PC boots to the normal login screen again (from the next boot)."
} }
+14 -3
View File
@@ -5,12 +5,12 @@
# Menu order. Components are turned on in this order and off in reverse; # Menu order. Components are turned on in this order and off in reverse;
# gaming must come first (single user builds on it). # gaming must come first (single user builds on it).
COMPONENTS=(gaming boot theme glyphs single launcher steamgame notify vram cec machine poweroff kpin hdmi bios) COMPONENTS=(gaming boot nvidia bigpicture theme glyphs single launcher steamgame notify vram cec machine poweroff kpin hdmi bios)
# One-off actions rather than on/off components: never preselected, never # One-off actions rather than on/off components: never preselected, never
# re-applied, not listed as on or off. # re-applied, not listed as on or off.
ACTIONS=(bios) ACTIONS=(bios)
# Sub-options, shown indented under their parent and only while it's ticked. # Sub-options, shown indented under their parent and only while it's ticked.
declare -A PARENT=([boot]=gaming [steamgame]=launcher [poweroff]=machine [kpin]=machine [hdmi]=machine [bios]=machine) declare -A PARENT=([boot]=gaming [bigpicture]=nvidia [steamgame]=launcher [poweroff]=machine [kpin]=machine [hdmi]=machine [bios]=machine)
# Never preselected on a first run: booting into the desktop is a choice, # Never preselected on a first run: booting into the desktop is a choice,
# gamescope is the default; HDMI-CEC is opt-in (it can wake the machine or # gamescope is the default; HDMI-CEC is opt-in (it can wake the machine or
# upset other devices on the TV, even on SteamOS), except on a Steam Machine, # upset other devices on the TV, even on SteamOS), except on a Steam Machine,
@@ -25,7 +25,7 @@ NO_PRESELECT=(boot cec kpin hdmi)
# FEATURE_BASELINE. # FEATURE_BASELINE.
FEATURE_BASELINE=2.1.0 FEATURE_BASELINE=2.1.0
declare -A FEATURE_VERSION=( declare -A FEATURE_VERSION=(
[gaming]=2.9.7 [boot]=2.1.0 [theme]=2.1.0 [glyphs]=2.1.0 [single]=2.1.0 [gaming]=2.9.0 [boot]=2.1.0 [nvidia]=2.9.7 [bigpicture]=2.9.7 [theme]=2.1.0 [glyphs]=2.1.0 [single]=2.1.0
[launcher]=2.1.0 [cec]=2.7.0 [machine]=2.9.0 [poweroff]=2.2.0 [vram]=2.3.0 [notify]=2.5.0 [steamgame]=2.5.1 [launcher]=2.1.0 [cec]=2.7.0 [machine]=2.9.0 [poweroff]=2.2.0 [vram]=2.3.0 [notify]=2.5.0 [steamgame]=2.5.1
[kpin]=2.1.0 [hdmi]=2.1.0 [kpin]=2.1.0 [hdmi]=2.1.0
) )
@@ -33,6 +33,8 @@ declare -A FEATURE_VERSION=(
declare -A LABEL=( declare -A LABEL=(
[gaming]="SteamOS conversion: boot into gaming mode, Steam on the desktop" [gaming]="SteamOS conversion: boot into gaming mode, Steam on the desktop"
[boot]="Boot into the desktop instead of gaming mode" [boot]="Boot into the desktop instead of gaming mode"
[nvidia]="Gaming on NVIDIA: Steam on the desktop, started at login"
[bigpicture]="Steam starts in Big Picture: the controller-friendly Steam (untick: Steam's normal window)"
[theme]="Install SteamOS theme: Vapor look (cachyos-vapor)" [theme]="Install SteamOS theme: Vapor look (cachyos-vapor)"
[glyphs]="Install Steam Deck/Machine icons: Deck button icons in gaming mode" [glyphs]="Install Steam Deck/Machine icons: Deck button icons in gaming mode"
[single]="Single user mode: no password, lock screen or log out (SDDM)" [single]="Single user mode: no password, lock screen or log out (SDDM)"
@@ -51,6 +53,11 @@ declare -A CURRENT WANTED
component_available() { component_available() {
case "$1" in case "$1" in
# gamescope's own session is broken on NVIDIA: the conversion is replaced by "Gaming on NVIDIA" there (shown
# anyway when it's already on, so it can be turned off).
gaming|boot|single|glyphs) ! nvidia_present || gaming_status ;;
nvidia) nvidia_available ;;
bigpicture) bigpicture_available ;;
machine|poweroff) machine_available ;; machine|poweroff) machine_available ;;
vram) vram_available ;; vram) vram_available ;;
steamgame) steamgame_available ;; steamgame) steamgame_available ;;
@@ -141,6 +148,7 @@ component_selectable() {
detect_components() { detect_components() {
local c any=false local c any=false
for c in "${COMPONENTS[@]}"; do CURRENT[$c]=0; WANTED[$c]=0; done
for c in "${COMPONENTS[@]}"; do for c in "${COMPONENTS[@]}"; do
component_available "$c" || continue component_available "$c" || continue
if "${c}_status"; then CURRENT[$c]=1; any=true; else CURRENT[$c]=0; fi if "${c}_status"; then CURRENT[$c]=1; any=true; else CURRENT[$c]=0; fi
@@ -270,6 +278,9 @@ toggle_component() {
if [[ "$c" == gaming && "${WANTED[gaming]}" == 0 ]]; then WANTED[single]=0; WANTED[boot]=0; fi if [[ "$c" == gaming && "${WANTED[gaming]}" == 0 ]]; then WANTED[single]=0; WANTED[boot]=0; fi
# Where to boot to is part of the conversion, too. # Where to boot to is part of the conversion, too.
if [[ "$c" == boot && "${WANTED[boot]}" == 1 ]]; then WANTED[gaming]=1; fi if [[ "$c" == boot && "${WANTED[boot]}" == 1 ]]; then WANTED[gaming]=1; fi
# Big Picture is opt-out: ticked along with "Gaming on NVIDIA".
if [[ "$c" == nvidia ]]; then WANTED[bigpicture]=${WANTED[nvidia]}; fi
if [[ "$c" == bigpicture && "${WANTED[bigpicture]}" == 1 ]]; then WANTED[nvidia]=1; fi
# The power-off fix is opt-out: ticked along with Steam Machine support. # The power-off fix is opt-out: ticked along with Steam Machine support.
if [[ "$c" == machine ]]; then WANTED[poweroff]=${WANTED[machine]}; fi if [[ "$c" == machine ]]; then WANTED[poweroff]=${WANTED[machine]}; fi
if [[ "$c" == poweroff && "${WANTED[poweroff]}" == 1 ]]; then WANTED[machine]=1; fi if [[ "$c" == poweroff && "${WANTED[poweroff]}" == 1 ]]; then WANTED[machine]=1; fi
+89 -12
View File
@@ -1,22 +1,99 @@
#!/bin/bash #!/bin/bash
# NVIDIA fix for gaming mode, part of the SteamOS conversion # Gaming on NVIDIA PCs: the SteamOS conversion (gamescope session) isn't offered there, because gamescope's DRM session shows a
# (gaming_enable/gaming_disable). gamescope drives the display itself # corrupted picture on NVIDIA (NVIDIA's open bug 5240452: modes above 2560x1440@120). `nvidia` is the replacement: Steam on the
# through DRM/KMS; with NVIDIA that needs kernel modesetting and the # Plasma desktop, installed when missing and started at login; `bigpicture` (a sub-option) makes it start in Big Picture.
# framebuffer driver (nvidia-drm.modeset=1 nvidia-drm.fbdev=1) and the # On a supported card (RTX 20 series or newer, `nvidia_supported`) it also sets up what NVIDIA's Wayland/DRM stack wants:
# driver in the initramfs, or the screen shows a corrupted image. # nvidia-drm.modeset=1 and fbdev=1 on the kernel command line and the NVIDIA modules in the initramfs. That didn't cure
# Does nothing without a supported NVIDIA GPU (RTX 20 series or newer) that has # gamescope's picture (the driver already reported both `Y`), but it is the standard setup and may be needed.
# its driver installed.
# Sourced by steamify.sh; not meant to be run on its own. # Sourced by steamify.sh; not meant to be run on its own.
NVIDIA_UNIT=steamify-steam-autostart.service
NVIDIA_PARAMS="nvidia-drm.modeset=1 nvidia-drm.fbdev=1" NVIDIA_PARAMS="nvidia-drm.modeset=1 nvidia-drm.fbdev=1"
NVIDIA_INITRAMFS_CONF=/etc/mkinitcpio.conf.d/90-steamify-nvidia.conf NVIDIA_INITRAMFS_CONF=${NVIDIA_INITRAMFS_CONF:-/etc/mkinitcpio.conf.d/90-steamify-nvidia.conf}
# The script and pacman hook that keep the initramfs file right at every kernel change. # The script and pacman hook that keep the initramfs file right at every kernel change.
NVIDIA_SCRIPT=${NVIDIA_SCRIPT:-/usr/local/libexec/steamify-nvidia-initramfs} NVIDIA_SCRIPT=${NVIDIA_SCRIPT:-/usr/local/libexec/steamify-nvidia-initramfs}
NVIDIA_HOOK=${NVIDIA_HOOK:-/etc/pacman.d/hooks/85-steamify-nvidia-initramfs.hook} NVIDIA_HOOK=${NVIDIA_HOOK:-/etc/pacman.d/hooks/85-steamify-nvidia-initramfs.hook}
# The running kernel's command line; the tests point this at a file.
NVIDIA_CMDLINE=${NVIDIA_CMDLINE:-/proc/cmdline}
# The DRM devices in sysfs; the tests point this at a fake tree. # The DRM devices in sysfs; the tests point this at a fake tree.
NVIDIA_DRM_DIR=${NVIDIA_DRM_DIR:-/sys/class/drm} NVIDIA_DRM_DIR=${NVIDIA_DRM_DIR:-/sys/class/drm}
nvidia_unit_file() { echo "$HOME/.config/systemd/user/$NVIDIA_UNIT"; }
nvidia_present() { nvidia_present() {
# An NVIDIA GPU (PCI vendor 0x10de, display class) whose driver provides
# nvidia_drm. nouveau has none, and gamescope is not a problem there.
local d
for d in "$NVIDIA_DRM_DIR"/card[0-9]*/device; do
[[ "$(cat "$d/vendor" 2>/dev/null)" == 0x10de ]] || continue
[[ "$(cat "$d/class" 2>/dev/null)" == 0x03* ]] || continue
modinfo nvidia_drm >/dev/null 2>&1 && return 0
done
return 1
}
# Shown on NVIDIA PCs, unless the SteamOS conversion is already on there (it
# has to be turned off first: both would start Steam at login).
nvidia_available() { nvidia_present && ! gaming_status 2>/dev/null; }
bigpicture_available() { nvidia_available; }
nvidia_status() {
pacman -Q steam >/dev/null 2>&1 && [[ -f "$(nvidia_unit_file)" ]] &&
user_systemctl is-enabled -q "$NVIDIA_UNIT" 2>/dev/null
}
nvidia_write_unit() {
# nvidia_write_unit [args]: the autostart unit, Steam started with those arguments.
local unit; unit="$(nvidia_unit_file)"
mkdir -p "$(dirname "$unit")"
service_file steamify-steam-autostart.service ARGS="$1" > "$unit" || { err "Writing $unit failed."; return 1; }
user_systemctl daemon-reload
}
nvidia_enable() {
info "Gaming on NVIDIA: Steam on the desktop, started at login..."
if ! pacman -Q steam >/dev/null 2>&1; then
sudo pacman -S --needed --noconfirm steam || { err "Installing Steam failed."; return 1; }
state_set nvidia installed_pkgs steam
fi
# Keeps what the Big Picture option set up; a first run starts Steam normally.
local args=""; bigpicture_status && args=-gamepadui
nvidia_write_unit "$args" || return 1
user_systemctl enable "$NVIDIA_UNIT" >/dev/null 2>&1 || { err "Enabling $NVIDIA_UNIT failed."; return 1; }
nvidia_kernel_enable || return 1
ok "Steam starts at your next login."
}
nvidia_disable() {
local pkgs unit; unit="$(nvidia_unit_file)"
user_systemctl disable --now "$NVIDIA_UNIT" >/dev/null 2>&1
rm -f "$unit"
user_systemctl daemon-reload
pkgs="$(state_get nvidia installed_pkgs)"
# Only what Steamify installed; games and the Steam folder stay.
# shellcheck disable=SC2086 # a list of package names
[[ -n "$pkgs" ]] && sudo pacman -Rns --noconfirm $pkgs >/dev/null 2>&1
state_clear nvidia
nvidia_kernel_disable
ok "Steam no longer starts at login."
}
bigpicture_status() { grep -qs -- '-gamepadui' "$(nvidia_unit_file)"; }
bigpicture_enable() {
# The unit comes from nvidia_enable (it runs first); without it there is nothing to change.
[[ -f "$(nvidia_unit_file)" ]] || return 0
nvidia_write_unit -gamepadui && ok "Steam starts in Big Picture at your next login."
}
bigpicture_disable() {
[[ -f "$(nvidia_unit_file)" ]] || return 0
nvidia_write_unit "" && ok "Steam starts in its normal window at your next login."
}
# --- Kernel parameters and early modules (a supported card only)
nvidia_supported() {
# A supported NVIDIA GPU: PCI vendor 0x10de, display class, its kernel # A supported NVIDIA GPU: PCI vendor 0x10de, display class, its kernel
# driver installed, and not older than the RTX 20 series, decided like the # driver installed, and not older than the RTX 20 series, decided like the
# VRAM booster does (vram_nvidia_legacy_id: chwd's legacy card lists, every # VRAM booster does (vram_nvidia_legacy_id: chwd's legacy card lists, every
@@ -53,7 +130,7 @@ nvidia_param_set() {
# The kernel treats "nvidia_drm" and "nvidia-drm" alike: CachyOS' own # The kernel treats "nvidia_drm" and "nvidia-drm" alike: CachyOS' own
# setup may already have written the underscore spelling. # setup may already have written the underscore spelling.
local f re; f="$(nvidia_boot_file)"; re="${1//nvidia-drm/nvidia[-_]drm}" local f re; f="$(nvidia_boot_file)"; re="${1//nvidia-drm/nvidia[-_]drm}"
grep -qwE -- "$re" /proc/cmdline 2>/dev/null || grep -qwE -- "$re" "$NVIDIA_CMDLINE" 2>/dev/null ||
{ [[ -n "$f" ]] && grep -qwE -- "$re" "$f" 2>/dev/null; } { [[ -n "$f" ]] && grep -qwE -- "$re" "$f" 2>/dev/null; }
} }
@@ -107,8 +184,8 @@ nvidia_boot_has_params() {
sudo grep -rqs 'nvidia-drm.modeset=1' "$target" sudo grep -rqs 'nvidia-drm.modeset=1' "$target"
} }
nvidia_enable() { nvidia_kernel_enable() {
nvidia_present || return 0 nvidia_supported || return 0
local f changed=0 p; f="$(nvidia_boot_file)" local f changed=0 p; f="$(nvidia_boot_file)"
if nvidia_params_missing; then if nvidia_params_missing; then
if [[ -z "$f" ]]; then if [[ -z "$f" ]]; then
@@ -154,7 +231,7 @@ nvidia_enable() {
return 0 return 0
} }
nvidia_disable() { nvidia_kernel_disable() {
local f changed=0; f="$(nvidia_boot_file)" local f changed=0; f="$(nvidia_boot_file)"
if [[ -n "$f" ]] && grep -q "$NVIDIA_PARAMS" "$f" 2>/dev/null; then if [[ -n "$f" ]] && grep -q "$NVIDIA_PARAMS" "$f" 2>/dev/null; then
sudo sed -i "s/ \?$NVIDIA_PARAMS//" "$f" sudo sed -i "s/ \?$NVIDIA_PARAMS//" "$f"
+1
View File
@@ -11,6 +11,7 @@ in the shell code.
|---|---|---| |---|---|---|
| `steamify-boot-desktop.service` | `lib/boot-session.sh` (Boot into: desktop) | Sets the Plasma session before the login manager starts | | `steamify-boot-desktop.service` | `lib/boot-session.sh` (Boot into: desktop) | Sets the Plasma session before the login manager starts |
| `sync-steamos-session.path`, `.service` | `lib/login-manager.sh` (SteamOS conversion, plasma-login-manager) | The sync bridge: copies Steam's session choice into `plasmalogin.conf` | | `sync-steamos-session.path`, `.service` | `lib/login-manager.sh` (SteamOS conversion, plasma-login-manager) | The sync bridge: copies Steam's session choice into `plasmalogin.conf` |
| `steamify-steam-autostart.service` | `lib/nvidia.sh` (Gaming on NVIDIA) | Steam at login on the Plasma desktop, normal or in Big Picture (user unit) |
| `steam-desktop-autostart.service` | `lib/steam-desktop.sh` (SteamOS conversion) | Steam in the background on the Plasma desktop (user unit) | | `steam-desktop-autostart.service` | `lib/steam-desktop.sh` (SteamOS conversion) | Steam in the background on the Plasma desktop (user unit) |
| `ensure-kernel-headers.service` | `lib/steam-machine.sh` (Steam Machine support) | Installs missing kernel headers at boot, so DKMS builds for every kernel | | `ensure-kernel-headers.service` | `lib/steam-machine.sh` (Steam Machine support) | Installs missing kernel headers at boot, so DKMS builds for every kernel |
| `steamify-update-check.service`, `.timer` | `lib/update-notifier.sh` (Update notifications) | The daily and login check for a new release (user units) | | `steamify-update-check.service`, `.timer` | `lib/update-notifier.sh` (Update notifications) | The daily and login check for a new release (user units) |
+15
View File
@@ -0,0 +1,15 @@
[Unit]
Description=Steam at login (Steamify, NVIDIA PCs)
After=graphical-session.target
PartOf=graphical-session.target
[Service]
Type=simple
# Only in the Plasma desktop session.
ExecCondition=/bin/sh -c '[ "$XDG_CURRENT_DESKTOP" = KDE ]'
ExecStart=/usr/bin/steam @ARGS@
Restart=on-failure
RestartSec=5
[Install]
WantedBy=graphical-session.target
+106 -30
View File
@@ -1,43 +1,109 @@
#!/bin/bash #!/bin/bash
# Tests lib/nvidia.sh against a fake RTX 5080 (PCI 10de:2c02) beside an # Tests lib/nvidia.sh ("Gaming on NVIDIA" and its Big Picture option) and the menu rules around it, against a fake RTX 5080
# Intel iGPU, a stub modinfo, and temp copies of the boot loader files. No # (PCI 10de:2c02) beside an Intel iGPU, a stub modinfo, pacman and systemctl, and a temp home. No root, VM or NVIDIA
# root, VM or NVIDIA hardware needed: bash tests/nvidia-test.sh # hardware needed: bash tests/nvidia-test.sh
cd "$(dirname "$0")/.." || exit 1 cd "$(dirname "$0")/.." || exit 1
T="$(mktemp -d)"; trap 'rm -rf "$T"' EXIT T="$(mktemp -d)"; trap 'rm -rf "$T"' EXIT
fail=0 fail=0
check() { if eval "$2"; then echo "ok $1"; else echo "FAIL $1"; fail=1; fi; } check() { if eval "$2"; then echo "ok $1"; else echo "FAIL $1"; fail=1; fi; }
SCRIPT_DIR="$PWD"; source lib/common.sh; source lib/hdmi-refresh.sh; source lib/vram-booster.sh; source lib/nvidia.sh SCRIPT_DIR="$PWD"; HOME="$T/home"; mkdir -p "$HOME"
sudo() { "$@"; } source lib/common.sh; source lib/state.sh; source lib/hdmi-refresh.sh; source lib/vram-booster.sh; source lib/nvidia.sh; source lib/menu.sh
# Runs as the user, and refuses anything under the real system folders: a test must never touch them.
sudo() { local a; for a in "$@"; do case "$a" in /etc/*|/usr/*|/boot/*|/var/*) echo "REFUSED sudo $*" >&2; return 1 ;; esac; done; "$@"; }
info() { :; }; ok() { :; }; warn() { :; }; err() { echo "ERR $*"; } info() { :; }; ok() { :; }; warn() { :; }; err() { echo "ERR $*"; }
backup_file() { [[ -f "$1.bak" ]] || cp "$1" "$1.bak"; } kwriteconfig6() { local f g k v; while [[ $# -gt 0 ]]; do case "$1" in --file) f="$2";; --key) k="$2";; esac; [[ $# -ge 2 ]] && v="$2"; shift; done; printf '%s=%s\n' "$k" "$v" > "$f"; }
modinfo() { [[ "$FAKE_DRIVER" == 1 ]]; } kreadconfig6() { local f k; while [[ $# -gt 0 ]]; do case "$1" in --file) f="$2";; --key) k="$2";; esac; shift; done; sed -n "s/^$k=//p" "$f" 2>/dev/null; }
REBUILDS=0; nvidia_rebuild_boot() { REBUILDS=$((REBUILDS + 1)); } # A pretend package database and systemd: what the tests assert on.
NVIDIA_INITRAMFS_CONF="$T/90-steamify-nvidia.conf" PKGS=""; PACMAN_LOG="$T/pacman.log"; : > "$PACMAN_LOG"; ENABLED=0
pacman() {
case "$1" in
-Q) [[ " $PKGS " == *" $2 "* ]] ;;
-S) echo "S $*" >> "$PACMAN_LOG"; PKGS+=" ${*: -1}" ;;
-Rns) echo "R $*" >> "$PACMAN_LOG"; PKGS=" ${PKGS//${*: -1}/} " ;;
esac
}
user_systemctl() {
case "$1" in
enable) ENABLED=1 ;;
disable) ENABLED=0 ;;
is-enabled) [[ $ENABLED == 1 ]] ;;
esac
return 0
}
FAKE_DRIVER=1; modinfo() { [[ "$FAKE_DRIVER" == 1 ]]; }
GAMING_ON=0; gaming_status() { [[ "$GAMING_ON" == 1 ]]; }
UNIT="$HOME/.config/systemd/user/$NVIDIA_UNIT"
mkdir -p "$T/drm/card0/device" "$T/drm/card1/device" mkdir -p "$T/drm/card0/device" "$T/drm/card1/device"
echo 0x8086 > "$T/drm/card0/device/vendor"; echo 0x030000 > "$T/drm/card0/device/class" echo 0x8086 > "$T/drm/card0/device/vendor"; echo 0x030000 > "$T/drm/card0/device/class"
echo 0x10de > "$T/drm/card1/device/vendor"; echo 0x030000 > "$T/drm/card1/device/class" echo 0x10de > "$T/drm/card1/device/vendor"; echo 0x030000 > "$T/drm/card1/device/class"
echo 0x2c02 > "$T/drm/card1/device/device" echo 0x2c02 > "$T/drm/card1/device/device"
NVIDIA_DRM_DIR="$T/drm" NVIDIA_DRM_DIR="$T/drm"
mkdir -p "$T/mods/6.1.0-cachyos/kernel"; : > "$T/mods/6.1.0-cachyos/kernel/nvidia-drm.ko.zst"; : > "$T/mods/6.1.0-cachyos/pkgbase" backup_file() { [[ -f "$1.bak" ]] || cp "$1" "$1.bak"; }
REBUILDS=0; nvidia_rebuild_boot() { REBUILDS=$((REBUILDS + 1)); }
: > "$T/cmdline"; NVIDIA_CMDLINE="$T/cmdline" # the running kernel's command line: without the parameters
NVIDIA_INITRAMFS_CONF="$T/90-steamify-nvidia.conf"
NVIDIA_SCRIPT="$T/libexec/steamify-nvidia-initramfs"; NVIDIA_HOOK="$T/hooks/85-steamify-nvidia-initramfs.hook" NVIDIA_SCRIPT="$T/libexec/steamify-nvidia-initramfs"; NVIDIA_HOOK="$T/hooks/85-steamify-nvidia-initramfs.hook"
mkdir -p "$T/mods/6.1.0-cachyos/kernel"; : > "$T/mods/6.1.0-cachyos/kernel/nvidia-drm.ko.zst"; : > "$T/mods/6.1.0-cachyos/pkgbase"
NVIDIA_MODULES_DIR="$T/mods" NVIDIA_MODULES_DIR="$T/mods"
NVIDIA_LIMINE_CONF="$T/none/limine.conf"; NVIDIA_SDBOOT_DIR="$T/none/entries"; NVIDIA_GRUB_CFG="$T/none/grub.cfg" # not generated here: not checked NVIDIA_LIMINE_CONF="$T/none/limine.conf"; NVIDIA_SDBOOT_DIR="$T/none/entries"; NVIDIA_GRUB_CFG="$T/none/grub.cfg" # not generated here: not checked
mkdir -p "$T/chwd"; VRAM_CHWD_IDS="$T/chwd" mkdir -p "$T/chwd"; VRAM_CHWD_IDS="$T/chwd"
FAKE_DRIVER=1; check "finds the NVIDIA card as card1 beside an iGPU (no legacy lists)" nvidia_present # The component's kernel step edits this boot loader file (systemd-boot's) in the tests, never a real one.
printf '1c03\n1b80\n' > "$T/chwd/nvidia-580.ids" # a GTX 1060 and a GTX 1080: chwd's 580xx legacy list printf 'LINUX_OPTIONS="quiet"\n' > "$T/sdboot-manage.conf"; nvidia_boot_file() { echo "$T/sdboot-manage.conf"; }
check "RTX 5080 (2c02) is not on a legacy list: supported" nvidia_present
echo 0x1c03 > "$T/drm/card1/device/device" # --- detection
check "GTX 1060 (on chwd's legacy list, older than RTX 20): not supported" '! nvidia_present' check "finds the NVIDIA card as card1 beside an iGPU" nvidia_present
check "...and reported as a legacy GPU" nvidia_legacy_gpu FAKE_DRIVER=0; check "no nvidia_drm module (nouveau): not an NVIDIA PC" '! nvidia_present'
echo 0x2c02 > "$T/drm/card1/device/device"; check "RTX 5080 is not a legacy GPU" '! nvidia_legacy_gpu' FAKE_DRIVER=1; NVIDIA_DRM_DIR="$T/none"; check "no NVIDIA GPU: not an NVIDIA PC" '! nvidia_present'
printf '2c02\n' > "$T/chwd/nvidia-580.ids"; check "a card id that is on a legacy list is skipped, whatever it is" '! nvidia_present'
printf '1c03\n' > "$T/chwd/nvidia-580.ids"
FAKE_DRIVER=0; check "skips when the driver isn't installed" '! nvidia_present'
FAKE_DRIVER=1; NVIDIA_DRM_DIR="$T/none"; check "skips without an NVIDIA GPU" '! nvidia_present'
NVIDIA_DRM_DIR="$T/drm" NVIDIA_DRM_DIR="$T/drm"
# --- which items the menu shows
check "NVIDIA PC: the SteamOS conversion and its options are hidden" '! component_available gaming && ! component_available boot && ! component_available single && ! component_available glyphs'
check "NVIDIA PC: Gaming on NVIDIA and Big Picture are shown" 'component_available nvidia && component_available bigpicture'
GAMING_ON=1
check "NVIDIA PC with the conversion already on: it is shown, so it can be turned off" 'component_available gaming && component_available boot'
check "...and Gaming on NVIDIA is hidden (both would start Steam)" '! component_available nvidia && ! component_available bigpicture'
GAMING_ON=0; NVIDIA_DRM_DIR="$T/none"
check "no NVIDIA: the conversion is shown as before" 'component_available gaming && component_available boot'
check "...and Gaming on NVIDIA is hidden" '! component_available nvidia && ! component_available bigpicture'
NVIDIA_DRM_DIR="$T/drm"
# --- turning it on
check "off to begin with" '! nvidia_status && ! bigpicture_status'
nvidia_enable
check "Steam is installed when missing, and recorded as ours" 'grep -q "^S " "$PACMAN_LOG" && [[ "$(state_get nvidia installed_pkgs)" == steam ]]'
check "the autostart unit is written: Steam without arguments" 'grep -q "^ExecStart=/usr/bin/steam $" "$UNIT"'
check "it is on" 'nvidia_status && ! bigpicture_status'
n="$(wc -l < "$PACMAN_LOG")"; nvidia_enable
check "a second run installs nothing again" '[[ "$(wc -l < "$PACMAN_LOG")" == "$n" ]]'
# --- Big Picture
bigpicture_enable
check "Big Picture: Steam starts with -gamepadui" 'grep -q "^ExecStart=/usr/bin/steam -gamepadui$" "$UNIT" && bigpicture_status'
nvidia_enable
check "turning Gaming on NVIDIA on again keeps Big Picture" 'bigpicture_status'
bigpicture_disable
check "Big Picture off: Steam's normal window again" '! bigpicture_status && nvidia_status'
# --- turning it off
bigpicture_enable; nvidia_disable
check "off: the unit is gone and Steam, which we installed, is removed" '! nvidia_status && [[ ! -e "$UNIT" ]] && ! pacman -Q steam && [[ -z "$(state_get nvidia installed_pkgs)" ]]'
check "Big Picture without the unit does nothing" 'bigpicture_enable && bigpicture_disable && [[ ! -e "$UNIT" ]]'
# --- Steam that was there already is never removed
PKGS=" steam"; : > "$PACMAN_LOG"
nvidia_enable; nvidia_disable
check "Steam installed before is kept, and not installed again" '[[ ! -s "$PACMAN_LOG" ]] && pacman -Q steam'
# --- kernel parameters and early modules (a supported card only: RTX 20 series or newer)
check "RTX 5080 (2c02) is supported: no chwd legacy lists" nvidia_supported
printf '1c03\n1b80\n' > "$T/chwd/nvidia-580.ids" # a GTX 1060 and a GTX 1080: chwd's 580xx legacy list
check "RTX 5080 is not on a legacy list" 'nvidia_supported && ! nvidia_legacy_gpu'
echo 0x1c03 > "$T/drm/card1/device/device"
check "GTX 1060 (older than RTX 20): no kernel setup, but still an NVIDIA PC" '! nvidia_supported && nvidia_legacy_gpu && nvidia_present'
echo 0x2c02 > "$T/drm/card1/device/device"
for loader in limine limineplus sdboot grub; do for loader in limine limineplus sdboot grub; do
case $loader in case $loader in
limine) F="$T/limine"; printf 'KERNEL_CMDLINE[default]="quiet splash"\n' > "$F" ;; limine) F="$T/limine"; printf 'KERNEL_CMDLINE[default]="quiet splash"\n' > "$F" ;;
@@ -48,14 +114,14 @@ for loader in limine limineplus sdboot grub; do
esac esac
nvidia_boot_file() { echo "$F"; } nvidia_boot_file() { echo "$F"; }
rm -f "$NVIDIA_INITRAMFS_CONF"; REBUILDS=0; ORIG="$(cat "$F")" rm -f "$NVIDIA_INITRAMFS_CONF"; REBUILDS=0; ORIG="$(cat "$F")"
nvidia_enable nvidia_kernel_enable
check "$loader: parameters added" 'grep -q "nvidia-drm.modeset=1" "$F" && grep -q "nvidia-drm.fbdev=1" "$F"' check "$loader: parameters added" 'grep -q "nvidia-drm.modeset=1" "$F" && grep -q "nvidia-drm.fbdev=1" "$F"'
check "$loader: initramfs drop-in written" 'grep -q nvidia_drm "$NVIDIA_INITRAMFS_CONF"' check "$loader: initramfs drop-in written" 'grep -q nvidia_drm "$NVIDIA_INITRAMFS_CONF"'
check "$loader: script and pacman hook installed" '[[ -x "$NVIDIA_SCRIPT" ]] && grep -q "^Exec = $NVIDIA_SCRIPT sync" "$NVIDIA_HOOK"' check "$loader: script and pacman hook installed" '[[ -x "$NVIDIA_SCRIPT" ]] && grep -q "^Exec = $NVIDIA_SCRIPT sync" "$NVIDIA_HOOK"'
check "$loader: backup made, rebuilt once" '[[ -f "$F.bak" && $REBUILDS == 1 ]]' check "$loader: backup made, rebuilt once" '[[ -f "$F.bak" && $REBUILDS == 1 ]]'
SUM="$(cat "$F")"; nvidia_enable SUM="$(cat "$F")"; nvidia_kernel_enable
check "$loader: second run changes nothing" '[[ "$(cat "$F")" == "$SUM" && $REBUILDS == 1 ]]' check "$loader: second run changes nothing" '[[ "$(cat "$F")" == "$SUM" && $REBUILDS == 1 ]]'
nvidia_disable nvidia_kernel_disable
check "$loader: disable restores the file, drops the drop-in, script and hook" '[[ "$(cat "$F")" == "$ORIG" && ! -f "$NVIDIA_INITRAMFS_CONF" && ! -e "$NVIDIA_SCRIPT" && ! -e "$NVIDIA_HOOK" ]]' check "$loader: disable restores the file, drops the drop-in, script and hook" '[[ "$(cat "$F")" == "$ORIG" && ! -f "$NVIDIA_INITRAMFS_CONF" && ! -e "$NVIDIA_SCRIPT" && ! -e "$NVIDIA_HOOK" ]]'
done done
@@ -71,20 +137,30 @@ syncit; check "hook script: a new kernel without modules -> drop-in removed" '[[
syncit; check "hook script: the modules arrive (DKMS built) -> drop-in back" '[[ -f "$NVIDIA_INITRAMFS_CONF" ]]' syncit; check "hook script: the modules arrive (DKMS built) -> drop-in back" '[[ -f "$NVIDIA_INITRAMFS_CONF" ]]'
rm -rf "$T/mods/6.6.0-lts"; mkdir -p "$T/mods/5.0.0-leftover"; : > "$T/mods/5.0.0-leftover/modules.dep" rm -rf "$T/mods/6.6.0-lts"; mkdir -p "$T/mods/5.0.0-leftover"; : > "$T/mods/5.0.0-leftover/modules.dep"
syncit; check "hook script: a leftover folder of a removed kernel is ignored" '[[ -f "$NVIDIA_INITRAMFS_CONF" ]]' syncit; check "hook script: a leftover folder of a removed kernel is ignored" '[[ -f "$NVIDIA_INITRAMFS_CONF" ]]'
rm -rf "$T/mods/5.0.0-leftover"; nvidia_disable rm -rf "$T/mods/5.0.0-leftover"; nvidia_kernel_disable
# A second kernel without the NVIDIA modules: no early-load drop-in, parameters still set. # A second kernel without the NVIDIA modules: no early-load drop-in, parameters still set.
mkdir -p "$T/mods/6.6.0-lts/kernel"; : > "$T/mods/6.6.0-lts/pkgbase"; F="$T/sdboot-manage.conf"; printf 'LINUX_OPTIONS="quiet"\n' > "$F" mkdir -p "$T/mods/6.6.0-lts/kernel"; : > "$T/mods/6.6.0-lts/pkgbase"; F="$T/sdboot-manage.conf"; printf 'LINUX_OPTIONS="quiet"\n' > "$F"
nvidia_boot_file() { echo "$F"; }; rm -f "$NVIDIA_INITRAMFS_CONF"; REBUILDS=0; nvidia_enable nvidia_boot_file() { echo "$F"; }; rm -f "$NVIDIA_INITRAMFS_CONF"; REBUILDS=0; nvidia_kernel_enable
check "kernel without nvidia modules: no drop-in, parameters set" '[[ ! -f "$NVIDIA_INITRAMFS_CONF" ]] && grep -q "nvidia-drm.fbdev=1" "$F"' check "kernel without nvidia modules: no drop-in, parameters set" '[[ ! -f "$NVIDIA_INITRAMFS_CONF" ]] && grep -q "nvidia-drm.fbdev=1" "$F"'
rm -rf "$T/mods/6.6.0-lts" rm -rf "$T/mods/6.6.0-lts"
# Generated boot entries without the parameters (the initramfs build failed): an error. # Generated boot entries without the parameters (the initramfs build failed): an error.
printf 'linux /vmlinuz root=/dev/sda1\n' > "$T/grub.cfg"; NVIDIA_GRUB_CFG="$T/grub.cfg" printf 'linux /vmlinuz root=/dev/sda1\n' > "$T/grub.cfg"; NVIDIA_GRUB_CFG="$T/grub.cfg"
F="$T/grub"; printf 'GRUB_CMDLINE_LINUX_DEFAULT="quiet"\n' > "$F"; nvidia_boot_file() { echo "$F"; }; rm -f "$NVIDIA_INITRAMFS_CONF" F="$T/grub"; printf 'GRUB_CMDLINE_LINUX_DEFAULT="quiet"\n' > "$F"; nvidia_boot_file() { echo "$F"; }; rm -f "$NVIDIA_INITRAMFS_CONF"
check "boot entries without the parameters: error" '! nvidia_enable >/dev/null' check "boot entries without the parameters: error" '! nvidia_kernel_enable >/dev/null'
NVIDIA_GRUB_CFG="$T/none/grub.cfg" NVIDIA_GRUB_CFG="$T/none/grub.cfg"
# A config file without the setting to edit: an error, not "applied". # A config file without the setting to edit: an error, not "applied".
F="$T/sdboot-manage.conf"; printf '#LINUX_OPTIONS=""\n' > "$F"; nvidia_boot_file() { echo "$F"; }; REBUILDS=0 F="$T/sdboot-manage.conf"; printf '#LINUX_OPTIONS=""\n' > "$F"; nvidia_boot_file() { echo "$F"; }; REBUILDS=0
check "no setting to edit: error, nothing rebuilt" '! nvidia_enable >/dev/null && [[ $REBUILDS == 0 ]]' check "no setting to edit: error, nothing rebuilt" '! nvidia_kernel_enable >/dev/null && [[ $REBUILDS == 0 ]]'
FAKE_DRIVER=0; printf 'LINUX_OPTIONS="quiet"\n' > "$T/sdboot"; F="$T/sdboot"; REBUILDS=0; nvidia_enable FAKE_DRIVER=0; NVIDIA_DRM_DIR="$T/drm"; printf 'LINUX_OPTIONS="quiet"\n' > "$T/sdboot"; F="$T/sdboot"; REBUILDS=0; nvidia_kernel_enable
check "no NVIDIA driver: nothing touched" '[[ "$(cat "$F")" == "LINUX_OPTIONS=\"quiet\"" && $REBUILDS == 0 ]]' check "no NVIDIA driver: nothing touched" '[[ "$(cat "$F")" == "LINUX_OPTIONS=\"quiet\"" && $REBUILDS == 0 ]]'
# --- the menu rules
declare -A WANTED=([nvidia]=1 [bigpicture]=1 [gaming]=0 [boot]=0 [single]=0 [machine]=0 [poweroff]=0 [launcher]=0 [steamgame]=0)
component_selectable() { return 0; }
toggle_component nvidia
check "unticking Gaming on NVIDIA unticks Big Picture" '[[ "${WANTED[nvidia]}" == 0 && "${WANTED[bigpicture]}" == 0 ]]'
toggle_component bigpicture
check "ticking Big Picture ticks Gaming on NVIDIA" '[[ "${WANTED[nvidia]}" == 1 && "${WANTED[bigpicture]}" == 1 ]]'
check "Big Picture follows Gaming on NVIDIA in the menu" '[[ " ${COMPONENTS[*]} " == *" nvidia bigpicture "* && "${PARENT[bigpicture]}" == nvidia ]]'
exit $fail exit $fail
+2
View File
@@ -77,6 +77,8 @@ Item {
// The same rules as the terminal menu (toggle_component). // The same rules as the terminal menu (toggle_component).
if (id === "gaming" && !w.gaming) w.single = false; if (id === "gaming" && !w.gaming) w.single = false;
if (id === "single" && w.single) w.gaming = true; if (id === "single" && w.single) w.gaming = true;
if (id === "nvidia") w.bigpicture = w.nvidia;
if (id === "bigpicture" && w.bigpicture) w.nvidia = true;
if (id === "machine") w.poweroff = w.machine; if (id === "machine") w.poweroff = w.machine;
if (id === "poweroff" && w.poweroff) w.machine = true; if (id === "poweroff" && w.poweroff) w.machine = true;
if (id === "machine" && !w.machine) w.kpin = false; if (id === "machine" && !w.machine) w.kpin = false;
+6
View File
@@ -10,6 +10,12 @@ QtObject {
boot: { label: "Boot into", hint: "Where the PC starts", boot: { label: "Boot into", hint: "Where the PC starts",
body: "Where the PC starts after a restart. Switching back and forth works the same either way.", body: "Where the PC starts after a restart. Switching back and forth works the same either way.",
changes: ["Desktop: the Plasma session is set before login", "Gaming: the SteamOS default"] }, changes: ["Desktop: the Plasma session is set before login", "Gaming: the SteamOS default"] },
nvidia: { label: "Gaming on NVIDIA", hint: "Steam on the desktop, started at login",
body: "gamescope's own gaming mode shows a corrupted picture on NVIDIA graphics cards (an open NVIDIA driver bug), so it isn't offered here. This puts Steam on the Plasma desktop instead and starts it when you log in.",
changes: ["Steam is installed when it's missing", "Steam starts at login (a systemd user service)", "Off: the service is removed again; Steam is only removed if Steamify installed it"] },
bigpicture: { label: "Steam starts in Big Picture", hint: "The controller-friendly Steam, or the normal window",
body: "Steam opens in Big Picture at login, which works well with a controller on the TV. Untick it for Steam's normal window.",
changes: ["Steam is started with -gamepadui", "Off: Steam starts in its normal window"] },
theme: { label: "SteamOS theme", hint: "Vapor look for the desktop, Add to Steam", theme: { label: "SteamOS theme", hint: "Vapor look for the desktop, Add to Steam",
body: "The Vapor look of SteamOS for the desktop, with its panel, launcher icon and wallpaper.", body: "The Vapor look of SteamOS for the desktop, with its panel, launcher icon and wallpaper.",
changes: ["cachyos-vapor global theme", "Add to Steam in right-click menus", "Nested Desktop, Steam keyboard window rule"] }, changes: ["cachyos-vapor global theme", "Add to Steam in right-click menus", "Nested Desktop, Steam keyboard window rule"] },