fix(console): first-boot follow-ups, plus three Sway desktop fixes #113
+100
-32
@@ -9,17 +9,12 @@ A 4th-generation Core i7 (Haswell) on a UEFI board with an NVIDIA GeForce GTX
|
||||
is driven from the sofa with a Bluetooth controller; keyboard and mouse are
|
||||
supported but secondary.
|
||||
|
||||
## Not installed yet
|
||||
## Disk
|
||||
|
||||
`hardware-configuration.nix` in this host directory is a **placeholder**, not a
|
||||
hardware scan. It exists so the flake evaluates in CI and assumes the install
|
||||
labels its partitions `nixos` (root, ext4) and `BOOT` (ESP, vfat). Replace the
|
||||
whole file with the output of `nixos-generate-config` run on the machine and
|
||||
commit that. If the labels do not match, the boot fails on a missing device
|
||||
rather than touching the wrong disk.
|
||||
|
||||
Partition the disk GPT with an ESP (vfat, 512 MB is comfortable). Nothing else
|
||||
in the host config depends on the disk layout.
|
||||
`hardware-configuration.nix` is a real `nixos-generate-config` scan from the
|
||||
installed machine: GPT with a vfat ESP at `/boot` and an ext4 root, both
|
||||
addressed by UUID, and no swap device. Nothing else in the host config depends
|
||||
on the disk layout.
|
||||
|
||||
## Bootloader
|
||||
|
||||
@@ -88,7 +83,7 @@ to ReGreet, where the ordinary Sway session is available for everything else.
|
||||
`services.greetd.restart` defaults to `false` once `initial_session` is set,
|
||||
which is what stops a logout looping straight back into autologin.
|
||||
|
||||
Two details worth knowing:
|
||||
Three details worth knowing:
|
||||
|
||||
- The launcher is referenced as `/run/current-system/sw/bin/steam-gamescope`.
|
||||
The steam module builds that script privately and only adds it to
|
||||
@@ -96,17 +91,73 @@ Two details worth knowing:
|
||||
- `programs.gamescope.capSysNice = true` installs gamescope as a setcap wrapper
|
||||
in `/run/wrappers/bin` instead of the system profile. That path precedes the
|
||||
system profile on `PATH`, so `steam-gamescope` still resolves it.
|
||||
- greetd gives the session the VT for its standard streams, so anything the
|
||||
Steam session prints as it dies is erased the moment the greeter repaints.
|
||||
`initial_session` therefore runs the launcher under `systemd-cat`, and the
|
||||
output is readable after the fact with `journalctl -b -t steam-session`.
|
||||
|
||||
### When the television lands on ReGreet instead of Steam
|
||||
|
||||
greetd starts `initial_session` **once per boot** — the check is the presence of
|
||||
`/run/greetd.run` — and if the session process starts and then exits, greetd
|
||||
falls through to `default_session`, i.e. ReGreet. A gamescope that dies on
|
||||
startup is therefore indistinguishable from autologin never having run, unless
|
||||
the logs are read:
|
||||
|
||||
```sh
|
||||
journalctl -b -t steam-session # what the session itself said
|
||||
journalctl -b -u greetd # whether greetd started it at all
|
||||
ls -l /run/greetd.run # exists => greetd has already had its one go
|
||||
```
|
||||
|
||||
If greetd never even reaches the session, it prints `unable to start greeter`
|
||||
and **exits** — there is no greeter to fall back to and the screen stays blank.
|
||||
Recover over SSH (`modules/ssh.nix`), or hold space at power-on and boot the
|
||||
previous generation.
|
||||
|
||||
To reproduce a session failure by hand, switch to a free VT and run
|
||||
`steam-gamescope` there. Running it from inside Sway is not the same test:
|
||||
gamescope picks its nested Wayland backend when `WAYLAND_DISPLAY` is set, and it
|
||||
is the DRM backend — the one the boot session uses — that is in question.
|
||||
|
||||
The greeter is **Dvorak**, like every other host here (`modules/sway.nix` forces
|
||||
`XKB_DEFAULT_VARIANT=dvorak` on cage). Only relevant if someone else has to type
|
||||
a password.
|
||||
|
||||
### Adding RetroArch and Clone Hero to Big Picture
|
||||
### Adding RetroArch, PCSX2 and Clone Hero to Big Picture
|
||||
|
||||
Both are installed system-wide but are not Steam titles. Add each once, from a
|
||||
Sway session, via Steam's **Games → Add a Non-Steam Game**; they then appear in
|
||||
Big Picture and inherit Steam Input, so the controller works in them without
|
||||
further configuration.
|
||||
All three are installed system-wide but are not Steam titles. Added as Steam
|
||||
shortcuts they appear in Big Picture and inherit Steam Input, so the controller
|
||||
works in them without further configuration.
|
||||
|
||||
Steam's own **Games → Add a Non-Steam Game** is the documented route and is also
|
||||
the one that tends not to work. Both that dialog's **Browse** button and the
|
||||
library-folder picker below go through the XDG desktop portal `FileChooser`
|
||||
interface; when the portal is unreachable the client silently falls back to a
|
||||
legacy chooser that is blank or inert — Valve
|
||||
[#9447](https://github.com/ValveSoftware/steam-for-linux/issues/9447) and
|
||||
[#10415](https://github.com/ValveSoftware/steam-for-linux/issues/10415), neither
|
||||
fixed. Check the portal side before blaming the client:
|
||||
|
||||
```sh
|
||||
busctl --user introspect org.freedesktop.portal.Desktop \
|
||||
/org/freedesktop/portal/desktop | grep FileChooser
|
||||
```
|
||||
|
||||
`modules/sway.nix` enables `xdg-desktop-portal-gtk`, which is the backend that
|
||||
implements `FileChooser` (`xdg-desktop-portal-wlr` implements only screenshot
|
||||
and screencast), and the generated `sway-portals.conf` routes everything but
|
||||
those two to `gtk`. If the interface is missing from the introspection above,
|
||||
the backend is not running and that is the fault to chase.
|
||||
|
||||
Independent of the dialog, `steamtinkerlaunch` writes `shortcuts.vdf` directly:
|
||||
|
||||
```sh
|
||||
# Steam must be closed -- it rewrites shortcuts.vdf on exit.
|
||||
steamtinkerlaunch addnonsteamgame -an="RetroArch" -ep="$(command -v retroarch)"
|
||||
steamtinkerlaunch addnonsteamgame -an="PCSX2" -ep="$(command -v pcsx2-qt)"
|
||||
steamtinkerlaunch addnonsteamgame -an="Clone Hero" -ep="$(command -v clonehero)"
|
||||
```
|
||||
|
||||
## Emulation — RetroArch
|
||||
|
||||
@@ -167,13 +218,12 @@ system directory on this host:
|
||||
Be honest about the two heaviest cores. `dolphin` and `pcsx2` are libretro ports
|
||||
of emulators whose upstream effort goes into their **standalone** builds; the
|
||||
cores lag on compatibility and are the first place to look when a GameCube, Wii
|
||||
or PS2 title misbehaves. If a game does not cooperate, add the standalone
|
||||
emulators to `environment.systemPackages` in `gaming.nix`:
|
||||
or PS2 title misbehaves.
|
||||
|
||||
```nix
|
||||
pkgs.dolphin-emu # GameCube / Wii
|
||||
pkgs.pcsx2 # PlayStation 2
|
||||
```
|
||||
That has already happened for PS2: the LRPS2 core was not good enough in
|
||||
practice, so **standalone `pkgs.pcsx2` is installed** in `gaming.nix` alongside
|
||||
the core and is what PS2 titles should be run through. `pkgs.dolphin-emu` is not
|
||||
installed; add it the same way if GameCube or Wii turns out to need it.
|
||||
|
||||
Both are controller-driven and can be added to Big Picture the same way as
|
||||
RetroArch. The hardware is not the limit here — a GTX 1070 and a Haswell i7 run
|
||||
@@ -226,7 +276,19 @@ RetroArch is pointed at these paths declaratively. The other two have to be told
|
||||
once, in their own UIs:
|
||||
|
||||
- **Steam** — Settings → Storage → the `+` control → add `/srv/games/steam` as a
|
||||
library folder. Games installed there survive a reinstall of the OS.
|
||||
library folder. Games installed there survive a reinstall of the OS. That
|
||||
picker is the broken one described under
|
||||
[Adding RetroArch, PCSX2 and Clone Hero to Big Picture](#adding-retroarch-pcsx2-and-clone-hero-to-big-picture);
|
||||
when it comes up blank, use Steam's own console instead — open Steam with
|
||||
`steam -console`, pick the **CONSOLE** tab and run:
|
||||
|
||||
```
|
||||
library_folder_add /srv/games/steam
|
||||
```
|
||||
|
||||
The directory must already exist and be writable by the user Steam runs as,
|
||||
which `systemd.tmpfiles` guarantees. The command does not create it.
|
||||
|
||||
- **Clone Hero** — set the song library path to `/srv/games/clonehero/songs` from
|
||||
its settings screen. Clone Hero keeps its own config in `~/.clonehero`.
|
||||
|
||||
@@ -311,17 +373,23 @@ wired 360 pads — as well as `mt76x2u`, and pulls in proprietary dongle firmwar
|
||||
Not worth the side effects unless that dongle is actually in use, and if it ever
|
||||
is, the 360 pads have to be re-tested.
|
||||
|
||||
## Untested claims
|
||||
## Open problems
|
||||
|
||||
This host has not been built or booted yet. Two things are worth watching on
|
||||
first boot:
|
||||
The machine is installed and Sway works. Still outstanding:
|
||||
|
||||
- **gamescope on the proprietary NVIDIA driver.** `gaming.nix` sets
|
||||
`GBM_BACKEND=nvidia-drm` and `__GLX_VENDOR_LIBRARY_NAME=nvidia` for the
|
||||
session, which is the standard fix, but the combination has a history of
|
||||
needing tweaks. If the session dies at startup, switch the greeter back to
|
||||
interactive by commenting out `services.greetd.settings.initial_session`, log
|
||||
into Sway, and read `journalctl --user -b`.
|
||||
- **Autologin into Steam does not happen** — the television comes up on ReGreet.
|
||||
Not yet root-caused; the config side is correct (`initial_session` is present
|
||||
in the generated `greetd.toml` and `services.greetd.restart` evaluates to
|
||||
`false`), so the suspicion is that gamescope starts and dies on the
|
||||
proprietary NVIDIA driver, which greetd treats as a finished session and
|
||||
answers by starting the greeter. `gaming.nix` sets `GBM_BACKEND=nvidia-drm`
|
||||
and `__GLX_VENDOR_LIBRARY_NAME=nvidia`, the standard fix, but the combination
|
||||
has a history of needing more. Read `journalctl -b -t steam-session` first —
|
||||
see [When the television lands on ReGreet instead of Steam](#when-the-television-lands-on-regreet-instead-of-steam).
|
||||
- **Steam's file pickers do not open** — both the non-Steam-game **Browse**
|
||||
dialog and the library-folder picker. Upstream client bugs with usable
|
||||
workarounds; see the two sections above.
|
||||
- **Boot into Big Picture has not been exercised**, since autologin has not run.
|
||||
- **Television resolution and refresh.** gamescope takes the output's native
|
||||
mode by default. Add `gamescopeSession.args = [ "-W" "3840" "-H" "2160" "-r"
|
||||
"60" ]` if a specific mode is wanted.
|
||||
|
||||
@@ -61,6 +61,14 @@ let
|
||||
"clonehero/backgrounds"
|
||||
];
|
||||
|
||||
# greetd gives a session the VT for stdio, so a failed Steam session leaves no
|
||||
# evidence once the greeter takes the VT back. Log to the journal instead:
|
||||
# `journalctl -b -t steam-session`.
|
||||
steamSession = pkgs.writeShellScript "steam-session" ''
|
||||
exec ${pkgs.systemd}/bin/systemd-cat --identifier=steam-session \
|
||||
/run/current-system/sw/bin/steam-gamescope
|
||||
'';
|
||||
|
||||
# RetroArch and the cores this machine is expected to run. The wrapper already
|
||||
# points RetroArch at the packaged assets, core info and joypad autoconfig
|
||||
# profiles; `settings` here is merged on top of those.
|
||||
@@ -178,13 +186,11 @@ in
|
||||
# ask for it; Steam's Proton builds and most native titles do.
|
||||
programs.gamemode.enable = true;
|
||||
|
||||
# Autologin into the Steam session. The launcher is not exposed as a package
|
||||
# by the steam module -- it is built inside it and added to
|
||||
# environment.systemPackages -- so reference it through the system profile.
|
||||
# greetd's `restart` option defaults to false once initial_session is set,
|
||||
# which is what stops a logout from looping straight back into autologin.
|
||||
# Autologin into the Steam session. greetd's `restart` option defaults to
|
||||
# false once initial_session is set, which is what stops a logout from looping
|
||||
# straight back into autologin.
|
||||
services.greetd.settings.initial_session = {
|
||||
command = "/run/current-system/sw/bin/steam-gamescope";
|
||||
command = "${steamSession}";
|
||||
user = tvUser;
|
||||
};
|
||||
|
||||
@@ -242,6 +248,10 @@ in
|
||||
pkgs.clonehero
|
||||
pkgs.pcsx2
|
||||
pkgs.dualsensectl # DualSense LED/battery/mic control from the shell
|
||||
# Writes shortcuts.vdf from the shell. Steam's own "Add a Non-Steam Game"
|
||||
# dialog depends on a working portal file picker and frequently does not
|
||||
# open; see docs/hosts/console.md.
|
||||
pkgs.steamtinkerlaunch
|
||||
pkgs.mangohud # FPS/frametime overlay; use `mangohud %command%` in Steam
|
||||
pkgs.vulkan-tools # vulkaninfo, for checking the 32/64-bit ICDs Proton needs
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user