Merge pull request #26 from theupriser/feat/vram-booster

2.3.0: VRAM booster, New badge
This commit is contained in:
theupriser authored and GitHub committed 2026-09-27 13:05:19 +02:00
commit f774b79007
9 files changed
+186 -29

No files matched your search

+10 -1
View File
@@ -33,7 +33,8 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
`VERSION` whenever what `<id>_enable` sets up changes (a new component gets
one too): installs recorded with an older version
are ticked and re-applied ("update" in the plan and the app). New default
sub-options are ticked for installs whose parent is on (`feature_new`).
options are ticked for installs whose parent (top-level: `gaming`) is on
(`feature_new`, shown as "new").
Status still comes from the system; don't add ad-hoc `<id>_repair` checks
for new changes.
- **Reversibility.** Every per-user KDE setting a component changes goes
@@ -231,6 +232,14 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
`linux-cachyos` is clang-built, `-bore` GCC-built: let DKMS pick the
compiler, never pass `LLVM=1`. Test shutdown on the real machine for every
new major kernel.
- VRAM booster (`vram`, `lib/vram-booster.sh`, top-level, ticked by
default, 2.3.0; only available when `/sys/fs/cgroup/dmem.capacity` lists a
VRAM region of at least 2 GB; greyed out with an NVIDIA card,
`vram_selectable`, faked with `WIZARD_VRAM_FAKE_NVIDIA=1`): CachyOS's `dmemcg-booster` (system + user service) and
`plasma-foreground-booster`, like SteamOS 3.9's VRAM management. The
latter only starts with `kcgroupsrc [Foreground Booster] autostart=true`
(set with `kset`). Disable removes only the packages it installed
(`state_get vram installed_pkgs`).
- `Relogin=true` means a gamescope that fails to start is relaunched in a
tight loop; keep that in mind when changing session handling.
+9 -1
View File
@@ -5,9 +5,17 @@ All notable changes, per version and per commit. Versions follow
`steamify.sh`. Versions before 0.7.0 were numbered afterwards,
one per merged pull request.
## 2.3.0 - 2026-09-27
- **feat: VRAM booster greyed out with an NVIDIA card, with why**
- `b0947d7` **feat: VRAM booster only for GPUs with at least 2 GB of their own VRAM**
- `3f97c85` **feat: VRAM booster for every supported GPU, not only the Steam Machine**
- `fd162c1` **feat: New badge for default sub-options added in this version**
- `54ebddf` **feat: VRAM booster for the Steam Machine**
## 2.2.0 - 2026-09-27
- **docs: Changelog entries per commit for 2.2.0**
- `ef585c0` **docs: Changelog entries per commit for 2.2.0**
- `32795bd` **feat(ui): Update badge on the progress screen**
- `3c8ca65` **fix(ui): Never write the sudo password to a file; Update label on the progress screen**
- The app gave `sudo` the password through a short-lived file; the helper
+6 -1
View File
@@ -28,7 +28,12 @@ Steam Machine.
5. **Steamify shortcut** - "Steamify CachyOS" on the desktop and in the
launcher opens the newest Steamify app, so you don't need the install
command again. "Steamify Terminal" in the launcher opens the terminal menu.
6. **HDMI-CEC** (experimental; off by default, on by default on a Steam
6. **VRAM booster** - on by default: the game you're playing keeps its video
memory and background apps make room, like SteamOS 3.9. Shown for GPUs
whose driver supports it (AMD, Intel) on kernel 7.2 or newer; greyed out
with an NVIDIA card until NVIDIA's driver supports it
([details](TECHNICAL.md#vram-booster)).
7. **HDMI-CEC** (experimental; off by default, on by default on a Steam
Machine) - use Steam with your TV's
remote, and the TV turns on and off with the PC. Needs a PC with CEC (like
the Steam Machine) or a USB CEC adapter; most graphics cards, NVIDIA
+34 -3
View File
@@ -236,6 +236,34 @@ Where Steam Machine support was set up before 2.2.0, the menu ticks the
power-off fix as a new default sub-option (see feature versions below), so a
normal run adds it.
## VRAM booster
SteamOS 3.9 manages the dGPU's VRAM per cgroup: the game in front is
protected, background apps are evicted first. Without it a game that needs
most of the VRAM (8 GB on the Steam Machine) can be pushed into system RAM
by the desktop and other apps, and stutter. The kernel side is the `dmem`
cgroup controller (7.2); amdgpu and Intel's xe register their VRAM with it,
NVIDIA's driver doesn't: with an NVIDIA card the option is shown greyed
out, with why (`WIZARD_VRAM_FAKE_NVIDIA=1` fakes that for tests). Otherwise
the **VRAM booster** option is only shown when
`/sys/fs/cgroup/dmem.capacity` lists a VRAM region of at least 2 GB (a
dedicated GPU; an integrated one registers a small carve-out) or it's already on, and is
ticked by default; new in 2.3.0, so setups with the SteamOS conversion on
get it ticked. CachyOS packages the userspace side, which it installs:
- `dmemcg-booster`: `dmemcg-booster-system.service` enables the `dmem`
controller and sets `dmem.low` for the cgroup in front;
`dmemcg-booster-user.service` runs in the user session.
- `plasma-foreground-booster`: tells it which window is in front on the
desktop. It only starts with `autostart=true` under `[Foreground Booster]`
in `kcgroupsrc`, which the wizard sets (and reverts).
Check it with `cat /sys/fs/cgroup/cgroup.subtree_control` (lists `dmem`) and
the `dmem.low` of the slices under `user@<uid>.service`. Turning it off
disables the services and removes the packages the wizard installed.
Not added: a fixed `dmem.max` cap for `app.slice` (as some guides do); only
worth it if the booster itself turns out to cause stutter.
## Feature versions (updates)
Each component has a feature version (`FEATURE_VERSION` in `lib/menu.sh`):
@@ -250,9 +278,11 @@ on the system itself; the version only decides about updates:
"update". A setup from before versions were recorded counts as 2.1.0,
so on a machine set up with 2.1.0, Steam Machine support (2.2.0) is
updated.
- **A new default sub-option** (not in `NO_PRESELECT`) whose parent is on
and that was never turned on or off: ticked, so a normal run adds it.
Turning it off once records `off`, so it isn't ticked again.
- **A new default option** (not in `NO_PRESELECT`) whose parent is on (for
a top-level one: the SteamOS conversion) and that was never turned on or
off: ticked, so a normal run adds it. Turning it off once records `off`,
so it isn't ticked again. The menu and the app show it with a **New**
badge, and the plan says "new in this version".
Set a component's entry to the new `VERSION` whenever what its
`<id>_enable` sets up changes.
@@ -327,6 +357,7 @@ immediately, which can turn into a loop - see
| `lib/cec.sh` | HDMI-CEC: Valve's `cecd` and friends from its `holo` repository |
| `lib/steam-machine.sh` | Steam Machine support: LED driver, LED access, steamos-manager |
| `lib/fremont-poweroff.sh` | Steam Machine support: the power-off fix (DKMS module from `patches/`) |
| `lib/vram-booster.sh` | VRAM booster (`dmemcg-booster`, `plasma-foreground-booster`) |
| `patches/` | Module sources and patches the scripts build or apply (`patch_file`); see its README |
| `.github/tools/bundle.sh` | Builds the single-file version (`dist/steamify.sh`), with `patches/` embedded |
| `.github/workflows/bundle.yml` | Builds and checks it on every push; publishes it on `main` |
+1
View File
@@ -63,6 +63,7 @@ backend_status() {
items+=",\"on\":$( [[ "$now" == 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+=",\"new\":$(feature_new "$c" && echo true || echo false)"
items+=",\"selectable\":$(component_selectable "$c" && echo true || echo false)}"
done
local cec="" f
+22 -12
View File
@@ -5,7 +5,7 @@
# Menu order. Components are turned on in this order and off in reverse;
# gaming must come first (single user builds on it).
COMPONENTS=(gaming boot theme glyphs single launcher cec machine poweroff kpin hdmi bios)
COMPONENTS=(gaming boot theme glyphs single launcher vram cec machine poweroff kpin hdmi bios)
# One-off actions rather than on/off components: never preselected, never
# re-applied, not listed as on or off.
ACTIONS=(bios)
@@ -26,7 +26,7 @@ NO_PRESELECT=(boot cec kpin hdmi)
FEATURE_BASELINE=2.1.0
declare -A FEATURE_VERSION=(
[gaming]=2.1.0 [boot]=2.1.0 [theme]=2.1.0 [glyphs]=2.1.0 [single]=2.1.0
[launcher]=2.1.0 [cec]=2.1.0 [machine]=2.2.0 [poweroff]=2.2.0
[launcher]=2.1.0 [cec]=2.1.0 [machine]=2.2.0 [poweroff]=2.2.0 [vram]=2.3.0
[kpin]=2.1.0 [hdmi]=2.1.0
)
@@ -37,6 +37,7 @@ declare -A LABEL=(
[glyphs]="Install Steam Deck/Machine icons: Deck button icons in gaming mode"
[single]="Single user mode: no password, lock screen or log out (SDDM)"
[launcher]="Steamify shortcut: the app on the desktop, Steamify Terminal in the launcher"
[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)"
[machine]="Steam Machine support: LED bar driver, hardware settings in Steam"
[poweroff]="Power-off fix: the Steam Machine stays off after shutting down"
@@ -49,6 +50,7 @@ declare -A CURRENT WANTED
component_available() {
case "$1" in
machine|poweroff) machine_available ;;
vram) vram_available ;;
kpin) kpin_available ;;
hdmi) hdmi_available ;;
bios) bios_available ;;
@@ -89,20 +91,25 @@ feature_outdated() {
menu_label() {
# The label, with "(update)" after the name when a newer version of it
# will be applied.
local l="${LABEL[$1]}"
if feature_outdated "$1"; then
if [[ "$l" == *:* ]]; then l="${l%%:*} ${c_yellow}(update)${c_reset}:${l#*:}"
else l+=" ${c_yellow}(update)${c_reset}"; fi
# will be applied, "(new)" for a default sub-option added since the
# last run.
local l="${LABEL[$1]}" b=""
if feature_outdated "$1"; then b="${c_yellow}(update)${c_reset}"
elif feature_new "$1"; then b="${c_green}(new)${c_reset}"; fi
if [[ -n "$b" ]]; then
if [[ "$l" == *:* ]]; then l="${l%%:*} $b:${l#*:}"
else l+=" $b"; fi
fi
printf '%s' "$l"
}
feature_new() {
# A default sub-option added after its parent was set up (e.g. the
# power-off fix under Steam Machine support): never turned on or off.
[[ -n "${PARENT[$1]:-}" && "${CURRENT[${PARENT[$1]}]:-0}" == 1 && "${CURRENT[$1]:-0}" == 0 ]] &&
! is_action "$1" && [[ " ${NO_PRESELECT[*]} " != *" $1 "* ]] &&
# A default option added after its parent was set up (e.g. the power-off
# fix under Steam Machine support; a top-level one counts the SteamOS
# conversion as its parent): never turned on or off.
local p="${PARENT[$1]:-gaming}"
[[ "$1" != gaming && "${CURRENT[$p]:-0}" == 1 && "${CURRENT[$1]:-0}" == 0 ]] &&
! is_action "$1" && component_selectable "$1" && [[ " ${NO_PRESELECT[*]} " != *" $1 "* ]] &&
[[ -z "$(state_get features "$1")" ]]
}
@@ -110,6 +117,7 @@ component_selectable() {
# Greyed out and not tickable when it has nothing to do.
case "$1" in
bios) bios_selectable ;;
vram) vram_selectable ;;
esac
}
@@ -138,10 +146,12 @@ detect_components() {
launcher_repair && WANTED[launcher]=1
# Shows the current and newest BIOS version.
bios_available && { bios_lookup_newest; LABEL[bios]="$(bios_label)"; }
# Greyed out with an NVIDIA card: say why.
component_available vram && ! vram_selectable && LABEL[vram]="VRAM booster: not supported by NVIDIA's driver yet"
# First run: preselect the full SteamOS experience (never an action).
if [[ "$any" == false ]]; then
for c in "${COMPONENTS[@]}"; do
component_available "$c" && ! is_action "$c" &&
component_available "$c" && component_selectable "$c" && ! is_action "$c" &&
[[ " ${NO_PRESELECT[*]} " != *" $c "* ]] && WANTED[$c]=1
done
machine_available && WANTED[cec]=1
+78
View File
@@ -0,0 +1,78 @@
#!/bin/bash
# "VRAM booster" menu item (vram), ticked by default, like SteamOS 3.9's
# dGPU VRAM management: the game in front keeps its VRAM, background apps
# are evicted first, so a game that needs most of it doesn't spill into
# system RAM and stutter. The kernel side is the dmem cgroup controller
# (7.2; amdgpu and xe register their VRAM, NVIDIA's driver doesn't), so it's
# only offered when the kernel lists a VRAM region of at least 2 GB. CachyOS packages the userspace
# side: dmemcg-booster (a system service that enables the controller and
# sets the limits, plus a user service) and plasma-foreground-booster, which
# tells it which window is in front on the desktop. The latter only starts
# with "autostart" set in kcgroupsrc.
# Sourced by steamify.sh; not meant to be run on its own.
VRAM_PKGS=(dmemcg-booster plasma-foreground-booster)
VRAM_MIN_BYTES=$((2 * 1024 * 1024 * 1024))
vram_supported() {
# WIZARD_VRAM_FAKE_NVIDIA=1 (tests): as with an NVIDIA card.
[[ -n "${WIZARD_VRAM_FAKE_NVIDIA:-}" ]] && return 1
# Only for a GPU with its own VRAM: an integrated GPU registers a small
# carve-out too, but mostly uses system RAM, so there's little to boost.
awk -v min="$VRAM_MIN_BYTES" '$1 ~ /\/vram$/ && $2 >= min { found = 1 } END { exit !found }' \
/sys/fs/cgroup/dmem.capacity 2>/dev/null
}
vram_nvidia() {
# An NVIDIA display controller (PCI vendor 10de, class 03xxxx).
local d
[[ -n "${WIZARD_VRAM_FAKE_NVIDIA:-}" ]] && return 0
for d in /sys/bus/pci/devices/*; do
[[ "$(cat "$d/vendor" 2>/dev/null)" == 0x10de && "$(cat "$d/class" 2>/dev/null)" == 0x03* ]] && return 0
done
return 1
}
# Shown where it works, and greyed out with an NVIDIA card, whose driver
# doesn't register its VRAM with the kernel (yet): so it's clear why it
# can't be turned on. Hidden elsewhere (integrated graphics, older kernel).
vram_available() { vram_supported || vram_status || vram_nvidia; }
vram_selectable() { vram_supported || vram_status; }
vram_status() {
pacman -Q "${VRAM_PKGS[@]}" >/dev/null 2>&1 &&
systemctl is-enabled -q dmemcg-booster-system.service 2>/dev/null &&
systemctl --user is-enabled -q dmemcg-booster-user.service 2>/dev/null
}
vram_enable() {
local p missing=()
info "Installing the VRAM booster (the game in front keeps its VRAM)..."
for p in "${VRAM_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; }
state_set vram installed_pkgs "${missing[*]}"
fi
sudo systemctl enable --now dmemcg-booster-system.service >/dev/null 2>&1 ||
{ err "Starting dmemcg-booster failed."; return 1; }
systemctl --user enable --now dmemcg-booster-user.service >/dev/null 2>&1 ||
{ err "Starting dmemcg-booster for $USER failed."; return 1; }
kset vram kcgroupsrc "Foreground Booster" autostart true
# Started by the Plasma session from now on; start it in this one too.
[[ "${XDG_CURRENT_DESKTOP:-}" == KDE ]] &&
systemctl --user start plasma-foreground-booster.service >/dev/null 2>&1
ok "VRAM booster on: the game in front keeps its VRAM."
}
vram_disable() {
local pkgs
systemctl --user disable --now plasma-foreground-booster.service dmemcg-booster-user.service >/dev/null 2>&1
sudo systemctl disable --now dmemcg-booster-system.service >/dev/null 2>&1
krevert vram
pkgs="$(state_get vram installed_pkgs)"
# shellcheck disable=SC2086 # a list of package names
[[ -n "$pkgs" ]] && sudo pacman -Rns --noconfirm $pkgs >/dev/null 2>&1
state_clear vram
ok "VRAM booster off."
}
+5 -3
View File
@@ -15,11 +15,11 @@
set -uo pipefail
# Release version, see CHANGELOG.md.
VERSION=2.2.0
VERSION=2.3.0
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for lib in common state packages login-manager single-user steam-desktop steam-machine fremont-poweroff hdmi-refresh cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut menu backend; do
for lib in common state packages login-manager single-user steam-desktop steam-machine fremont-poweroff vram-booster hdmi-refresh cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut menu backend; do
# shellcheck source=/dev/null
source "$SCRIPT_DIR/lib/$lib.sh"
done
@@ -140,7 +140,9 @@ while true; do
if [[ "$c" == boot ]]; then echo " - boot into: desktop (from the next boot)"
elif is_action "$c"; then echo " - run: ${LABEL[$c]%%:*} at your own risk (checks, then asks twice more)"
elif feature_outdated "$c"; then echo " - update: ${LABEL[$c]} (changed in this version)"
elif [[ "${CURRENT[$c]}" == 1 ]]; then echo " - re-apply: ${LABEL[$c]}"; else echo " - turn on: ${LABEL[$c]}"; fi
elif [[ "${CURRENT[$c]}" == 1 ]]; then echo " - re-apply: ${LABEL[$c]}"
elif feature_new "$c"; then echo " - turn on: ${LABEL[$c]} (new in this version)"
else echo " - turn on: ${LABEL[$c]}"; fi
done
ask_yn "Go ahead?" y || { info "Nothing changed."; continue; }
+21 -8
View File
@@ -45,6 +45,11 @@ ApplicationWindow {
}
// --- Texts per item (the backend's labels are the fallback) ---
// Replaces the explanation of an option that can't be turned on here.
readonly property var unsupported: ({
vram: { body: "Not available with your NVIDIA graphics card: NVIDIA's driver doesn't tell Linux how its video memory is used yet, so there's nothing to steer. It works with AMD and Intel graphics cards, and shows up here as soon as NVIDIA's driver supports it.",
changes: ["Nothing: can't be turned on with NVIDIA's driver"] }
})
readonly property var texts: ({
gaming: { label: "SteamOS conversion", hint: "Boot into gaming mode, Steam on the desktop",
body: "Boots straight into gaming mode. Switch to Desktop in Steam works, and Return to Gaming Mode on the desktop brings you back.",
@@ -72,6 +77,9 @@ ApplicationWindow {
poweroff: { label: "Power-off fix", hint: "Stays off after shutting down",
body: "With recent kernels the Steam Machine starts again right after shutting down: the firmware leaves a wake bit set, and newer kernels (7.2, and updates of 6.x, 7.0 and 7.1) no longer clear it. Valve's own kernel clears it; this small module does the same right before power-off.",
changes: ["steamify-fremont-poweroff module for each installed kernel (DKMS)", "Only on a Steam Machine, only touches that one wake bit", "Off: recent kernels may start it again after shutting down"] },
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) 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"] },
kpin: { label: "Pin the kernel", hint: "Untick for CachyOS's current kernel",
body: "Keeps the Steam Machine on CachyOS kernel 7.1.6. Untick it to go back to CachyOS's current kernel; HDMI refresh boost goes with it.",
changes: ["linux-cachyos from Steamify's release (signature checked)", "Kept in /var/cache/steamify/kernel", "Added to IgnorePkg"] },
@@ -241,6 +249,8 @@ ApplicationWindow {
function toggle(id) {
hdmiNote = "";
var cur = items.find(function (i) { return i.id === id; });
if (cur && cur.kind === "toggle" && cur.selectable === false) return;
var w = Object.assign({}, want);
w[id] = !w[id];
if (id === "gaming" && !w.gaming) { w.single = false; }
@@ -264,7 +274,7 @@ ApplicationWindow {
var it = items[i];
if (it.kind !== "toggle") continue;
if (it.parent && !want[it.parent]) { if (it.on) p.push({ id: it.id, action: "off" }); continue; }
if (want[it.id] && !it.on) p.push({ id: it.id, action: "on" });
if (want[it.id] && !it.on) p.push({ id: it.id, action: "on", isNew: !!it["new"] });
else if (!want[it.id] && it.on) p.push({ id: it.id, action: "off" });
else if (want[it.id] && (reapply || it.update)) p.push({ id: it.id, action: reapply ? "again" : "update" });
}
@@ -626,17 +636,19 @@ ApplicationWindow {
anchors.verticalCenter: parent.verticalCenter; spacing: 2
x: row.modelData.parent ? 46 : 16
width: controls.x - x - 16
opacity: row.modelData.kind === "action" && !(bios && bios.selectable) ? 0.6 : 1
// The name, with an Update badge when a newer version of it will be applied.
opacity: (row.modelData.kind === "action" && !(bios && bios.selectable)) || (row.modelData.kind === "toggle" && row.modelData.selectable === false) ? 0.6 : 1
// The name, with an Update badge when a newer version of it will be
// applied, New for a default sub-option added since the last run.
Row { width: parent.width; spacing: 10
Text { text: label(row.modelData); color: t.textHi; font.family: t.body; font.pixelSize: 17; font.weight: Font.DemiBold; elide: Text.ElideRight
width: Math.min(implicitWidth, parent.width - (upd.visible ? upd.width + parent.spacing : 0)) }
Chip { id: upd; visible: !!row.modelData.update; text: "Update"; fg: t.warn; bgc: t.warnBg; height: 20; anchors.verticalCenter: parent.verticalCenter } }
Text { text: row.modelData.id === "bios" ? biosHint() : ((row.modelData.id === "hdmi" && hdmiRowHint()) || (texts[row.modelData.id] && texts[row.modelData.id].hint) || row.modelData.hint); color: t.mute; font.family: t.body; font.pixelSize: 13; elide: Text.ElideRight; width: parent.width }
Chip { id: upd; visible: !!row.modelData.update || !!row.modelData["new"]; text: row.modelData.update ? "Update" : "New"; fg: row.modelData.update ? t.warn : t.good; bgc: row.modelData.update ? t.warnBg : t.goodBg; height: 20; anchors.verticalCenter: parent.verticalCenter } }
Text { text: row.modelData.id === "bios" ? biosHint() : row.modelData.selectable === false ? row.modelData.hint : ((row.modelData.id === "hdmi" && hdmiRowHint()) || (texts[row.modelData.id] && texts[row.modelData.id].hint) || row.modelData.hint); color: t.mute; font.family: t.body; font.pixelSize: 13; elide: Text.ElideRight; width: parent.width }
}
// Right: every control ends on the same edge
Item {
id: controls
opacity: row.modelData.kind === "toggle" && row.modelData.selectable === false ? 0.4 : 1
anchors.right: parent.right; anchors.rightMargin: 16; anchors.verticalCenter: parent.verticalCenter
width: 180; height: 32
// choice
@@ -678,7 +690,7 @@ ApplicationWindow {
id: detail
width: parent.width; height: parent.height - sys.height - 16; radius: 16; color: t.card
readonly property var it: sel < rows.length ? rows[sel] : null
readonly property var tx: it ? (texts[it.id] || {}) : {}
readonly property var tx: it ? (it.selectable === false && unsupported[it.id] ? Object.assign({}, texts[it.id], unsupported[it.id]) : (texts[it.id] || {})) : {}
// Long texts scroll instead of running out of the card;
// each item starts at the top.
onItChanged: detailFlick.contentY = 0
@@ -763,6 +775,7 @@ ApplicationWindow {
Row { anchors.fill: parent; anchors.leftMargin: 18; spacing: 14
Chip { text: parent.parent.st[0]; fg: parent.parent.st[1]; bgc: parent.parent.st[2]; width: 84; anchors.verticalCenter: parent.verticalCenter }
Text { text: (texts[parent.parent.modelData.id] || {}).label || parent.parent.modelData.id; color: t.textHi; font.family: t.body; font.pixelSize: 17; font.weight: Font.DemiBold; anchors.verticalCenter: parent.verticalCenter }
Chip { visible: !!parent.parent.modelData.isNew; text: "New"; fg: t.good; bgc: t.goodBg; height: 20; anchors.verticalCenter: parent.verticalCenter }
}
}
}
@@ -858,7 +871,7 @@ ApplicationWindow {
border.width: parent.parent.st === "wait" || parent.parent.st === "run" ? 2 : 0; border.color: parent.parent.st === "run" ? t.accent : "#343f50"
Text { anchors.centerIn: parent; text: parent.parent.parent.st === "ok" ? "✓" : (parent.parent.parent.st === "fail" ? "!" : ""); color: parent.parent.parent.st === "ok" ? t.good : t.bad; font.pixelSize: 13; font.weight: Font.Bold }
RotationAnimator on rotation { running: parent.parent.parent.st === "run"; from: 0; to: 360; duration: 1000; loops: Animation.Infinite } }
// The step; an update shows the name with an Update badge, like the menu.
// The step; an update or new sub-option shows its badge, like the menu.
Item { width: 380; height: parent.height
readonly property var step: parent.parent.modelData
readonly property bool update: step.action === "update"
@@ -866,7 +879,7 @@ ApplicationWindow {
Text { text: (({ on: "Turn on ", off: "Turn off ", again: "Re-apply ", desktop: "Boot into ", gaming: "Boot into ", check: "Download and check the ", flash: "Hand to fwupd: the " })[parent.parent.step.action] || "") + ((texts[parent.parent.step.id] || {}).label || parent.parent.step.id)
color: parent.parent.parent.parent.st === "wait" ? t.faint : t.textHi; font.family: t.body; font.pixelSize: 16; font.weight: Font.DemiBold; anchors.verticalCenter: parent.verticalCenter; elide: Text.ElideRight
width: Math.min(implicitWidth, parent.width - (stepUpd.visible ? stepUpd.width + parent.spacing : 0)) }
Chip { id: stepUpd; visible: parent.parent.update; text: "Update"; fg: t.warn; bgc: t.warnBg; height: 20; anchors.verticalCenter: parent.verticalCenter } } }
Chip { id: stepUpd; visible: parent.parent.update || !!parent.parent.step.isNew; text: parent.parent.update ? "Update" : "New"; fg: parent.parent.update ? t.warn : t.good; bgc: parent.parent.update ? t.warnBg : t.goodBg; height: 20; anchors.verticalCenter: parent.verticalCenter } } }
Text { text: ({ wait: "Waiting", run: "Working…", ok: "Done", fail: "Problem" })[parent.parent.st]; color: parent.parent.st === "ok" ? t.good : (parent.parent.st === "fail" ? t.bad : "#b8c3d1"); font.family: t.body; font.pixelSize: 13; anchors.verticalCenter: parent.verticalCenter }
}
}