Compare commits

...
6 Commits
Author SHA1 Message Date
theupriser 45ff036f09 Merge pull request #13 from theupriser/feat/hdmi-cec
Feat/hdmi cec
2026-09-25 09:53:29 +02:00
theupriser de02f267f4 docs: README's Steam Machine part lists its features, HDMI-CEC included 2026-09-25 09:50:55 +02:00
theupriser 0f123004d0 docs: CEC.md, which PCs have HDMI-CEC and how to add it 2026-09-25 09:47:22 +02:00
theupriser 3048b35dd8 feat: HDMI-CEC ticked by default on a Steam Machine 2026-09-25 09:18:28 +02:00
theupriser f7837f82b9 fix: Restart steamos-manager after HDMI-CEC changes
It only offers Steam its HDMI-CEC settings when cecd was there at its start.
2026-09-25 09:17:05 +02:00
theupriser 3eb41eef5a feat: HDMI-CEC with Valve's cecd, on any PC
Opt-in menu item: cecd, cec-audio-control and inputattach-cec-units from
Valve's holo repository (SHA-256 checked). Works with any /dev/cec*.
2026-09-25 09:11:44 +02:00
9 changed files with 237 additions and 9 deletions

No files matched your search

+48
View File
@@ -0,0 +1,48 @@
# HDMI-CEC: does my PC have it?
The **HDMI-CEC** item in Steamify lets you use Steam with your TV's remote,
and turns the TV on and off with the PC. It only works when the PC has a
CEC device (`/dev/cec*`). Many PCs don't: on desktop PCs CEC is rare.
How it works: [TECHNICAL.md](TECHNICAL.md#hdmi-cec); problems:
[TROUBLESHOOTING.md](TROUBLESHOOTING.md#the-tv-remote-does-nothing-hdmi-cec).
## Graphics cards
- **NVIDIA:** no. The driver doesn't expose CEC on the HDMI port, on Linux
or Windows.
- **AMD and Intel:** the CEC line of the HDMI port is normally not
connected on desktop cards. The Linux drivers (`amdgpu`, `i915`) only
support CEC over a **DisplayPort** connection: some DisplayPort-to-HDMI
adapters and built-in converter chips pass CEC along ("DP-AUX CEC"). That
depends on the adapter or chip, not on the graphics card, so it's worth
trying a different adapter.
## Devices with CEC built in
- the **Valve Steam Machine** (Steamify ticks HDMI-CEC by default there);
- some **Intel NUC** mini PCs, which have a CEC chip on the board;
- the **Raspberry Pi**.
## Any PC: a USB CEC adapter
A USB CEC adapter, such as the **Pulse-Eight USB-CEC adapter** (or a
RainShadow Tech one), sits between the PC and the TV on the HDMI cable and
works on Linux. This is the way to get CEC on a custom build, e.g. with an
NVIDIA card. Steamify installs what these adapters need
(`inputattach-cec-units`), so plug it in and turn on HDMI-CEC.
## Check your PC
After turning on HDMI-CEC in Steamify, the menu lists the CEC devices it
found. Or run:
```bash
ls /dev/cec*
```
No device (and no USB adapter): no CEC on this PC. Also turn on CEC on the
TV itself: it has a brand name there (Sony: BRAVIA Sync, Samsung: Anynet+,
LG: SimpLink, Philips: EasyLink, Panasonic: VIERA Link).
This overview is based on how the Linux drivers work; hardware differs,
so the only sure test is `ls /dev/cec*` on your own PC.
+16
View File
@@ -5,6 +5,22 @@ 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.
## 1.1.0 - 2026-09-25
- **feat: HDMI-CEC** (experimental, on every PC; ticked by default only on a
Steam Machine)
- Valve's `cecd`, `cec-audio-control` and `inputattach-cec-units` from its
SteamOS repository (SHA-256 checked): use Steam with the TV remote, and
the TV turns on and off with the PC. On a Steam Machine, steamos-manager
configures it from Steam's settings.
- Works with any `/dev/cec*` (GPU or USB adapter); the menu lists them.
- `CEC.md`: which PCs have CEC (NVIDIA doesn't, AMD/Intel only over some
DisplayPort adapters), and USB adapters for your own build.
- Restarts steamos-manager, which only offers Steam its HDMI-CEC settings
when cecd was there at its start.
- The README no longer says Steam Machine support alone gives HDMI-CEC:
`cecd` wasn't installed, so it didn't.
## 1.0.0 - 2026-09-25
- **feat: Pin the kernel to 7.1.6-1 on a Steam Machine**
+11 -2
View File
@@ -27,13 +27,22 @@ Steam Machine.
([details](TECHNICAL.md#single-user-mode-sddm-no-locking)).
5. **Steamify shortcut** - an icon on the desktop and in the launcher that
opens the newest Steamify, so you don't need the install command again.
6. **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
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)).
## Steam Machine
On a Valve Steam Machine the menu has two more items:
What Steamify can do on a Valve Steam Machine:
- **HDMI-CEC** - ticked by default here, as on SteamOS: use Steam with your
TV's remote, and the TV turns on and off with the Steam Machine
([details](TECHNICAL.md#hdmi-cec)).
- **Steam Machine support** - the front **LED bar** works, Steam's
**hardware settings** (fan, TV control over HDMI-CEC) work, and the power
**hardware settings** (fan, performance) work, and the power
button puts it to sleep like a console.
- **Pin the kernel to 7.1.6-1** - on by default: with newer CachyOS kernels
the Steam Machine reboots instead of shutting down. Untick it once CachyOS
+36 -2
View File
@@ -154,8 +154,9 @@ The **Steam Machine support** component, only shown on Fremont hardware
- console-like power button: it puts the machine to sleep, and it never
suspends by itself on mains power (the launcher's Shut Down still shuts down);
- installs and enables `steamos-manager`, the service Steam in gaming mode
uses for hardware settings (fan, HDMI-CEC, performance); it recognises the
Steam Machine from its DMI data.
uses for hardware settings (fan, performance, and the HDMI-CEC settings
when [HDMI-CEC](#hdmi-cec) is on); it recognises the Steam Machine from its
DMI data.
Turning it off removes all of that again (the AUR helper is kept).
@@ -168,6 +169,38 @@ or upgraded. A newly added kernel doesn't come with its headers, so
`ensure-kernel-headers.service` checks at every boot and installs any
missing `-headers` package, which makes DKMS build the driver for it.
## HDMI-CEC
The **HDMI-CEC** item (on every PC; ticked by default only on a Steam
Machine) installs
Valve's CEC stack from its SteamOS `holo` repository, the newest `holo-X.Y`
on `steamdeck-packages.steamos.cloud`, each package checked against the
SHA-256 in Valve's package index:
- `cecd`, Valve's CEC daemon (a user service started with the desktop and
gaming mode): TV remote keys become normal key presses (arrows, Enter,
Back), and it turns the TV on and off with the PC;
- `cec-audio-control`: volume of the TV or receiver;
- `inputattach-cec-units` (with `linuxconsole` from CachyOS for
`inputattach`): attaches USB CEC adapters (Pulse-Eight, RainShadow).
It works with any `/dev/cec*`: a GPU that has CEC on its HDMI port (the
Steam Machine; the CachyOS kernel has DisplayPort CEC built in) or a USB
adapter ([CEC.md](CEC.md) lists which PCs have one). The menu lists the CEC
devices found. Also turn on CEC on the TV
(Sony: BRAVIA Sync, Samsung: Anynet+, LG: SimpLink). On a Steam Machine
`steamos-manager` writes cecd's settings from Steam's (wake the TV, put it to
sleep), in `~/.config/cecd/config.d/`, and Steam shows its HDMI-CEC
settings; the wizard restarts steamos-manager so that happens right away.
It's experimental: on SteamOS itself CEC can wake the Steam Machine right
after it goes to sleep (Samsung TVs,
[SteamOS#2626](https://github.com/ValveSoftware/SteamOS/issues/2626)) and
upset CEC for the TV's other devices
([SteamOS#2817](https://github.com/ValveSoftware/SteamOS/issues/2817)).
Turning it off removes the packages again (`linuxconsole` only if the
wizard installed it).
## Kernel pin (Steam Machine)
With CachyOS kernels newer than 7.1.6 a Steam Machine reboots instead of
@@ -256,6 +289,7 @@ immediately, which can turn into a loop - see
| `lib/single-user.sh` | Single user mode: no lock screen, user switching or log out |
| `lib/wizard-shortcut.sh` | Steamify shortcut: desktop icon and launcher entry that run the newest release |
| `lib/bios.sh` | Update BIOS (Steam Machine, opt-in): current/newest version, double confirmation, fwupd |
| `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; kernel pin |
| `.github/tools/bundle.sh` | Builds the single-file version (`dist/steamify.sh`) |
| `.github/workflows/bundle.yml` | Builds and checks it on every push; publishes it on `main` |
+18
View File
@@ -32,6 +32,24 @@ cat /var/lib/dkms/leds-valve-dkms/0.1/build/make.log
journalctl --user -b | grep -i led
```
## The TV remote does nothing (HDMI-CEC)
- Turn on CEC in the TV's settings (Sony: BRAVIA Sync, Samsung: Anynet+, LG:
SimpLink) and, if it has one, allow the PC to control it.
- Check that the PC has a CEC device, and that `cecd` runs:
```bash
ls /dev/cec*
systemctl --user status cecd
journalctl --user -u cecd -b
cec-ctl -d /dev/cec0 -S # the devices on the TV's CEC bus (v4l-utils)
```
No `/dev/cec*`: your PC has no CEC; a USB CEC adapter (e.g. Pulse-Eight)
works. See [CEC.md](CEC.md). The Steam Machine wakes up again right after going
to sleep, or other devices lose CEC? That happens on SteamOS too; turn
HDMI-CEC off in the wizard.
## The Steam Machine still reboots when I shut it down
Check that the pinned kernel is installed and running:
+98
View File
@@ -0,0 +1,98 @@
#!/bin/bash
# "HDMI-CEC" menu item, on any PC: Valve's CEC daemon (cecd), TV/receiver
# volume control (cec-audio-control) and the units that attach USB CEC
# adapters (Pulse-Eight, RainShadow) with inputattach. They're only in
# Valve's SteamOS (holo) repository, not in CachyOS or the AUR. Works with
# any /dev/cec*: a GPU with CEC (e.g. the Steam Machine) or a USB adapter.
# On a Steam Machine, steamos-manager configures cecd from Steam's settings.
# Sourced by steamify.sh; not meant to be run on its own.
CEC_PKGS=(cecd cec-audio-control inputattach-cec-units)
restart_steamos_manager() {
# steamos-manager only offers its HDMI-CEC interface (Steam's CEC
# settings) when cecd was there at its start.
systemctl --user is-active -q steamos-manager.service 2>/dev/null &&
systemctl --user restart steamos-manager.service
return 0
}
cec_status() { pacman -Q "${CEC_PKGS[@]}" >/dev/null 2>&1; }
fetch_holo_pkg() {
# fetch_holo_pkg <dir> <package>: download the newest <package> from
# Valve's newest holo repository into <dir> and print its path. The
# SHA-256 comes from Valve's package index and is verified.
local dir="$1" name="$2" repo desc file_name sha256
repo="$(curl -fsL "$VALVE_MIRROR/" | grep -oE 'holo-[0-9]+\.[0-9]+/' | tr -d / | sort -V | tail -n 1)"
if [[ ! -f "$dir/holo.db" ]]; then
[[ -n "$repo" ]] && curl -fsL "$VALVE_MIRROR/$repo/os/x86_64/$repo.db" -o "$dir/holo.db" ||
{ err "Couldn't read Valve's SteamOS package index ($VALVE_MIRROR)."; return 1; }
fi
desc="$(tar -tf "$dir/holo.db" 2>/dev/null | grep -E "^$name-[0-9][^/]*/desc$" | head -n 1)"
[[ -n "$desc" ]] || { err "No $name in Valve's $repo repository."; return 1; }
file_name="$(tar -xOf "$dir/holo.db" "$desc" | awk '/^%FILENAME%$/ { getline; print }')"
sha256="$(tar -xOf "$dir/holo.db" "$desc" | awk '/^%SHA256SUM%$/ { getline; print }')"
info "Downloading $file_name ($repo)..." >&2
curl -fsL "$VALVE_MIRROR/$repo/os/x86_64/$file_name" -o "$dir/$file_name" ||
{ err "Downloading $file_name failed."; return 1; }
echo "$sha256 $dir/$file_name" | sha256sum -c --quiet - >&2 ||
{ err "Checksum mismatch for $file_name; not using it."; return 1; }
echo "$dir/$file_name"
}
cec_enable() {
local tmp p f files=()
# inputattach, needed by inputattach-cec-units.
if ! pacman -Q linuxconsole >/dev/null 2>&1; then
sudo pacman -S --needed --noconfirm linuxconsole || { err "Installing linuxconsole failed."; return 1; }
state_set cec installed_linuxconsole 1
fi
tmp="$(mktemp -d)"
for p in "${CEC_PKGS[@]}"; do
f="$(fetch_holo_pkg "$tmp" "$p")" || { rm -rf "$tmp"; return 1; }
files+=("$f")
done
info "Installing Valve's CEC daemon..."
if ! sudo pacman -U --needed --noconfirm "${files[@]}"; then
rm -rf "$tmp"
err "Installing ${CEC_PKGS[*]} failed."
return 1
fi
rm -rf "$tmp"
# Its udev rule gives the user /dev/cec*; cecd starts with the graphical
# session, after steamos-manager wrote its config from Steam's settings.
sudo udevadm control --reload
sudo udevadm trigger --subsystem-match=cec --action=add
systemctl --user daemon-reload
systemctl --user enable steamos-manager-configure-cecd.service 2>/dev/null
if compgen -G "/dev/cec*" >/dev/null; then
systemctl --user restart cecd.service 2>/dev/null
restart_steamos_manager
ok "HDMI-CEC on ($(cd /dev && echo cec*)). Turn on CEC on your TV too (e.g. Sony: BRAVIA Sync, Samsung: Anynet+, LG: SimpLink)."
else
warn "No CEC device (/dev/cec*) found: your GPU may not support CEC. A USB CEC adapter"
warn "(e.g. Pulse-Eight) works too. Check again after a restart with: ls /dev/cec*"
fi
}
cec_disable() {
info "Removing HDMI-CEC..."
systemctl --user disable --now cecd.service cec-audio-control.socket cec-audio-control.service 2>/dev/null
systemctl --user disable steamos-manager-configure-cecd.service 2>/dev/null
sudo pacman -Rns --noconfirm "${CEC_PKGS[@]}" 2>/dev/null
if [[ -n "$(state_get cec installed_linuxconsole)" ]]; then
sudo pacman -Rns --noconfirm linuxconsole 2>/dev/null
state_clear cec
fi
sudo udevadm control --reload
restart_steamos_manager
ok "HDMI-CEC removed."
}
cec_overview() {
# For the menu's kernel overview.
local dev="none"
compgen -G "/dev/cec*" >/dev/null && dev="$(cd /dev && echo cec*)"
echo "CEC devices: $dev cecd: $(systemctl --user is-active cecd 2>/dev/null)"
}
+7 -3
View File
@@ -5,15 +5,17 @@
# 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 machine kpin bios)
COMPONENTS=(gaming boot theme glyphs single launcher cec machine kpin bios)
# One-off actions rather than on/off components: never preselected, never
# re-applied, not listed as on or off.
ACTIONS=(bios)
# Sub-options, shown indented under their parent and only while it's ticked.
declare -A PARENT=([boot]=gaming [kpin]=machine)
# Never preselected on a first run: booting into the desktop is a choice,
# gamescope is the default.
NO_PRESELECT=(boot)
# 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,
# which has CEC like on SteamOS.
NO_PRESELECT=(boot cec)
declare -A LABEL=(
[gaming]="SteamOS conversion: boot into gaming mode, Steam on the desktop"
@@ -22,6 +24,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: desktop icon to run this again"
[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"
[kpin]="Pin the kernel to $PINNED_KERNEL_VER (fixes rebooting after shutdown)"
[bios]="Update BIOS"
@@ -72,6 +75,7 @@ detect_components() {
component_available "$c" && ! is_action "$c" &&
[[ " ${NO_PRESELECT[*]} " != *" $c "* ]] && WANTED[$c]=1
done
machine_available && WANTED[cec]=1
fi
}
+1
View File
@@ -344,6 +344,7 @@ kernel_overview() {
fi
echo -e " ${running}${line}"
done
cec_status && { echo; echo -e " $(cec_overview)"; }
if [[ "$leds" == true ]]; then
local loaded="$miss" nodes
lsmod | grep -q '^leds_valve' && loaded="$mark"
+2 -2
View File
@@ -15,11 +15,11 @@
set -uo pipefail
# Release version, see CHANGELOG.md.
VERSION=1.0.0
VERSION=1.1.0
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
for lib in common state packages login-manager single-user steam-desktop steam-machine boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut menu; do
for lib in common state packages login-manager single-user steam-desktop steam-machine cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut menu; do
# shellcheck source=/dev/null
source "$SCRIPT_DIR/lib/$lib.sh"
done