From 8580ed12bd444a130d403c4d37a7cadd661e9aaa Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 01/15] steam: remove empty let-in --- modules/steam/autostart.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/steam/autostart.nix b/modules/steam/autostart.nix index db027d4b..a52912d1 100644 --- a/modules/steam/autostart.nix +++ b/modules/steam/autostart.nix @@ -81,8 +81,7 @@ in services.greetd = { enable = true; settings = { - default_session = let - in { + default_session = { user = "jovian-greeter"; command = "${pkgs.jovian-greeter}/bin/jovian-greeter ${cfg.user}"; }; From 95a2a1b5dd679fd3e59874758188300958a7d4d4 Mon Sep 17 00:00:00 2001 From: K900 Date: Sun, 24 Sep 2023 09:30:25 +0300 Subject: [PATCH 02/15] jupiter-dock-updater: use finalAttrs --- pkgs/jupiter-dock-updater-bin/default.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/jupiter-dock-updater-bin/default.nix b/pkgs/jupiter-dock-updater-bin/default.nix index 43a344cf..9dfca030 100644 --- a/pkgs/jupiter-dock-updater-bin/default.nix +++ b/pkgs/jupiter-dock-updater-bin/default.nix @@ -6,14 +6,14 @@ , libusb }: -stdenv.mkDerivation rec { +stdenv.mkDerivation(finalAttrs: { pname = "jupiter-dock-updater-bin"; version = "20230714.01"; src = fetchFromGitHub { owner = "Jovian-Experiments"; repo = "jupiter-dock-updater-bin"; - rev = "jupiter-${version}"; + rev = "jupiter-${finalAttrs.version}"; hash = "sha256-tfMPBC1x4YE3Sv3GbVkQJ12CYODeHjK1cBEaw9jBZpY="; }; @@ -38,4 +38,4 @@ stdenv.mkDerivation rec { runHook postInstall ''; -} +}) From ab337a93bd160df7878d9447d53c57383efdfaff Mon Sep 17 00:00:00 2001 From: K900 Date: Sun, 24 Sep 2023 09:30:31 +0300 Subject: [PATCH 03/15] jupiter-fan-control: use finalAttrs --- pkgs/jupiter-fan-control/default.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/jupiter-fan-control/default.nix b/pkgs/jupiter-fan-control/default.nix index 06cdeff2..65785870 100644 --- a/pkgs/jupiter-fan-control/default.nix +++ b/pkgs/jupiter-fan-control/default.nix @@ -1,6 +1,6 @@ { lib, stdenv, python3, fetchFromGitHub }: -stdenv.mkDerivation rec { +stdenv.mkDerivation(finalAttrs: { pname = "jupiter-fan-control"; version = "20230209.1"; @@ -9,7 +9,7 @@ stdenv.mkDerivation rec { src = fetchFromGitHub { owner = "Jovian-Experiments"; repo = "jupiter-fan-control"; - rev = version; + rev = finalAttrs.version; sha256 = "sha256-9sNJdR0t8GW0hcSNylTK5YcflPltfqyN9KnPos1YcA0="; }; @@ -38,4 +38,4 @@ stdenv.mkDerivation rec { # PKGBUILD says MIT, but PID.py is licensed under GPLv3+ license = licenses.gpl3Plus; }; -} +}) From 02e71680c99c1e934ccc0216161624241286bcb4 Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 04/15] steamdeck-firmware: add missing deps, install systemd units --- pkgs/jupiter-hw-support/firmware.nix | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pkgs/jupiter-hw-support/firmware.nix b/pkgs/jupiter-hw-support/firmware.nix index d7e8beef..b4a1f47c 100644 --- a/pkgs/jupiter-hw-support/firmware.nix +++ b/pkgs/jupiter-hw-support/firmware.nix @@ -10,8 +10,10 @@ # jupiter-biosupdate , libkrb5 , zlib -, jq +, coreutils +, gawk , dmidecode +, jq , efiSysMountPoint ? "/boot" }: @@ -96,7 +98,7 @@ stdenv.mkDerivation { sed -i "s|/usr/share/jupiter_bios_updater/h2offt|$h2offt_nixos|g" $out/bin/jupiter-biosupdate sed -i "s|/usr/|$out/|g" $out/bin/jupiter-biosupdate wrapProgram $out/bin/jupiter-biosupdate \ - --prefix PATH : ${lib.makeBinPath [ jq dmidecode ]} + --prefix PATH : ${lib.makeBinPath [ coreutils dmidecode gawk jq ]} cp usr/bin/jupiter-controller-update $out/bin sed -i "s|/usr/|$out/|g" $out/bin/jupiter-controller-update @@ -110,6 +112,10 @@ stdenv.mkDerivation { rm h2offt-g H2OFFTx64-G.sh popd + substituteInPlace usr/lib/systemd/system/*.service --replace "/usr" "$out" + install -D -m 644 usr/lib/systemd/system/jupiter-biosupdate.service $out/lib/systemd/system/jupiter-biosupdate.service + install -D -m 644 usr/lib/systemd/system/jupiter-controller-update.service $out/lib/systemd/system/jupiter-controller-update.service + runHook postInstall ''; From 2e405c02fdabc8754151fd9bac4671c5f904a165 Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 05/15] modules/steamdeck/firmware: allow auto-updates like upstream --- modules/steamdeck/firmware.nix | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/modules/steamdeck/firmware.nix b/modules/steamdeck/firmware.nix index eb5b0b19..798aa1bb 100644 --- a/modules/steamdeck/firmware.nix +++ b/modules/steamdeck/firmware.nix @@ -4,7 +4,6 @@ let inherit (lib) - mkDefault mkIf mkMerge mkOption @@ -15,6 +14,14 @@ in { options = { jovian.devices.steamdeck = { + autoUpdate = mkOption { + type = types.bool; + default = false; + description = '' + Whether to automatically update the BIOS and controller firmware. + ''; + }; + enableFwupdBiosUpdates = mkOption { type = types.bool; default = cfg.enable; @@ -27,6 +34,12 @@ in }; config = mkMerge [ + (mkIf (cfg.autoUpdate) { + systemd.packages = [pkgs.steamdeck-firmware]; + + systemd.services.jupiter-biosupdate.wantedBy = ["multi-user.target"]; + systemd.services.jupiter-controller-update.wantedBy = ["multi-user.target"]; + }) (mkIf (cfg.enableFwupdBiosUpdates) { services.fwupd.enable = true; From 31ad9a93e6a0ac92f1b2c8fb1b510042f895c3fb Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 06/15] steamdeck-bios-fwupd: use src like everything else This will become important later --- pkgs/jupiter-hw-support/bios-fwupd.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/jupiter-hw-support/bios-fwupd.nix b/pkgs/jupiter-hw-support/bios-fwupd.nix index 327a03f7..ba6c68f4 100644 --- a/pkgs/jupiter-hw-support/bios-fwupd.nix +++ b/pkgs/jupiter-hw-support/bios-fwupd.nix @@ -14,7 +14,7 @@ # The following parameters are for your enjoyment of flashing custom/older BIOSes: # The BIOS file (e.g., "F7A0110_sign.fd") or a directory containing it. -, biosFile ? jupiter-hw-support.src +, biosFile ? callPackage ./src.nix { } # The BIOS version (e.g., "0110"). # If null, parsed from the BIOS file name. From ab04234e67b2a7bf53fd02f51ceee66a11e678e3 Mon Sep 17 00:00:00 2001 From: K900 Date: Sun, 24 Sep 2023 10:22:06 +0300 Subject: [PATCH 07/15] jovian-steam-protocol-handler: add common Steam shim This will become important later (tm) --- overlay.nix | 1 + pkgs/jovian-steam-protocol-handler/default.nix | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 pkgs/jovian-steam-protocol-handler/default.nix diff --git a/overlay.nix b/overlay.nix index 7345b7cb..26d692be 100644 --- a/overlay.nix +++ b/overlay.nix @@ -46,6 +46,7 @@ rec { opensd = super.callPackage ./pkgs/opensd { }; jovian-greeter = super.callPackage ./pkgs/jovian-greeter { }; + jovian-steam-protocol-handler = super.callPackage ./pkgs/jovian-steam-protocol-handler { }; steamPackages = super.steamPackages.overrideScope (scopeFinal: scopeSuper: { steam = final.callPackage ./pkgs/steam-jupiter/unwrapped.nix { diff --git a/pkgs/jovian-steam-protocol-handler/default.nix b/pkgs/jovian-steam-protocol-handler/default.nix new file mode 100644 index 00000000..7e9f12e6 --- /dev/null +++ b/pkgs/jovian-steam-protocol-handler/default.nix @@ -0,0 +1,9 @@ +{ + writeShellScript, + steamPackages, +}: +# FIXME: this is a hack, replace with a better implementation +# Investigate magic socket? +writeShellScript "jovian-steam-protocol-handler" '' + exec ${steamPackages.steam-fhsenv.run}/bin/steam-run ~/.steam/root/ubuntu12_32/steam "$@" +'' From c43a1a2772ff3983363775424845c37eb8b88b49 Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 08/15] jupiter-hw-support: resholve, add patch to use our protocol handler --- pkgs/jupiter-hw-support/default.nix | 67 +++++++++++++++++++++++++--- pkgs/jupiter-hw-support/jovian.patch | 13 ++++++ pkgs/jupiter-hw-support/src.nix | 29 +++++++++--- 3 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 pkgs/jupiter-hw-support/jovian.patch diff --git a/pkgs/jupiter-hw-support/default.nix b/pkgs/jupiter-hw-support/default.nix index 25788e09..80af7e77 100644 --- a/pkgs/jupiter-hw-support/default.nix +++ b/pkgs/jupiter-hw-support/default.nix @@ -1,14 +1,66 @@ { lib , stdenv , callPackage -, python3 +, resholve +, bash +, coreutils +, e2fsprogs +, exfatprogs +, f3 +, findutils +, gawk +, gnused +, jq +, parted +, procps +, systemd +, util-linux }: let src = callPackage ./src.nix { }; - pythonEnv = python3.withPackages (py: with py; [ - evdev - ]); + + solution = { + scripts = [ "bin/*" "lib/hwsupport/*.sh" ]; + interpreter = "${bash}/bin/bash"; + inputs = [ + coreutils + e2fsprogs + exfatprogs + f3 + findutils + gawk + gnused + jq + parted + procps + systemd + util-linux + + "${placeholder "out"}/lib/hwsupport" + ]; + execer = [ + "cannot:${e2fsprogs}/bin/mkfs.ext4" + "cannot:${procps}/bin/pgrep" + "cannot:${systemd}/bin/systemctl" + "cannot:${systemd}/bin/udevadm" + "cannot:${util-linux}/bin/flock" + + "cannot:${placeholder "out"}/lib/hwsupport/format-device.sh" + ]; + fake = { + # we're using wrappers for these + external = [ "umount" ]; + }; + fix = { + "/usr/lib/hwsupport/format-device.sh" = true; + }; + keep = { + # pre-applied via patch + # FIXME: why do we need to discard string context here? + "${builtins.unsafeDiscardStringContext "${systemd}/bin/systemd-run"}" = true; + }; + }; in stdenv.mkDerivation { pname = "jupiter-hw-support"; @@ -16,14 +68,15 @@ stdenv.mkDerivation { inherit src; inherit (src) version; - buildInputs = [ pythonEnv ]; - dontConfigure = true; dontBuild = true; installPhase = '' runHook preInstall + mkdir -p $out/bin + cp usr/bin/jupiter-check-support $out/bin + mkdir -p $out/lib cp -r usr/lib/hwsupport $out/lib @@ -46,6 +99,8 @@ stdenv.mkDerivation { # alsaucm: error failed to set _verb=HiFi: Exec format error sed -i 's|exec "echo|#exec "echo|g' $out/share/alsa/ucm2/conf.d/acp5x/HiFi*.conf + ${resholve.phraseSolution "jupiter-hw-support" solution} + runHook postInstall ''; diff --git a/pkgs/jupiter-hw-support/jovian.patch b/pkgs/jupiter-hw-support/jovian.patch new file mode 100644 index 00000000..ef858595 --- /dev/null +++ b/pkgs/jupiter-hw-support/jovian.patch @@ -0,0 +1,13 @@ +diff --git a/usr/lib/hwsupport/steamos-automount.sh b/usr/lib/hwsupport/steamos-automount.sh +index 9e40c22..dc125a2 100755 +--- a/usr/lib/hwsupport/steamos-automount.sh ++++ b/usr/lib/hwsupport/steamos-automount.sh +@@ -53,7 +53,7 @@ send_steam_url() + if pgrep -x "steam" > /dev/null; then + # TODO use -ifrunning and check return value - if there was a steam process and it returns -1, the message wasn't sent + # need to retry until either steam process is gone or -ifrunning returns 0, or timeout i guess +- systemd-run -M 1000@ --user --collect --wait sh -c "./.steam/root/ubuntu12_32/steam steam://${command}/${encoded@Q}" ++ @systemd@/bin/systemd-run -M 1000@ --user --collect --wait @handler@ "steam://${command}/${encoded@Q}" + echo "Sent URL to steam: steam://${command}/${arg} (steam://${command}/${encoded})" + else + echo "Could not send steam URL steam://${command}/${arg} (steam://${command}/${encoded}) -- steam not running" diff --git a/pkgs/jupiter-hw-support/src.nix b/pkgs/jupiter-hw-support/src.nix index c6b2c710..f430da26 100644 --- a/pkgs/jupiter-hw-support/src.nix +++ b/pkgs/jupiter-hw-support/src.nix @@ -1,13 +1,28 @@ -{ fetchFromGitHub }: +{ + applyPatches, + fetchFromGitHub, + substituteAll, + jovian-steam-protocol-handler, + systemd, +}: let version = "20230918.1"; -in (fetchFromGitHub { - name = "jupiter-hw-support-${version}"; - owner = "Jovian-Experiments"; - repo = "jupiter-hw-support"; - rev = "jupiter-${version}"; - hash = "sha256-w5rX8h/P4gCYV6WVj9XhyVrg1VUQ+z+ev8ijiPgl0u0="; +in (applyPatches { + src = fetchFromGitHub { + owner = "Jovian-Experiments"; + repo = "jupiter-hw-support"; + rev = "jupiter-${version}"; + hash = "sha256-w5rX8h/P4gCYV6WVj9XhyVrg1VUQ+z+ev8ijiPgl0u0="; + }; + + patches = [ + (substituteAll { + handler = jovian-steam-protocol-handler; + systemd = systemd; + src = ./jovian.patch; + }) + ]; }) // { inherit version; } From 991ce4b35e5c71485b2f3a3e70f9b65749b3bbca Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 09/15] powerbuttond: init --- overlay.nix | 1 + pkgs/powerbuttond/default.nix | 43 ++++++++++++++++++++++++++++++++++ pkgs/powerbuttond/jovian.patch | 18 ++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 pkgs/powerbuttond/default.nix create mode 100644 pkgs/powerbuttond/jovian.patch diff --git a/overlay.nix b/overlay.nix index 26d692be..b522dcea 100644 --- a/overlay.nix +++ b/overlay.nix @@ -36,6 +36,7 @@ rec { }; jupiter-fan-control = final.callPackage ./pkgs/jupiter-fan-control { }; + powerbuttond = final.callPackage ./pkgs/powerbuttond { }; jupiter-hw-support = final.callPackage ./pkgs/jupiter-hw-support { }; steamdeck-hw-theme = final.callPackage ./pkgs/jupiter-hw-support/theme.nix { }; diff --git a/pkgs/powerbuttond/default.nix b/pkgs/powerbuttond/default.nix new file mode 100644 index 00000000..8140de41 --- /dev/null +++ b/pkgs/powerbuttond/default.nix @@ -0,0 +1,43 @@ +{ + lib, + stdenv, + fetchFromGitHub, + substituteAll, + pkg-config, + libevdev, + jovian-steam-protocol-handler, +}: +stdenv.mkDerivation { + pname = "powerbuttond"; + version = "1.0"; + + src = fetchFromGitHub { + owner = "Jovian-Experiments"; + repo = "powerbuttond"; + rev = "v1"; + hash = "sha256-2MvmkclbPIu8qIoZRd+4Kr+H7nO1xUWJ2JrCJC7gzK4="; + }; + + patches = [ + (substituteAll { + handler = jovian-steam-protocol-handler; + src = ./jovian.patch; + }) + ]; + + nativeBuildInputs = [pkg-config]; + buildInputs = [libevdev]; + + installPhase = '' + runHook preInstall + + install -D -m 555 powerbuttond $out/bin/powerbuttond + + runHook postInstall + ''; + + meta = with lib; { + description = "Steam Deck power button daemon"; + license = licenses.bsd2; + }; +} diff --git a/pkgs/powerbuttond/jovian.patch b/pkgs/powerbuttond/jovian.patch new file mode 100644 index 00000000..d6e070ca --- /dev/null +++ b/pkgs/powerbuttond/jovian.patch @@ -0,0 +1,18 @@ +diff --git a/powerbuttond.c b/powerbuttond.c +index 722ba77..b8c3c97 100644 +--- a/powerbuttond.c ++++ b/powerbuttond.c +@@ -31,12 +31,9 @@ struct libevdev* find_dev(void) { + } + + void do_press(const char* type) { +- char steam[PATH_MAX]; ++ char* steam = "@handler@"; + char press[32]; +- char* home = getenv("HOME"); + char* const args[] = {steam, "-ifrunning", press, NULL}; +- +- snprintf(steam, sizeof(steam), "%s/.steam/root/ubuntu12_32/steam", home); + snprintf(press, sizeof(press), "steam://%spowerpress", type); + + pid_t pid = vfork(); From c9e22f9639d7eb8991b982db4b7c35e916829b84 Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 10/15] steam_notif_daemon: init --- overlay.nix | 1 + pkgs/steam_notif_daemon/default.nix | 40 ++++++++++++++++++++++++++++ pkgs/steam_notif_daemon/jovian.patch | 29 ++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 pkgs/steam_notif_daemon/default.nix create mode 100644 pkgs/steam_notif_daemon/jovian.patch diff --git a/overlay.nix b/overlay.nix index b522dcea..81e8abe5 100644 --- a/overlay.nix +++ b/overlay.nix @@ -37,6 +37,7 @@ rec { jupiter-fan-control = final.callPackage ./pkgs/jupiter-fan-control { }; powerbuttond = final.callPackage ./pkgs/powerbuttond { }; + steam_notif_daemon = final.callPackage ./pkgs/steam_notif_daemon { }; jupiter-hw-support = final.callPackage ./pkgs/jupiter-hw-support { }; steamdeck-hw-theme = final.callPackage ./pkgs/jupiter-hw-support/theme.nix { }; diff --git a/pkgs/steam_notif_daemon/default.nix b/pkgs/steam_notif_daemon/default.nix new file mode 100644 index 00000000..1ee16baa --- /dev/null +++ b/pkgs/steam_notif_daemon/default.nix @@ -0,0 +1,40 @@ +{ + lib, + stdenv, + fetchFromGitHub, + substituteAll, + meson, + ninja, + pkg-config, + systemd, + curl, + jovian-steam-protocol-handler, +}: +stdenv.mkDerivation (finalAttrs: { + pname = "steam_notif_daemon"; + version = "1.0.1"; + + src = fetchFromGitHub { + owner = "Jovian-Experiments"; + repo = "steam_notif_daemon"; + rev = "v${finalAttrs.version}"; + hash = "sha256-mtG2D+FEzTtYi3XnFKifhHLC5h8ApB2XREn74AVCbWc="; + }; + + patches = [ + (substituteAll { + handler = jovian-steam-protocol-handler; + src = ./jovian.patch; + }) + ]; + + mesonFlags = ["-Dsd-bus-provider=libsystemd"]; + + nativeBuildInputs = [pkg-config meson ninja]; + buildInputs = [systemd curl]; + + meta = with lib; { + description = "Steam notification daemon"; + license = licenses.mit; + }; +}) diff --git a/pkgs/steam_notif_daemon/jovian.patch b/pkgs/steam_notif_daemon/jovian.patch new file mode 100644 index 00000000..571e151e --- /dev/null +++ b/pkgs/steam_notif_daemon/jovian.patch @@ -0,0 +1,29 @@ +diff --git a/main.c b/main.c +index 97bad39..657ea2b 100644 +--- a/main.c ++++ b/main.c +@@ -29,7 +29,7 @@ enum sfd_event { + }; + + struct sfd_state { +- char steam_path[PATH_MAX]; ++ char* steam_path; + struct pollfd fds[SFD_EVENT_COUNT]; + sd_bus* bus; + sd_bus_slot *xdg_slot; +@@ -261,14 +261,7 @@ static int init_signalfd() { + } + + static void init_steam_path(struct sfd_state *state) { +- const char *homedir; +- if ((homedir = getenv("HOME")) == NULL) { +- homedir = getpwuid(getuid())->pw_dir; +- } +- +- snprintf(state->steam_path, sizeof(state->steam_path), +- "%s/.steam/root/ubuntu12_32/steam", +- homedir); ++ state->steam_path = "@handler@"; + } + + static bool init_dbus(struct sfd_state *state) { From 89ef892f2e0abec3b6706c72d1786287f953af90 Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 11/15] jovian-stubs: init --- overlay.nix | 1 + pkgs/jovian-stubs/default.nix | 15 +++++++++++++++ pkgs/jovian-stubs/jupiter-biosupdate | 5 +++++ pkgs/jovian-stubs/pkexec | 4 ++++ pkgs/jovian-stubs/steamos-factory-reset-config | 3 +++ pkgs/jovian-stubs/steamos-reboot | 3 +++ pkgs/jovian-stubs/steamos-select-branch | 3 +++ pkgs/jovian-stubs/steamos-update | 8 ++++++++ pkgs/jovian-stubs/sudo | 18 ++++++++++++++++++ 9 files changed, 60 insertions(+) create mode 100644 pkgs/jovian-stubs/default.nix create mode 100644 pkgs/jovian-stubs/jupiter-biosupdate create mode 100644 pkgs/jovian-stubs/pkexec create mode 100644 pkgs/jovian-stubs/steamos-factory-reset-config create mode 100644 pkgs/jovian-stubs/steamos-reboot create mode 100644 pkgs/jovian-stubs/steamos-select-branch create mode 100644 pkgs/jovian-stubs/steamos-update create mode 100644 pkgs/jovian-stubs/sudo diff --git a/overlay.nix b/overlay.nix index 81e8abe5..3118ab27 100644 --- a/overlay.nix +++ b/overlay.nix @@ -47,6 +47,7 @@ rec { opensd = super.callPackage ./pkgs/opensd { }; + jovian-stubs = final.callPackage ./pkgs/jovian-stubs { }; jovian-greeter = super.callPackage ./pkgs/jovian-greeter { }; jovian-steam-protocol-handler = super.callPackage ./pkgs/jovian-steam-protocol-handler { }; diff --git a/pkgs/jovian-stubs/default.nix b/pkgs/jovian-stubs/default.nix new file mode 100644 index 00000000..bd210376 --- /dev/null +++ b/pkgs/jovian-stubs/default.nix @@ -0,0 +1,15 @@ +{ stdenv }: +stdenv.mkDerivation { + name = "jovian-stubs"; + + buildCommand = '' + install -D -m 755 ${./jupiter-biosupdate} $out/bin/jupiter-biosupdate + install -D -m 755 ${./steamos-factory-reset-config} $out/bin/steamos-factory-reset-config + install -D -m 755 ${./steamos-reboot} $out/bin/steamos-reboot + install -D -m 755 ${./steamos-select-branch} $out/bin/steamos-select-branch + install -D -m 755 ${./steamos-update} $out/bin/steamos-update + + install -D -m 755 ${./pkexec} $out/bin/pkexec + install -D -m 755 ${./sudo} $out/bin/sudo + ''; +} diff --git a/pkgs/jovian-stubs/jupiter-biosupdate b/pkgs/jovian-stubs/jupiter-biosupdate new file mode 100644 index 00000000..bf9720dd --- /dev/null +++ b/pkgs/jovian-stubs/jupiter-biosupdate @@ -0,0 +1,5 @@ +#!/bin/sh +>&2 echo "[JOVIAN] $0: stub called with: $*" +>&2 echo "[JOVIAN] jupiter-biosupdate requires elevation, which is currently not available in the sandbox" +>&2 echo "[JOVIAN] Please run sudo jupiter-biosupdate from outside Steam if necessary" +exit 0 diff --git a/pkgs/jovian-stubs/pkexec b/pkgs/jovian-stubs/pkexec new file mode 100644 index 00000000..bebaaaaf --- /dev/null +++ b/pkgs/jovian-stubs/pkexec @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +>&2 echo "[JOVIAN] $0: stub called with: $*" +args=("$@") +exec "${args[@]/--disable-internal-agent}" diff --git a/pkgs/jovian-stubs/steamos-factory-reset-config b/pkgs/jovian-stubs/steamos-factory-reset-config new file mode 100644 index 00000000..c035f155 --- /dev/null +++ b/pkgs/jovian-stubs/steamos-factory-reset-config @@ -0,0 +1,3 @@ +#!/bin/sh +>&2 echo "[JOVIAN] $0: stub called with: $*" +exit 1 diff --git a/pkgs/jovian-stubs/steamos-reboot b/pkgs/jovian-stubs/steamos-reboot new file mode 100644 index 00000000..695acb8d --- /dev/null +++ b/pkgs/jovian-stubs/steamos-reboot @@ -0,0 +1,3 @@ +#!/bin/sh +>&2 echo "[JOVIAN] $0: stub called with: $*" +exec reboot diff --git a/pkgs/jovian-stubs/steamos-select-branch b/pkgs/jovian-stubs/steamos-select-branch new file mode 100644 index 00000000..c035f155 --- /dev/null +++ b/pkgs/jovian-stubs/steamos-select-branch @@ -0,0 +1,3 @@ +#!/bin/sh +>&2 echo "[JOVIAN] $0: stub called with: $*" +exit 1 diff --git a/pkgs/jovian-stubs/steamos-update b/pkgs/jovian-stubs/steamos-update new file mode 100644 index 00000000..82235db6 --- /dev/null +++ b/pkgs/jovian-stubs/steamos-update @@ -0,0 +1,8 @@ +#!/bin/sh +>&2 echo "[JOVIAN] $0: stub called with: $*" +# Exit codes according to vendor: +# 0 - update success +# 1 - update error +# 7 - no update available +# 8 - need reboot +exit 7 diff --git a/pkgs/jovian-stubs/sudo b/pkgs/jovian-stubs/sudo new file mode 100644 index 00000000..66082251 --- /dev/null +++ b/pkgs/jovian-stubs/sudo @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +>&2 echo "[JOVIAN] $0: stub called with: $*" + +declare -a final + +positional="" +for value in "$@"; do + if [[ -n "$positional" ]]; then + final+=("$value") + elif [[ "$value" == "-n" ]]; then + : + else + positional="y" + final+=("$value") + fi +done + +exec "${final[@]}" From e63f78dc86ec76469e86847257cc4afa9d0ffd6f Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 12/15] steamos-polkit-helpers: init --- overlay.nix | 1 + pkgs/jupiter-hw-support/polkit-helpers.nix | 94 ++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 pkgs/jupiter-hw-support/polkit-helpers.nix diff --git a/overlay.nix b/overlay.nix index 3118ab27..ca607063 100644 --- a/overlay.nix +++ b/overlay.nix @@ -44,6 +44,7 @@ rec { steamdeck-firmware = final.callPackage ./pkgs/jupiter-hw-support/firmware.nix { }; steamdeck-bios-fwupd = final.callPackage ./pkgs/jupiter-hw-support/bios-fwupd.nix { }; jupiter-dock-updater-bin = final.callPackage ./pkgs/jupiter-dock-updater-bin { }; + steamos-polkit-helpers = final.callPackage ./pkgs/jupiter-hw-support/polkit-helpers.nix { }; opensd = super.callPackage ./pkgs/opensd { }; diff --git a/pkgs/jupiter-hw-support/polkit-helpers.nix b/pkgs/jupiter-hw-support/polkit-helpers.nix new file mode 100644 index 00000000..9976e44a --- /dev/null +++ b/pkgs/jupiter-hw-support/polkit-helpers.nix @@ -0,0 +1,94 @@ +{ + stdenv, + callPackage, + resholve, + bash, + coreutils, + dmidecode, + gnugrep, + jovian-stubs, + jupiter-dock-updater-bin, + jupiter-hw-support, + steamdeck-firmware, + systemd, + wirelesstools, +}: + +let + src = callPackage ./src.nix { }; + + solution = { + scripts = [ "bin/steamos-polkit-helpers/*" ]; + interpreter = "${bash}/bin/bash"; + inputs = [ + coreutils + dmidecode + gnugrep + "${jupiter-dock-updater-bin}/lib/jupiter-dock-updater" + jovian-stubs + jupiter-hw-support + "${jupiter-hw-support}/lib/hwsupport" + steamdeck-firmware + systemd + wirelesstools + ]; + execer = [ + "cannot:${jovian-stubs}/bin/jupiter-biosupdate" + "cannot:${jovian-stubs}/bin/steamos-reboot" + "cannot:${jovian-stubs}/bin/steamos-factory-reset-config" + "cannot:${jovian-stubs}/bin/steamos-select-branch" + "cannot:${jovian-stubs}/bin/steamos-update" + "cannot:${jupiter-dock-updater-bin}/lib/jupiter-dock-updater/jupiter-dock-updater.sh" + "cannot:${jupiter-hw-support}/bin/jupiter-check-support" + "cannot:${jupiter-hw-support}/lib/hwsupport/format-device.sh" + "cannot:${jupiter-hw-support}/lib/hwsupport/format-sdcard.sh" + "cannot:${jupiter-hw-support}/lib/hwsupport/trim-devices.sh" + "cannot:${steamdeck-firmware}/bin/jupiter-biosupdate" + "cannot:${systemd}/bin/systemctl" + "cannot:${systemd}/bin/systemd-cat" + ]; + fake = { + external = ["pkexec"]; + }; + fix = { + "/usr/bin/jupiter-biosupdate" = true; + "/usr/bin/jupiter-check-support" = true; + "/usr/bin/steamos-factory-reset-config" = true; + "/usr/bin/steamos-reboot" = true; + "/usr/bin/steamos-select-branch" = true; + "/usr/bin/steamos-update" = true; + "/usr/lib/hwsupport/format-device.sh" = true; + "/usr/lib/hwsupport/format-sdcard.sh" = true; + "/usr/lib/hwsupport/trim-devices.sh" = true; + "/usr/lib/jupiter-dock-updater/jupiter-dock-updater.sh" = true; + }; + keep = { + # this file is removed in latest versions of hwsupport + "/usr/lib/hwsupport/jupiter-amp-control" = true; + }; + }; +in stdenv.mkDerivation { + pname = "steamos-polkit-helpers"; + + inherit src; + inherit (src) version; + + patchPhase = '' + runHook prePatch + + substituteInPlace usr/share/polkit-1/actions/org.valve.steamos.policy --replace /usr $out + + runHook postPatch + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/{bin,share} + cp -r usr/bin/steamos-polkit-helpers $out/bin/steamos-polkit-helpers + cp -r usr/share/polkit-1 $out/share + + ${resholve.phraseSolution "steamos-polkit-helpers" solution} + runHook postInstall + ''; +} From 199655722d9faa542e33aba67923f1422812388b Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 13/15] gamescope-session: init --- overlay.nix | 1 + pkgs/gamescope-session/default.nix | 146 +++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 pkgs/gamescope-session/default.nix diff --git a/overlay.nix b/overlay.nix index ca607063..f7d32e4e 100644 --- a/overlay.nix +++ b/overlay.nix @@ -22,6 +22,7 @@ rec { gamescope = final.callPackage ./pkgs/gamescope { gamescope' = super.gamescope; }; + gamescope-session = final.callPackage ./pkgs/gamescope-session { }; mangohud = final.callPackage ./pkgs/mangohud { libXNVCtrl = linuxPackages_jovian.nvidia_x11.settings.libXNVCtrl; diff --git a/pkgs/gamescope-session/default.nix b/pkgs/gamescope-session/default.nix new file mode 100644 index 00000000..25cb95e9 --- /dev/null +++ b/pkgs/gamescope-session/default.nix @@ -0,0 +1,146 @@ +{ + stdenv, + resholve, + writeText, + fetchFromGitHub, + python3, + steamdeck-hw-theme, + steamPackages, + bash, + coreutils, + dbus, + findutils, + gamescope, + gnugrep, + gnused, + gnutar, + ibus, + mangohud, + powerbuttond, + procps, + steam_notif_daemon, + steamos-polkit-helpers, + systemd, + util-linux, + xbindkeys, +}: + +let + gamescope-session-solution = { + scripts = [ "bin/gamescope-session" ]; + interpreter = "${bash}/bin/bash"; + inputs = [ + coreutils + dbus + findutils + gnugrep + gnused + gnutar + ibus + mangohud + powerbuttond + procps + steam_notif_daemon + "${steamos-polkit-helpers}/bin/steamos-polkit-helpers" + steamPackages.steam-fhsenv + util-linux + xbindkeys + ]; + execer = [ + "cannot:${ibus}/bin/ibus-daemon" + "cannot:${steamos-polkit-helpers}/bin/steamos-polkit-helpers/steamos-poweroff-now" + "cannot:${steamos-polkit-helpers}/bin/steamos-polkit-helpers/steamos-reboot-now" + "cannot:${steamos-polkit-helpers}/bin/steamos-polkit-helpers/steamos-retrigger-automounts" + "cannot:${steamPackages.steam-fhsenv}/bin/steam" + "cannot:${util-linux}/bin/flock" + "cannot:${xbindkeys}/bin/xbindkeys" + ]; + fake = { + # we're using wrappers for these + external = [ "sudo" "gamescope" ]; + }; + fix = { + "/usr/bin/ibus-daemon" = true; + "/usr/bin/steamos-polkit-helpers/steamos-poweroff-now" = true; + "/usr/bin/steamos-polkit-helpers/steamos-reboot-now" = true; + "/usr/bin/steamos-polkit-helpers/steamos-retrigger-automounts" = true; + "/usr/lib/hwsupport/powerbuttond" = true; + }; + keep = { + # if you've somehow managed to get devkit Steam on your NixOS, + # everything that happens beyond this point is entirely your fault + "$HOME/devkit-game/devkit-steam" = true; + }; + + # Don't resholve gamescope so we can use the cap_sys_nice wrapper when available + prologue = "${writeText "gamescope-session-prologue" '' + export PATH=/run/wrappers/bin:${gamescope}/bin:$PATH + ''}"; + }; + start-gamescope-session-solution = { + scripts = [ "bin/start-gamescope-session" ]; + interpreter = "${bash}/bin/bash"; + inputs = [ coreutils dbus gnugrep systemd ]; + execer = [ + "cannot:${systemd}/bin/systemctl" + ]; + + # Import user PATH into the environment to be able to start third party tools + prologue = "${writeText "start-gamescope-session-prologue" '' + ${systemd}/bin/systemctl --user import-environment PATH + ''}"; + }; +in stdenv.mkDerivation(finalAttrs: { + pname = "gamescope-session"; + version = "3.12.5-1.3"; + + src = fetchFromGitHub { + owner = "Jovian-Experiments"; + repo = "PKGBUILDs-mirror"; + rev = "jupiter-main/gamescope-${finalAttrs.version}"; + hash = "sha256-kRXnhWhmoMewyozFAVfjBmuyTmOe9qF8JAs7VltNmHo="; + }; + + patchPhase = '' + runHook prePatch + + patchShebangs steam-http-loader + + substituteInPlace gamescope-session \ + --replace /usr/share/steamos ${steamdeck-hw-theme}/share/steamos \ + --replace /usr/lib/steam ${steamPackages.steam}/lib/steam + + substituteInPlace gamescope-session.service \ + --replace /usr/bin $out/bin + + runHook postPatch + ''; + + nativeBuildInputs = [python3]; + + # Largely copied from upstream + installPhase = '' + runHook preInstall + + install -D -m 755 gamescope-session $out/bin/gamescope-session + install -D -m 755 start-gamescope-session $out/bin/start-gamescope-session + install -D -m 644 gamescope-wayland.desktop $out/share/wayland-sessions/gamescope-wayland.desktop + + # url handling + install -D -m 644 steam_http_loader.desktop $out/share/applications/steam_http_loader.desktop + install -D -m 644 gamescope-mimeapps.list $out/share/applications/gamescope-mimeapps.list + install -D -m 755 steam-http-loader $out/bin/steam-http-loader + + install -D -m 644 gamescope-session.service $out/share/systemd/user/gamescope-session.service + + # portals + install -D -m 644 gamescope-portals.conf $out/share/xdg-desktop-portal/gamescope-portals.conf + + ${resholve.phraseSolution "gamescope-session" gamescope-session-solution} + ${resholve.phraseSolution "start-gamescope-session" start-gamescope-session-solution} + + runHook postInstall + ''; + + passthru.providedSessions = ["gamescope-wayland"]; +}) From eaff309a6afb9d06017bf5c65bb20cea1d7695b4 Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 14/15] steam-jupiter: add stubs and polkit-helpers (latter currently disabled) --- pkgs/steam-jupiter/fhsenv.nix | 64 +++++++++++------------------------ 1 file changed, 19 insertions(+), 45 deletions(-) diff --git a/pkgs/steam-jupiter/fhsenv.nix b/pkgs/steam-jupiter/fhsenv.nix index e5c80bd0..e8eb4366 100644 --- a/pkgs/steam-jupiter/fhsenv.nix +++ b/pkgs/steam-jupiter/fhsenv.nix @@ -4,48 +4,23 @@ { lib , runCommand , writeShellScriptBin +, dmidecode +, jovian-stubs , steam-fhsenv +, steamos-polkit-helpers , ... } @ args: let - extraArgs = builtins.removeAttrs args [ "lib" "runCommand" "writeShellScriptBin" "steam-fhsenv" ]; - - # The sudo wrapper doesn't work in FHS environments. For our purposes - # we add a passthrough sudo command that does not actually escalate - # privileges. - # - # - passthroughSudo = writeShellScriptBin "sudo" '' - declare -a final - - positional="" - for value in "$@"; do - if [[ -n "$positional" ]]; then - final+=("$value") - elif [[ "$value" == "-n" ]]; then - : - else - positional="y" - final+=("$value") - fi - done - - exec "''${final[@]}" - ''; - - # Null SteamOS updater that does nothing - # - # This gets us past the OS update step in the OOBE wizard. - nullOsUpdater = writeShellScriptBin "steamos-update" '' - >&2 echo "steamos-update: Not supported on NixOS - Doing nothing" - exit 7; - ''; - - # Null Steam Deck BIOS updater that does nothing - nullBiosUpdater = writeShellScriptBin "jupiter-biosupdate" '' - >&2 echo "jupiter-biosupdate: Doing nothing" - ''; + extraArgs = builtins.removeAttrs args [ + "lib" + "runCommand" + "writeShellScriptBin" + "dmidecode" + "jovian-stubs" + "steam-fhsenv" + "steamos-polkit-helpers" + ]; # A very simplistic "session switcher." All it does is kill gamescope. sessionSwitcher = writeShellScriptBin "steamos-session-select" '' @@ -67,21 +42,20 @@ let mkdir -p ~/.local/state >~/.local/state/steamos-session-select echo "$session" - if [[ -n "$gamescope_pid" ]]; then - kill "$gamescope_pid" - else - >&2 echo "!! Don't know how to kill gamescope" - exit 1 - fi + systemctl stop --user gamescope-session ''; wrappedSteam = steam-fhsenv.override (extraArgs // { extraPkgs = pkgs: (if args ? extraPkgs then args.extraPkgs pkgs else []) ++ [ - nullOsUpdater nullBiosUpdater + dmidecode + jovian-stubs sessionSwitcher + + # FIXME: figure out how to fix pkexec (needs SUID in fhsenv, see https://github.com/NixOS/nixpkgs/issues/69338) + # and readd steamos-polkit-helpers ]; extraProfile = (args.extraProfile or "") + '' - export PATH=${passthroughSudo}/bin:$PATH + export PATH=${jovian-stubs}/bin:$PATH ''; # We need to add this flag when Steam is started directly (e.g., desktop mode) From f7efa7075788fe7c5db3f9a574dc4227dadedb21 Mon Sep 17 00:00:00 2001 From: K900 Date: Sat, 23 Sep 2023 12:08:33 +0300 Subject: [PATCH 15/15] treewide: switch to vendor gamescope-session --- modules/steam/autostart.nix | 15 +- modules/steam/steam.nix | 450 +-------------------------------- pkgs/jovian-greeter/greeter.py | 2 +- 3 files changed, 20 insertions(+), 447 deletions(-) diff --git a/modules/steam/autostart.nix b/modules/steam/autostart.nix index a52912d1..6c31f737 100644 --- a/modules/steam/autostart.nix +++ b/modules/steam/autostart.nix @@ -74,8 +74,19 @@ in displayManager.startx.enable = true; }; - jovian.steam.environment = { - JOVIAN_DESKTOP_SESSION = if cfg.desktopSession != null then cfg.desktopSession else "steam-wayland"; + systemd.user.services.gamescope-session = { + overrideStrategy = "asDropin"; + + environment = lib.mkForce { + JOVIAN_DESKTOP_SESSION = cfg.desktopSession; + }; + + # upstream unit redirects to a file, but this seems unnecessary now? + # see https://github.com/Jovian-Experiments/PKGBUILDs-mirror/blob/76aa4a564094dc656aa1b1daa0f116a7b93b0d7b/gamescope-session.service#L10 + serviceConfig = { + StandardOutput = "journal"; + StandardError = "journal"; + }; }; services.greetd = { diff --git a/modules/steam/steam.nix b/modules/steam/steam.nix index b4f66018..eca5da3a 100644 --- a/modules/steam/steam.nix +++ b/modules/steam/steam.nix @@ -2,346 +2,14 @@ let inherit (lib) - makeBinPath - mapAttrsToList mkDefault mkIf mkMerge - mkOption - types ; - cfg = config.jovian.steam; - - # Note that we override Steam in our overlay - inherit (pkgs) - gamescope - mangohud - bubblewrap - systemd - networkmanager - - jupiter-hw-support - steamdeck-hw-theme - - writeTextFile - writeShellScript - writeShellScriptBin - ; - - # For optimal performance, Gamescope needs to Renice itself at - # launch, it therefore needs the CAP_SYS_NICE capability. Bubblewrap - # can't run a binary with such a capability without being Setuid - # itself. - steam = - if pkgs ? "buildFHSEnv" then - pkgs.steam.override { - buildFHSEnv = pkgs.buildFHSEnv.override { - bubblewrap = "${config.security.wrapperDir}/.."; - }; - } - else - pkgs.steam.override { - buildFHSUserEnv = pkgs.buildFHSUserEnvBubblewrap.override { - bubblewrap = "${config.security.wrapperDir}/.."; - }; - }; - - sessionPath = makeBinPath [ - mangohud - systemd - networkmanager - steam - steam.run - ]; - - sessionEnvironment = builtins.concatStringsSep " " (mapAttrsToList (k: v: "${k}=${v}") config.jovian.steam.environment); - - # Shim that runs steam and associated services. - steam-shim = writeShellScript "steam-shim" '' - export PATH=${sessionPath}:$PATH - - export STEAM_USE_MANGOAPP=1 - export MANGOHUD_CONFIGFILE=$(mktemp $XDG_RUNTIME_DIR/mangohud.XXXXXXXX) - - powerbuttonPath="/dev/input/by-path/platform-i8042-serio-0-event-kbd" - - # Initially write no_display to our config file - # so we don't get mangoapp showing up before Steam initializes - # on OOBE and stuff. - mkdir -p "$(dirname "$MANGOHUD_CONFIGFILE")" - echo "no_display" > "$MANGOHUD_CONFIGFILE" - - # These additional services will be culled when the main service quits too. - # This is done by re-using the same slice name. - - systemd-run --user \ - --collect \ - --slice="steam-session" \ - --unit=steam-session.mangoapp \ - --property=Restart=always \ - --setenv=DISPLAY \ - --setenv=MANGOHUD_CONFIGFILE \ - -- \ - mangoapp - - if test -r "$powerbuttonPath"; then - systemd-run --user \ - --collect \ - --slice="steam-session" \ - --unit=steam-session.power-button-handler \ - --property=Restart=always \ - -- \ - steam-run ${jupiter-hw-support}/lib/hwsupport/power-button-handler.py - else - echo "" - echo "" - echo "================================================================================" - echo "[steam-session] WARNING: Power button device not readable by your user." - echo " Add $USER to the input group to have complete support" - echo " for the Steam Deck's power menu." - echo "================================================================================" - echo "" - echo "" - fi - - if [[ -z "$XDG_SESSION_TYPE" ]]; then - # See start-gamescope-session in the gamescope package for SteamOS - echo "" - echo "NOTE: Assuming this is running embedded (directly in a VT)" - echo "" - for var in DISPLAY XAUTHORITY; do - unset "$var" - export -n "$var" - export XDG_SESSION_TYPE=x11 - export XDG_DESKTOP_PORTAL_DIR="" - done - else - echo "" - echo "NOTE: Assuming this is running nested (within a wayland or X11 session)" - echo "" - fi - - # Workaround for steam crashing leaving gamescope hanging around with broken XWaylands. - # Implemented as such, since we already need to review the whole gamescopoe startup - # process to imitate what Steam now does. - cleanup() { - ( - PS4=" ⇒ " - echo ":: Cleaning up $1" - set -x - pkill -9 steam-session - ) - } - at_exit() { - cleanup "at_exit" - } - at_sigint() { - cleanup "at_sigint" - } - at_sigterm() { - cleanup "at_sigterm" - } - # NOTE: this is to better track the causes. - trap at_exit EXIT - trap at_sigint SIGINT - trap at_sigterm SIGTERM - - set -e - - # OOBE handling. - # (See steam-jupiter.sh in steam-jupiter-oobe and steam-jupiter-stable) - # On first boot, we need to start whatever steam we have packaged, to - # allow the user to connect to the internet. We don't have the luxury - # that Steam's OOBE has to be heavy-handed. So instead we'll see if it - # looks like the user has never started steam. If it looks that way, - # we'll init OOBE, and otherwise undo it. - ( - STEAM_LINKS="$HOME"/.steam - STEAM_DIR="$HOME"/.local/share/Steam - REGISTRY="$STEAM_LINKS"/registry.vdf - - echo ":: Checking if we're offline, or in OOBE..." - if ! test -f "$REGISTRY" || [[ "$(nmcli networking connectivity check)" != full ]]; then - echo " We are!!" - echo " Disabling the updater..." - mkdir -pv "$STEAM_DIR" - printf '# OOBE Inhibit\nBootStrapperInhibitAll = enable' \ - > "$STEAM_DIR"/Steam.cfg - else - echo " We are not" - if grep '^# OOBE Inhibit' "$STEAM_DIR"/Steam.cfg; then - echo " Deleting our own OOBE config." - rm -v "$STEAM_DIR"/Steam.cfg - fi - fi - ) - - steam -steamos3 -steampal -steamdeck -gamepadui "$@" & - wait - ''; - - # Shim that runs gamescope, with a specific environment. - # NOTE: This is only used to provide gamescope_pid. - gamescope-shim = writeShellScript "gamescope-shim" '' - # We will `exec` and thus replace the current process with - # gamescope, which will in turn have the current PID. - export gamescope_pid="''$$" - # gamescope_pid is used by the `steamos-session-select` script. - # TODO[Jovian]: Explore other ways to stop the session? - # -> `systemctl --user stop steam-session.slice`? - - # Plop GAMESCOPE_MODE_SAVE_FILE into $XDG_CONFIG_HOME (defaults to ~/.config). - export GAMESCOPE_MODE_SAVE_FILE="''${XDG_CONFIG_HOME:-$HOME/.config}/gamescope/modes.cfg" - export GAMESCOPE_PATCHED_EDID_FILE="''${XDG_CONFIG_HOME:-$HOME/.config}/gamescope/edid.bin" - - exec ${config.security.wrapperDir}/gamescope "$@" - ''; - - # TODO: consume width/height script input params - # TODO: consume script input param to disable fullscreening - # TODO: pass down unhandled arguments - # Script that launches the gamescope shim within a systemd scope. - steam-session = writeShellScriptBin "steam-session" '' - GAMESCOPE_WIDTH=''${GAMESCOPE_WIDTH:-1280} - GAMESCOPE_HEIGHT=''${GAMESCOPE_HEIGHT:-800} - - SLICE="steam-session" - - runtime_dir="$XDG_RUNTIME_DIR/$SLICE.run" - mkdir -p "$runtime_dir" - export GAMESCOPE_STATS="$runtime_dir/stats.pipe" - rm -f "$GAMESCOPE_STATS" - mkfifo -- "$GAMESCOPE_STATS" - - # To play nice with the short term callback-based limiter for now - # - # This file is also read by the SteamOS version of Mesa/RADV to override - # the swap interval. - # - # With pressure-vessel, only certain subpaths of $XDG_RUNTIME_DIR - # are bind-mounted into the sandbox. As a result, we use --tmpdir here - # instead of $runtime_dir. - export GAMESCOPE_LIMITER_FILE=$(mktemp --tmpdir gamescope-limiter.XXXXXXXX) - - # Prepare our initial VRS config file for dynamic VRS in Mesa. - # - # Same as above. - export RADV_FORCE_VRS_CONFIG_FILE=$(mktemp --tmpdir radv_vrs.XXXXXXXX) - echo "1x1" > "$RADV_FORCE_VRS_CONFIG_FILE" - - # Prepare gamescope mode save file (3.1.44+) - gamescope_config_dir="''${XDG_CONFIG_HOME:-$HOME/.config}/gamescope" - mkdir -p "$gamescope_config_dir" - export GAMESCOPE_MODE_SAVE_FILE="$gamescope_config_dir/modes.cfg" - touch "$GAMESCOPE_MODE_SAVE_FILE" - - gamescope_incantation=( - "${gamescope-shim}" - - # Steam intrinsically knows it can use one of the layer for the - # game, and the other for its overlay UI. - # TODO[Jovian]: verify assertion - --xwayland-count 2 - - -w $GAMESCOPE_WIDTH -h $GAMESCOPE_HEIGHT - - --fullscreen - - # TODO[Jovian]: document why '*' here - --prefer-output '*',eDP-1 - --generate-drm-mode fixed - --max-scale 2 - - --default-touch-mode 4 - - --hide-cursor-delay 3000 - --fade-out-duration 200 - # TODO[Jovian]: Provide our own cursor for FOSS steam-less gamescope - # -> adwaita or similar - --cursor ${steamdeck-hw-theme}/share/steamos/steamos-cursor.png - --cursor-hotspot 5,3 - - # TODO[Jovian]: only add when running steam - --steam - - # Steam uses this - # TODO[Jovian]: document how it's used? - --stats-path "$GAMESCOPE_STATS" - - # Not needed when executing steam as a child process - # --ready-fd "$socket" - - -- - systemd-run --user - --collect - --scope - --slice="$SLICE" - - -- - - "${steam-shim}" "$@" - ) - - at_exit() { - systemctl --quiet --user stop "$SLICE.slice" - } - trap at_exit SIGINT SIGTERM EXIT - - PS4=" [steam-session] $ " - set -x - - ${sessionEnvironment} "''${gamescope_incantation[@]}" - ''; - - steam-session-desktop = (writeTextFile { - name = "steam-session-desktop"; - destination = "/share/wayland-sessions/steam-wayland.desktop"; - text = '' - [Desktop Entry] - Encoding=UTF-8 - Name=Gaming Mode - Exec=${steam-session}/bin/steam-session - Icon=steamicon.png - Type=Application - DesktopNames=gamescope - ''; - }) // { - providedSessions = [ "steam-wayland" ]; - }; + cfg = config.jovian.steam; in { - options = { - jovian = { - steam = { - environment = mkOption { - type = types.attrsOf types.str; - default = {}; - description = lib.mdDoc '' - Environment variables to set for Steam. - ''; - }; - - useStockEnvironment = mkOption { - type = types.bool; - default = true; - description = lib.mdDoc '' - Whether to use the stock environment variables from gamescope-session. - ''; - }; - - useStockSteamDeckEnvironment = mkOption { - type = types.bool; - default = config.jovian.devices.steamdeck.enable; - defaultText = lib.literalExpression "config.jovian.devices.steamdeck.enable"; - description = lib.mdDoc '' - Whether to use the Steam Deck-specific environment variables from stock gamescope-session. - ''; - }; - }; - }; - }; - config = mkIf cfg.enable (mkMerge [ { warnings = [] @@ -352,26 +20,20 @@ in security.wrappers.gamescope = { owner = "root"; group = "root"; - source = "${gamescope}/bin/gamescope"; + source = "${pkgs.gamescope}/bin/gamescope"; capabilities = "cap_sys_nice+pie"; }; } - { - security.wrappers.bwrap = { - owner = "root"; - group = "root"; - source = "${bubblewrap}/bin/bwrap"; - setuid = true; - }; - } { hardware.opengl.driSupport32Bit = true; hardware.pulseaudio.support32Bit = true; hardware.steam-hardware.enable = mkDefault true; - environment.systemPackages = [ steam-session ]; + environment.systemPackages = [ pkgs.gamescope-session pkgs.steamos-polkit-helpers ]; + + systemd.packages = [ pkgs.gamescope-session ]; - services.xserver.displayManager.sessionPackages = [ steam-session-desktop ]; + services.xserver.displayManager.sessionPackages = [ pkgs.gamescope-session ]; # Conflicts with power-button-handler services.logind.extraConfig = '' @@ -397,105 +59,5 @@ in }); ''; } - (mkIf cfg.useStockEnvironment { - jovian.steam.environment = { - # Set input method modules for Qt/GTK that will show the Steam keyboard - QT_IM_MODULE = "steam"; - GTK_IM_MODULE = "Steam"; - - # Enable volume key management via steam for this session - STEAM_ENABLE_VOLUME_HANDLER = "1"; - - # Have SteamRT's xdg-open send http:// and https:// URLs to Steam - SRT_URLOPEN_PREFER_STEAM = "1"; - - # Disable automatic audio device switching in steam, now handled by wireplumber - STEAM_DISABLE_AUDIO_DEVICE_SWITCHING = "1"; - - # Let steam know it can unmount drives without superuser privileges - STEAM_ALLOW_DRIVE_UNMOUNT = "1"; - - # Allow formatting external drives - STEAM_ALLOW_DRIVE_ADOPT = "1"; - - # Enable support for xwayland isolation per-game in Steam - STEAM_MULTIPLE_XWAYLANDS = "1"; - - # We have the Mesa integration for the fifo-based dynamic fps-limiter - STEAM_GAMESCOPE_DYNAMIC_FPSLIMITER = "1"; - - # We have NIS support - STEAM_GAMESCOPE_NIS_SUPPORTED = "1"; - - # Support for gamescope tearing with GAMESCOPE_ALLOW_TEARING atom (3.11.44+) - STEAM_GAMESCOPE_HAS_TEARING_SUPPORT = "1"; - - # Enable tearing controls in steam - STEAM_GAMESCOPE_TEARING_SUPPORTED = "1"; - - # When set to 1, a toggle will show up in the steamui to control whether dynamic refresh rate is applied to the steamui - STEAM_GAMESCOPE_DYNAMIC_REFRESH_IN_STEAM_SUPPORTED = "0"; - - # Enable VRR controls in steam - STEAM_GAMESCOPE_VRR_SUPPORTED = "1"; - - # Scaling support - STEAM_GAMESCOPE_FANCY_SCALING_SUPPORT = "1"; - - # Color management support - STEAM_GAMESCOPE_COLOR_MANAGED = "1"; - STEAM_GAMESCOPE_VIRTUAL_WHITE = "1"; - - # Enable HDR support in steam - STEAM_GAMESCOPE_HDR_SUPPORTED = "1"; - - # Set refresh rate range and enable refresh rate switching - STEAM_DISPLAY_REFRESH_LIMITS = "40,60"; - - # We no longer need to set GAMESCOPE_EXTERNAL_OVERLAY from steam, mangoapp now does it itself - STEAM_DISABLE_MANGOAPP_ATOM_WORKAROUND = "1"; - - # Enable horizontal mangoapp bar - STEAM_MANGOAPP_HORIZONTAL_SUPPORTED = "1"; - - # Enable mangoapp overlay presets - STEAM_MANGOAPP_PRESETS_SUPPORTED = "1"; - - STEAM_USE_DYNAMIC_VRS = "1"; - - STEAM_UPDATEUI_PNG_BACKGROUND = "${steamdeck-hw-theme}/share/steamos/steamos.png"; - - # Don't wait for buffers to idle on the client side before sending them to gamescope - vk_xwayland_wait_ready = "false"; - - # There is no way to set a color space for an NV12 - # buffer in Wayland. And the color management protocol that is - # meant to let this happen is missing the color range... - # So just workaround this with an ENV var that Remote Play Together - # and Gamescope will use for now. - GAMESCOPE_NV12_COLORSPACE = "k_EStreamColorspace_BT601"; - - # To expose vram info from radv's patch we're including - WINEDLLOVERRIDES = "dxgi=n"; - - XCURSOR_THEME = "steam"; - - SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS = "0"; - }; - }) - (mkIf cfg.useStockSteamDeckEnvironment { - jovian.steam.environment = { - # Enable dynamic backlight, we have the kernel patch to disable events - STEAM_ENABLE_DYNAMIC_BACKLIGHT = "1"; - - # Enabled fan control toggle in steam - STEAM_ENABLE_FAN_CONTROL = "1"; - - # Let's try this across the board to see if it breaks anything - # Helps performance in HZD, Cyberpunk, at least - # Expose 8 physical cores, instead of 4c/8t - WINE_CPU_TOPOLOGY = "8:0,1,2,3,4,5,6,7"; - }; - }) ]); } diff --git a/pkgs/jovian-greeter/greeter.py b/pkgs/jovian-greeter/greeter.py index 5798a2e9..0e7a6701 100644 --- a/pkgs/jovian-greeter/greeter.py +++ b/pkgs/jovian-greeter/greeter.py @@ -12,7 +12,7 @@ from pathlib import Path from typing import Any, Optional, Iterable, Mapping, List -DEFAULT_SESSION = 'steam-wayland' +DEFAULT_SESSION = 'gamescope-wayland' HELPER_PREFIX = Path('/run/current-system/sw/lib/jovian-greeter') class Session: