Merge feature/extended-controller-support into release/2.10.0

This commit is contained in:
theupriser committed 2026-10-01 21:29:42 +02:00
commit 1987fa903b
13 files changed
+199 -19

No files matched your search

+9 -4
View File
@@ -58,7 +58,9 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
one too): installs recorded with an older version one too): installs recorded with an older version
are ticked and re-applied ("update" in the plan and the app). New default are ticked and re-applied ("update" in the plan and the app). New default
options are ticked for installs whose parent (top-level: `gaming`) is on options are ticked for installs whose parent (top-level: `gaming`) is on
(`feature_new`, shown as "new"). (`feature_new`, shown as "new"). New opt-in options (`NO_PRESELECT`) get the
same "new" badge without being ticked (`feature_new_optin`). Both count "Gaming
on NVIDIA" as a parent where the conversion isn't offered.
Options shown but left unticked in a confirmed run are recorded as Options shown but left unticked in a confirmed run are recorded as
`off` (`feature_record_unticked`), or `feature_new` would tick them again. `off` (`feature_record_unticked`), or `feature_new` would tick them again.
Status still comes from the system; don't add ad-hoc `<id>_repair` checks Status still comes from the system; don't add ad-hoc `<id>_repair` checks
@@ -154,9 +156,12 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
a warning when `VERSION` is a version that's already released (so a a warning when `VERSION` is a version that's already released (so a
release branch that forgot its bump shows it on every PR). release branch that forgot its bump shows it on every PR).
- A release that adds, removes or renames a menu row also retakes the - A release that adds, removes or renames a menu row also retakes the
README screenshot (`assets/screenshot-menu.png`): the app from the README screenshots (`assets/screenshot-menu-steam-machine.png` and
branch on a Steam Machine, every row visible (window 1280 wide, tall `assets/screenshot-menu-nvidia.png`, side by side in the README): the app from the branch on a Steam Machine and on a PC
enough), the header showing the new `VERSION`, scaled to 1600 px wide. with an NVIDIA card, every row visible and each window only as tall as its options need, the header showing the new
`VERSION`, 1600 px wide. Size the window with a KWin script (match the `steamify-ui` class exactly: a title match also hits
Konsole and editor windows) and crop the full-screen capture to the client rectangle; mind the display scale (the Steam
Machine runs at 1.75).
- Users install through `releases/latest/download/steamify.sh` - Users install through `releases/latest/download/steamify.sh`
(GitHub's newest release). The `latest` tag and release follow the newest (GitHub's newest release). The `latest` tag and release follow the newest
version tag too (moved, asset replaced, when a new version is released), version tag too (moved, asset replaced, when a new version is released),
+3
View File
@@ -10,6 +10,9 @@ one per merged pull request.
- **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, and Big Picture starts on an empty Plasma session (no windows of the last session on top of it) (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** - **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, and Big Picture starts on an empty Plasma session (no windows of the last session on top of it) (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**
- **feat: single user mode also works on NVIDIA PCs, without the SteamOS conversion: it switches to SDDM and logs in to the Plasma session by itself (/etc/sddm.conf.d/zzz-steamify-autologin.conf), and no longer ticks the conversion where that isn't offered (lib/single-user.sh)** - **feat: single user mode also works on NVIDIA PCs, without the SteamOS conversion: it switches to SDDM and logs in to the Plasma session by itself (/etc/sddm.conf.d/zzz-steamify-autologin.conf), and no longer ticks the conversion where that isn't offered (lib/single-user.sh)**
- **fix: "Add as non-Steam game" isn't offered on NVIDIA PCs (there is no gaming mode there for it to give the controller; shown when already on, so it can be turned off)** - **fix: "Add as non-Steam game" isn't offered on NVIDIA PCs (there is no gaming mode there for it to give the controller; shown when already on, so it can be turned off)**
- **feat: Extended controller support (extended_controller_support, off by default): the Xbox wireless dongle (xone-dkms, xone-dongle-firmware) and Xbox controllers over Bluetooth with rumble, button mapping and battery level (xpadneo-dkms), from the CachyOS repo, built for every installed kernel; a PC with the AUR's xone-dkms-git keeps it; off removes only what Steamify installed (lib/controllers.sh, tests/controllers-test.sh)**
- **feat: a new opt-in option (unticked by default, e.g. Extended controller support) shows the "new" badge in the menu and the app without being ticked for you (feature_new_optin); it counts "Gaming on NVIDIA" as its parent where the conversion isn't offered**
- **docs: README screenshots of the 2.10.0 app, side by side: on a Steam Machine and on a PC with an NVIDIA card**
- **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** - **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**
## 2.9.6 - 2026-09-30 ## 2.9.6 - 2026-09-30
+14 -1
View File
@@ -1,6 +1,14 @@
# Steamify CachyOS # Steamify CachyOS
![The Steamify app's menu on a Steam Machine](assets/screenshot-menu.png) The Steamify app's menu. On a Steam Machine (or any PC with an AMD or Intel
graphics card) it offers the full SteamOS conversion, on the left. On a PC with
an NVIDIA graphics card gamescope's gaming mode shows a corrupted picture, so the
menu offers **Gaming on NVIDIA** instead (Steam on the desktop, started at login,
optionally in Big Picture), on the right.
| On a Steam Machine | On a PC with an NVIDIA graphics card |
|---|---|
| ![The Steamify app's menu on a Steam Machine](assets/screenshot-menu-steam-machine.png) | ![The Steamify app's menu on a PC with an NVIDIA graphics card](assets/screenshot-menu-nvidia.png) |
Turn a CachyOS desktop PC into a SteamOS-style console: it boots straight Turn a CachyOS desktop PC into a SteamOS-style console: it boots straight
into Steam's Big Picture (gamescope), and you can switch to the KDE Plasma into Steam's Big Picture (gamescope), and you can switch to the KDE Plasma
@@ -62,6 +70,11 @@ Steam Machine.
the Steam Machine) or a USB CEC adapter; most graphics cards, NVIDIA the Steam Machine) or a USB CEC adapter; most graphics cards, NVIDIA
included, don't have it. See [CEC.md](CEC.md) for which PCs do, and how to included, don't have it. See [CEC.md](CEC.md) for which PCs do, and how to
add it to your own build ([details](TECHNICAL.md#hdmi-cec)). add it to your own build ([details](TECHNICAL.md#hdmi-cec)).
9. **Extended controller support** (off by default) - the Xbox wireless
dongle (xone) and Xbox controllers over Bluetooth with rumble, the right
button mapping and the battery level (xpadneo). Both are installed from the
CachyOS repo and built for every installed kernel
([details](TECHNICAL.md#extended-controller-support)).
## Steam Machine ## Steam Machine
+13
View File
@@ -214,6 +214,18 @@ 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.
## Extended controller support
`extended_controller_support` (`lib/controllers.sh`, top-level, off by default, 2.10.0) installs two kernel drivers from CachyOS's own
repo (no AUR): `xone-dkms` with `xone-dongle-firmware` for the Xbox wireless dongle (the kernel has no driver for it; wired
Xbox controllers go through the same driver), and `xpadneo-dkms` for Xbox One/Series controllers over Bluetooth (without it
they work as plain gamepads but miss rumble including the triggers, the right button mapping and the battery level). Both are
DKMS modules, built for every installed kernel, so `install_kernel_headers` (`lib/steam-machine.sh`) makes sure each kernel has its
headers first. A PC that already has the AUR's `xone-dkms-git` keeps it: it provides the same driver and conflicts with the repo's
`xone-dkms`. Status is the three packages being installed. Off removes only what Steamify installed (state
`extended_controller_support`, `installed_pkgs`); the headers stay. The drivers load when the device shows up: the dongle is
plugged in again, or the controller reconnected. `tests/controllers-test.sh` tests it with a stub `pacman`.
## Gaming on NVIDIA ## Gaming on NVIDIA
gamescope's own gaming mode shows a corrupted picture on NVIDIA graphics cards: NVIDIA's open bug 5240452 (flicker and gamescope's own gaming mode shows a corrupted picture on NVIDIA graphics cards: NVIDIA's open bug 5240452 (flicker and
@@ -553,6 +565,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/controllers.sh` | Extended controller support: Xbox wireless dongle (xone) and Xbox Bluetooth (xpadneo) from the CachyOS repo |
| `lib/nvidia.sh` | Gaming on NVIDIA: Steam on the desktop, started at login, optionally in Big Picture (replaces the SteamOS conversion there) | | `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 |
Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 519 KiB

+1 -1
View File
@@ -53,7 +53,7 @@ backend_status() {
items+=",\"on\":$( [[ "$now" == 1 ]] && echo true || echo false)" items+=",\"on\":$( [[ "$now" == 1 ]] && echo true || echo false)"
items+=",\"wanted\":$( [[ "${WANTED[$c]:-0}" == 1 ]] && echo true || echo false)" items+=",\"wanted\":$( [[ "${WANTED[$c]:-0}" == 1 ]] && echo true || echo false)"
items+=",\"update\":$(feature_outdated "$c" && echo true || echo false)" items+=",\"update\":$(feature_outdated "$c" && echo true || echo false)"
items+=",\"new\":$(feature_new "$c" && echo true || echo false)" items+=",\"new\":$({ feature_new "$c" || feature_new_optin "$c"; } && echo true || echo false)"
items+=",\"selectable\":$(component_selectable "$c" && echo true || echo false)" items+=",\"selectable\":$(component_selectable "$c" && echo true || echo false)"
# Why it can't be turned on, for the app's explanation. # Why it can't be turned on, for the app's explanation.
[[ "$c" == vram && -n "${VRAM_NVIDIA_CASE:-}" ]] && [[ "$c" == vram && -n "${VRAM_NVIDIA_CASE:-}" ]] &&
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
# Extended controller support: the Xbox wireless dongle (xone, with its firmware) and Xbox controllers over Bluetooth (xpadneo).
# The kernel has no driver for the dongle, and without xpadneo a Bluetooth Xbox controller works as a plain gamepad (buttons and
# sticks) but misses rumble (trigger motors too), proper button mapping and the battery level. Both are DKMS modules from CachyOS's
# own repo, built for every installed kernel (so every kernel needs its headers). Sourced by steamify.sh; not meant to be run on
# its own.
controller_xone_pkg() {
# A PC with the AUR's xone-dkms-git already works: the repo's xone-dkms would conflict with it.
pacman -Q xone-dkms-git >/dev/null 2>&1 && echo xone-dkms-git || echo xone-dkms
}
controller_pkgs() { echo "xpadneo-dkms $(controller_xone_pkg) xone-dongle-firmware"; }
extended_controller_support_status() {
# shellcheck disable=SC2046 # a list of package names
pacman -Q $(controller_pkgs) >/dev/null 2>&1
}
extended_controller_support_enable() {
local p prev missing=()
info "Installing extended controller support (Xbox wireless dongle, Xbox Bluetooth)..."
install_kernel_headers || return 1
for p in $(controller_pkgs); do pacman -Q "$p" >/dev/null 2>&1 || missing+=("$p"); done
if ((${#missing[@]})); then
sudo pacman -S --needed --noconfirm "${missing[@]}" ||
{ err "Installing ${missing[*]} failed."; return 1; }
# What a first, half-finished run installed stays on the list.
prev="$(state_get extended_controller_support installed_pkgs)"
state_set extended_controller_support installed_pkgs "$(echo "$prev ${missing[*]}" | xargs)"
fi
ok "Extended controller support on: plug the dongle in again (or reconnect the controller) to use it."
}
extended_controller_support_disable() {
local pkgs
pkgs="$(state_get extended_controller_support installed_pkgs)"
# Only what Steamify installed; kernel headers stay.
# shellcheck disable=SC2086 # a list of package names
[[ -n "$pkgs" ]] && sudo pacman -Rns --noconfirm $pkgs >/dev/null 2>&1
state_clear extended_controller_support
ok "Extended controller support off."
}
+28 -12
View File
@@ -5,7 +5,7 @@
# 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 nvidia bigpicture theme glyphs single launcher steamgame notify vram cec machine poweroff kpin hdmi bios) COMPONENTS=(gaming boot nvidia bigpicture theme glyphs single launcher steamgame notify extended_controller_support 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)
@@ -15,8 +15,9 @@ declare -A PARENT=([boot]=gaming [bigpicture]=nvidia [steamgame]=launcher [power
# 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,
# which has CEC like on SteamOS. HDMI refresh boost needs someone at the # which has CEC like on SteamOS. HDMI refresh boost needs someone at the
# screen to confirm each step. # screen to confirm each step. Extended controller support builds kernel modules for
NO_PRESELECT=(boot cec kpin hdmi) # every installed kernel: opt-in.
NO_PRESELECT=(boot cec kpin hdmi extended_controller_support)
# Feature versions: the Steamify version in which what a component's enable # Feature versions: the Steamify version in which what a component's enable
# sets up last changed; set it to the new VERSION whenever you change one. # sets up last changed; set it to the new VERSION whenever you change one.
# Each successful run records it (state "features"); a component that's on # Each successful run records it (state "features"); a component that's on
@@ -26,7 +27,7 @@ NO_PRESELECT=(boot cec kpin hdmi)
FEATURE_BASELINE=2.1.0 FEATURE_BASELINE=2.1.0
declare -A FEATURE_VERSION=( declare -A FEATURE_VERSION=(
[gaming]=2.9.0 [boot]=2.1.0 [nvidia]=2.10.0 [bigpicture]=2.10.0 [theme]=2.1.0 [glyphs]=2.1.0 [single]=2.1.0 [gaming]=2.9.0 [boot]=2.1.0 [nvidia]=2.10.0 [bigpicture]=2.10.0 [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 [extended_controller_support]=2.10.0
[kpin]=2.1.0 [hdmi]=2.1.0 [kpin]=2.1.0 [hdmi]=2.1.0
) )
@@ -41,6 +42,7 @@ declare -A LABEL=(
[launcher]="Steamify shortcut: the app on the desktop, Steamify Terminal in the launcher" [launcher]="Steamify shortcut: the app on the desktop, Steamify Terminal in the launcher"
[steamgame]="Add as non-Steam game: Steamify in your Steam library, for the controller and gaming mode" [steamgame]="Add as non-Steam game: Steamify in your Steam library, for the controller and gaming mode"
[notify]="Update notifications: a notification when there's a new Steamify, never updates by itself" [notify]="Update notifications: a notification when there's a new Steamify, never updates by itself"
[extended_controller_support]="Extended controller support: Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)"
[vram]="VRAM booster: the game in front keeps its VRAM, background apps make room" [vram]="VRAM booster: the game in front keeps its VRAM, background apps make room"
[cec]="HDMI-CEC: use Steam with the TV remote, TV on/off with the PC (experimental)" [cec]="HDMI-CEC: use Steam with the TV remote, TV on/off with the PC (experimental)"
[machine]="Steam Machine support: LED bar driver, hardware settings in Steam" [machine]="Steam Machine support: LED bar driver, hardware settings in Steam"
@@ -122,7 +124,7 @@ menu_label() {
# last run. # last run.
local l="${LABEL[$1]}" b="" local l="${LABEL[$1]}" b=""
if feature_outdated "$1"; then b="${c_yellow}(update)${c_reset}" if feature_outdated "$1"; then b="${c_yellow}(update)${c_reset}"
elif feature_new "$1"; then b="${c_green}(new)${c_reset}"; fi elif feature_new "$1" || feature_new_optin "$1"; then b="${c_green}(new)${c_reset}"; fi
if [[ -n "$b" ]]; then if [[ -n "$b" ]]; then
if [[ "$l" == *:* ]]; then l="${l%%:*} $b:${l#*:}" if [[ "$l" == *:* ]]; then l="${l%%:*} $b:${l#*:}"
else l+=" $b"; fi else l+=" $b"; fi
@@ -130,16 +132,30 @@ menu_label() {
printf '%s' "$l" printf '%s' "$l"
} }
feature_new() { feature_added() {
# A default option added after its parent was set up (e.g. the power-off # An option added after its parent was set up (e.g. the power-off fix under
# fix under Steam Machine support; a top-level one counts the SteamOS # Steam Machine support; a top-level one counts the SteamOS conversion, or
# conversion as its parent): never turned on or off. # "Gaming on NVIDIA" where that replaces it, as its parent), not on yet,
local p="${PARENT[$1]:-gaming}" # with no record: shown as "new".
[[ "$1" != gaming && "${CURRENT[$p]:-0}" == 1 && "${CURRENT[$1]:-0}" == 0 ]] && local p="${PARENT[$1]:-}" parent_on=0
! is_action "$1" && component_selectable "$1" && [[ " ${NO_PRESELECT[*]} " != *" $1 "* ]] && if [[ -n "$p" ]]; then parent_on="${CURRENT[$p]:-0}"
elif [[ "${CURRENT[gaming]:-0}" == 1 || "${CURRENT[nvidia]:-0}" == 1 ]]; then parent_on=1; fi
[[ "$1" != gaming && "$parent_on" == 1 && "${CURRENT[$1]:-0}" == 0 ]] &&
! is_action "$1" && component_selectable "$1" &&
[[ -z "$(state_get features "$1")" ]] [[ -z "$(state_get features "$1")" ]]
} }
feature_new() {
# A new default option: ticked for you (never turned on or off by itself).
feature_added "$1" && [[ " ${NO_PRESELECT[*]} " != *" $1 "* ]]
}
feature_new_optin() {
# A new opt-in option (unticked by default): the "new" badge only, it stays
# unticked. Boot into is a choice row of the conversion, not an item.
feature_added "$1" && [[ "$1" != boot && " ${NO_PRESELECT[*]} " == *" $1 "* ]]
}
component_selectable() { component_selectable() {
# Greyed out and not tickable when it has nothing to do. # Greyed out and not tickable when it has nothing to do.
case "$1" in case "$1" in
+1 -1
View File
@@ -19,7 +19,7 @@ VERSION=2.10.0
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for lib in common state packages login-manager single-user steam-desktop steam-machine fremont-poweroff vram-booster hdmi-refresh nvidia cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut steam-game update-notifier first-login menu backend; do for lib in common state packages login-manager single-user steam-desktop steam-machine fremont-poweroff vram-booster hdmi-refresh nvidia controllers cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut steam-game update-notifier first-login menu backend; do
# shellcheck source=/dev/null # shellcheck source=/dev/null
source "$SCRIPT_DIR/lib/$lib.sh" source "$SCRIPT_DIR/lib/$lib.sh"
done done
+84
View File
@@ -0,0 +1,84 @@
#!/bin/bash
# Tests lib/controllers.sh (extended controller support: xone, the Xbox wireless dongle, and xpadneo, Xbox Bluetooth) with a stub pacman
# and a temp home. No root, VM or hardware needed: bash tests/controllers-test.sh
cd "$(dirname "$0")/.." || exit 1
T="$(mktemp -d)"; trap 'rm -rf "$T"' EXIT
fail=0
check() { if eval "$2"; then echo "ok $1"; else echo "FAIL $1"; fail=1; fi; }
SCRIPT_DIR="$PWD"; HOME="$T/home"; mkdir -p "$HOME"
source lib/common.sh; source lib/state.sh; source lib/controllers.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 $*"; }
kwriteconfig6() { local f="" k="" v=""; while [[ $# -gt 0 ]]; do case "$1" in --file) f="$2"; shift ;; --key) k="$2"; shift ;; --group) shift ;; *) v="$1" ;; esac; shift; done; mkdir -p "$(dirname "$f")"; sed -i "/^$k=/d" "$f" 2>/dev/null; printf '%s=%s\n' "$k" "$v" >> "$f"; }
kreadconfig6() { local f="" k=""; while [[ $# -gt 0 ]]; do case "$1" in --file) f="$2"; shift ;; --key) k="$2"; shift ;; --group|--default) shift ;; esac; shift; done; sed -n "s/^$k=//p" "$f" 2>/dev/null; }
# A pretend package database.
PKGS=""; PACMAN_LOG="$T/pacman.log"; : > "$PACMAN_LOG"; PACMAN_FAIL=0
pacman() {
case "$1" in
-Q) local p; for p in "${@:2}"; do [[ " $PKGS " == *" $p "* ]] || return 1; done ;;
-S) [[ $PACMAN_FAIL == 1 ]] && return 1; echo "S ${*:4}" >> "$PACMAN_LOG"; PKGS+=" ${*:4}" ;;
-Rns) echo "R ${*:3}" >> "$PACMAN_LOG"; local p; for p in ${*:3}; do PKGS=" ${PKGS// $p / } "; done ;;
esac
}
HEADERS=0; install_kernel_headers() { HEADERS=$((HEADERS + 1)); }
check "off to begin with" '! extended_controller_support_status'
extended_controller_support_enable
check "installs the repo's xpadneo-dkms, xone-dkms and the dongle firmware" 'pacman -Q xpadneo-dkms xone-dkms xone-dongle-firmware'
check "kernel headers are made sure of first" '[[ $HEADERS == 1 ]]'
check "what we installed is recorded" '[[ "$(state_get extended_controller_support installed_pkgs)" == "xpadneo-dkms xone-dkms xone-dongle-firmware" ]]'
check "it is on" extended_controller_support_status
n="$(wc -l < "$PACMAN_LOG")"; extended_controller_support_enable
check "a second run installs nothing again" '[[ "$(wc -l < "$PACMAN_LOG")" == "$n" ]]'
extended_controller_support_disable
check "off: the three packages are removed again" '! pacman -Q xpadneo-dkms 2>/dev/null && ! pacman -Q xone-dkms 2>/dev/null && ! pacman -Q xone-dongle-firmware 2>/dev/null && [[ -z "$(state_get extended_controller_support installed_pkgs)" ]]'
# The AUR's xone-dkms-git conflicts with the repo's xone-dkms: it counts, and is kept.
PKGS=" xone-dkms-git xone-dongle-firmware xpadneo-dkms"; : > "$PACMAN_LOG"
check "xone-dkms-git counts as xone: already on" extended_controller_support_status
extended_controller_support_enable; extended_controller_support_disable
check "with xone-dkms-git: nothing installed and nothing removed" '[[ ! -s "$PACMAN_LOG" ]] && pacman -Q xone-dkms-git xpadneo-dkms xone-dongle-firmware'
PKGS=" xone-dkms-git"
extended_controller_support_enable
check "xone-dkms-git present: only the missing ones are installed, never xone-dkms" 'grep -q "^S xpadneo-dkms xone-dongle-firmware$" "$PACMAN_LOG" && ! pacman -Q xone-dkms 2>/dev/null'
extended_controller_support_disable
check "and off removes only those two, xone-dkms-git stays" 'pacman -Q xone-dkms-git && ! pacman -Q xpadneo-dkms 2>/dev/null'
# A failed install is an error and records nothing.
PKGS=""; PACMAN_FAIL=1
check "a failed pacman is an error" '! extended_controller_support_enable >/dev/null'
check "...and records nothing" '[[ -z "$(state_get extended_controller_support installed_pkgs)" ]]'
PACMAN_FAIL=0
# Packages that were already there are never removed by turning it off.
PKGS=" xpadneo-dkms xone-dkms xone-dongle-firmware"; : > "$PACMAN_LOG"
extended_controller_support_enable; extended_controller_support_disable
check "packages you had before stay" 'pacman -Q xpadneo-dkms xone-dkms xone-dongle-firmware && [[ ! -s "$PACMAN_LOG" ]]'
# The menu.
check "offered on every PC" 'component_available extended_controller_support'
check "not preselected: it builds kernel modules for every kernel" '[[ " ${NO_PRESELECT[*]} " == *" extended_controller_support "* ]]'
check "a top-level item with a label" '[[ -z "${PARENT[extended_controller_support]:-}" && -n "${LABEL[extended_controller_support]}" ]]'
# The "new" badge: an opt-in option added after setup shows it, but is never ticked for you.
component_selectable() { return 0; }
declare -A CURRENT=([gaming]=1 [nvidia]=0 [extended_controller_support]=0 [vram]=0 [boot]=0)
rm -f "$STATE_DIR/features.state"
check "new opt-in option (conversion on, no record): the new badge" 'feature_new_optin extended_controller_support'
check "...but it is not ticked for you (not a new default option)" '! feature_new extended_controller_support'
check "...and the menu label says (new)" '[[ "$(menu_label extended_controller_support)" == *"(new)"* ]]'
check "a new default option is still ticked for you, and is not the opt-in kind" 'feature_new vram && ! feature_new_optin vram'
check "Boot into never gets the badge (it is a choice row)" '! feature_new_optin boot'
state_set_features() { kwriteconfig6 --file "$STATE_DIR/features.state" --group State --key "$1" "$2"; }
state_set_features extended_controller_support off
check "once a run recorded it as off, the badge is gone" '! feature_new_optin extended_controller_support'
rm -f "$STATE_DIR/features.state"
CURRENT[gaming]=0; CURRENT[nvidia]=1
check "on an NVIDIA PC (Gaming on NVIDIA on, no conversion) it shows too" 'feature_new_optin extended_controller_support'
CURRENT[nvidia]=0
check "with neither the conversion nor Gaming on NVIDIA on (a fresh PC) nothing is new" '! feature_new_optin extended_controller_support && ! feature_new vram'
CURRENT[gaming]=1; CURRENT[extended_controller_support]=1
check "already on: not new" '! feature_new_optin extended_controller_support'
exit $fail
+3
View File
@@ -33,6 +33,9 @@ QtObject {
notify: { label: "Update notifications", hint: "A notification when there's a new Steamify", notify: { label: "Update notifications", hint: "A notification when there's a new Steamify",
body: "Checks once a day and when you log in to the desktop. When there's a new Steamify you get a notification and a tray icon: open the app to see what's new and choose what to update, or skip that version. It never updates anything by itself.", body: "Checks once a day and when you log in to the desktop. When there's a new Steamify you get a notification and a tray icon: open the app to see what's new and choose what to update, or skip that version. It never updates anything by itself.",
changes: ["A daily check (systemd user timer), only on the desktop", "Tray icon only while an update is waiting", "Skip this version: quiet until the next one"] }, changes: ["A daily check (systemd user timer), only on the desktop", "Tray icon only while an update is waiting", "Skip this version: quiet until the next one"] },
extended_controller_support: { label: "Extended controller support", hint: "Xbox wireless dongle, Xbox controllers over Bluetooth",
body: "Drivers for Xbox controllers that Linux doesn't handle well by itself. xone makes the Xbox wireless dongle work (the kernel has no driver for it), xpadneo gives an Xbox controller over Bluetooth rumble including the triggers, the right button mapping and its battery level. They are built for every installed kernel, which takes a minute or two each.",
changes: ["xone (the dongle) with its firmware, and xpadneo (Bluetooth), from the CachyOS repo", "Kernel headers for every installed kernel, so the drivers build for each", "Off: only what Steamify installed is removed again"] },
vram: { label: "VRAM booster", hint: "The game in front keeps its VRAM", vram: { label: "VRAM booster", hint: "The game in front keeps its VRAM",
body: "Like SteamOS 3.9: the game you're playing keeps its video memory, and background apps are moved out first. Without it a game that needs most of the video memory can spill into system RAM and stutter. Shown for GPUs whose driver supports it (AMD, Intel, NVIDIA with its open kernel modules from driver 615) on kernel 7.2 or newer.", body: "Like SteamOS 3.9: the game you're playing keeps its video memory, and background apps are moved out first. Without it a game that needs most of the video memory can spill into system RAM and stutter. Shown for GPUs whose driver supports it (AMD, Intel, NVIDIA with its open kernel modules from driver 615) on kernel 7.2 or newer.",
changes: ["dmemcg-booster (system and user service)", "plasma-foreground-booster, which tells it which window is in front", "Off: removed again, unless you had installed them yourself"] }, changes: ["dmemcg-booster (system and user service)", "plasma-foreground-booster, which tells it which window is in front", "Off: removed again, unless you had installed them yourself"] },