I have no idea :\ I use KDE as well but do not use kscreen-doctor
(I use the default conf
). I am using (mostly) the latest version of nixpkgs-unstable.
Hi! Did you ever find a solution to this? You are correct that this is caused by the security wrapper, but is there any way around it?
I’m facing the same issue. Have you managed to solve it?
I’ve worked around the security wrapper issue by creating a separate service for launching Steam games, one that is not encumbered by a security wrapper.
First, the service:
systemd.user.services.steam-run-url-service = {
enable = true;
description = "Listen and starts steam games by id";
wantedBy = ["graphical-session.target"];
partOf = [ "graphical-session.target" ];
wants = [ "graphical-session.target" ];
after = [ "graphical-session.target" ];
serviceConfig.Restart = "on-failure";
script = toString (pkgs.writers.writePython3 "steam-run-url-service" {} ''
import os
from pathlib import Path
import subprocess
pipe_path = Path(f'/run/user/{os.getuid()}/steam-run-url.fifo')
try:
pipe_path.parent.mkdir(parents=True, exist_ok=True)
pipe_path.unlink(missing_ok=True)
os.mkfifo(pipe_path, 0o600)
while True:
with pipe_path.open(encoding='utf-8') as pipe:
subprocess.Popen(['steam', pipe.read().strip()])
finally:
pipe_path.unlink(missing_ok=True)
'');
path = [
pkgs.steam
];
The service waits for a client to pipe Steam URL (e.g. steam://rungameid/1086940
) to a file at /run/user/1000/steam-run-url.fifo
(where 1000
is your user id). Upon reading an URL from the file the service launches Steam, passing the received URL to it.
Once you have the service running you can start a game with command:
# Launch Baldur's Gate 3
echo "steam://rungameid/1086940" > "/run/user/$(id --user)/steam-run-url.fifo"
Any terminal output from the game goes to steam-run-url-service
’s journal, which you can see with:
journalctl --user -u steam-run-url-service.service
To make it easier to launch games the launch command can be wrapped into a script:
steam-run-url = pkgs.writeShellApplication {
name = "steam-run-url";
text = ''
echo "$1" > "/run/user/$(id --user)/steam-run-url.fifo"
'';
runtimeInputs = [
pkgs.coreutils # For `id` command
];
};
Then add it to your environment so that it can be called from shell:
environment.systemPackages = [ steam-run-url ];
Examples:
steam-run-url steam://rungameid/1086940 # Start Baldur's Gate 3
steam-run-url steam://open/bigpicture # Start Steam in Big Picture mode
And finally, put it to Sunshine service’s PATH. This way you can use it in Sunshine’s app settings as a detached command:
systemd.user.services.sunshine.path = [ steam-run-url ];
In Sunshine’s app settings replace e.g. call:
setsid steam steam://rungameid/1086940
With:
steam-run-url steam://rungameid/1086940
See my Sunshine config for full example.
Thank you! it will surely be useful to me
Someone managed to turn on the screen with sunshine the hyprctl dispatch dpms command we work in the terminal but sunshine can’t do it.
Since headless is broken immediately, I stream the screen directly, but I have to turn on the screen first.
I have tried this and worked flawlessly. Thank you very much for solving it!
Hello,
I tried jhakonen’s solution, it does work and launch big picture properly.
However, it cause another annoying issue :
It prevents KDE from shutting down, logging out, or reboot… The only way to do it is to type “sudo reboot” in the console.
Even if i force close sunshine i still can’t shutdown/log out from KDE.
I tried simpler code with :
{
lib,
config,
pkgs,
...
}: {
# Sunshine Service Configuration
services.sunshine = {
enable = true;
autoStart = true;
capSysAdmin = true;
openFirewall = true;
settings = {
sunshine_name = "Barbatos-NixOS";
output_name = 1;
key_rightalt_to_key_win = "enabled";
};
applications = {
apps = [
{
name = "Launch BigSteam";
detached = [
"steam steam://open/gamepadui"
];
image-path = "steam.png";
}
];
};
};
}
And i noticed the same issue : sunshine prevents from KDE to logout/shutdown. However in this particular scenario, if i kill sunshine, KDE instantly logs out/shutdown properly.
I tried the same with autoStart = false; and launched sunshine manually, and this time i had no issue to logout/timeout.
So i suspect a systemd sequence issue with KDE, however the thing i don’t understand is when i start to look for a sunshine.service i can’t find anything :
systemctl status sunshine.service
Unit sunshine.service could not be found.
I also tried to write my own systemd to start sunshine, it works, but it didn’t take the settings defined in my services.sunshine…
I also tried to write my own KDE autostart script to start sunshine, and set it via home-manager, it does launch sunshine and doesn’t break KDE, however again it’s not taking settings from services.sunshine…
I’m still new to NixOS, and i have no clue how to properly debug and solve this issue, any help please?
Thanks !
You should start by looking at what the module does if you want to debug it:
Also it’s a user service, so you need to use --user
when using systemctl
.
Okay, from what I see here, both sunshine module and jhakonen’s systemd steam-run-url-service rely on “graphical-session.target” to start, which seems to cause issues on KDE.
Many questions :
-
- What can i put instead of graphical-session.target to avoid the logout/shutdown issue on kde?
-
- I’m still confused, why when i try to look for systemctl status sunshine.service or systemctl status steam-run-url-service.service, it says the unit could not be found ?
I think i might be on a good path right now :
I just noticed that graphical-session.target didn’t exist on my system, however there is graphical.target instead !
i replaced it in jhakonen’s systemd steam-run-url-service and now, the issue seems to be better, when i try to shutdown from KDE, only sunshine is preventing from it.
Probably because it uses “graphical-session.target” in here, how can i override the value of the sunshine module ?
I didn’t told it so far but I’m running on NixOS 24.11 with KDE
As I said, you need to use --user
for user services.
I did some good progress, now i’m able to shutdown and reboot, only logout isn’t working as intended now :
If i wan’t to logout from KDE, i need to click on logout, and then force manually sunshine.service to stop : systemctl stop sunshine.service --user
Here is my sunshine.nix
{
config,
lib,
pkgs,
...
}: let
# Helper utility for launching Steam games from Sunshine. This works around
# issue where Sunshine's security wrapper prevents Steam from launching.
# Examples:
# steam-run-url steam://rungameid/1086940 # Start Baldur's Gate 3
# steam-run-url steam://open/bigpicture # Start Steam in Big Picture mode
steam-run-url = pkgs.writeShellApplication {
name = "steam-run-url";
text = ''
echo "$1" > "/run/user/$(id --user)/steam-run-url.fifo"
'';
runtimeInputs = [
pkgs.coreutils # For `id` command
];
};
in {
# Sunshine Service Configuration
services.sunshine = {
enable = true;
capSysAdmin = true;
openFirewall = true;
settings = {
sunshine_name = "Barbatos-NixOS";
output_name = 1;
key_rightalt_to_key_win = "enabled";
};
applications = {
apps = [
{
name = "Launch BigSteam";
detached = [
"steam-run-url steam://open/gamepadui"
];
image-path = "steam.png";
}
];
};
};
systemd.user.services.sunshine = {
description = "Self-hosted game stream host for Moonlight";
path = [steam-run-url]; # Allow running `steam-run-url` from Sunshine without knowing the script's
wantedBy = ["graphical.target"];
partOf = ["graphical.target"];
wants = ["graphical.target"];
after = ["graphical.target"];
serviceConfig = {
ExecStop = "${pkgs.procps}/bin/pkill -SIGTERM -f sunshine";
ExecStopPost = "${pkgs.procps}/bin/pkill -SIGKILL -f sunshine";
KillSignal = "SIGTERM";
Restart = "on-failure";
TimeoutStopSec = "10s";
KillMode = "mixed";
type = "simple";
};
};
# Allow running `steam-run-url` from shell for testing purposes
environment.systemPackages = [steam-run-url];
# Service part for `steam-run-url`. This listens for Steam urls from a named
# pipe (typically at path `/run/user/1000/steam-run-url.fifo`) and then
# launches Steam, passing the url to it.
systemd.user.services.steam-run-url-service = {
enable = true;
description = "Listen and starts steam games by id";
wantedBy = ["default.target"];
partOf = ["default.target"];
wants = ["default.target"];
after = ["default.target"];
serviceConfig.Restart = "on-failure";
script = toString (pkgs.writers.writePython3 "steam-run-url-service" {} ''
import os
from pathlib import Path
import subprocess
pipe_path = Path(f'/run/user/{os.getuid()}/steam-run-url.fifo')
try:
pipe_path.parent.mkdir(parents=True, exist_ok=True)
pipe_path.unlink(missing_ok=True)
os.mkfifo(pipe_path, 0o600)
while True:
with pipe_path.open(encoding='utf-8') as pipe:
subprocess.Popen(['steam', pipe.read().strip()])
finally:
pipe_path.unlink(missing_ok=True)
'');
path = [
pkgs.gamemode
pkgs.steam
];
};
}
Had to slightly adjust the python script to get Steam to launch if not already running.
systemd.user.services.steam-run-url-service = {
enable = true;
description = "Listen and starts steam games by id";
wantedBy = ["default.target"];
partOf = ["default.target"];
wants = ["default.target"];
after = ["default.target"];
serviceConfig.Restart = "on-failure";
script = toString (pkgs.writers.writePython3 "steam-run-url-service" {} ''
import os
from pathlib import Path
import subprocess
pipe_path = Path(f'/run/user/{os.getuid()}/steam-run-url.fifo')
try:
pipe_path.parent.mkdir(parents=True, exist_ok=True)
pipe_path.unlink(missing_ok=True)
os.mkfifo(pipe_path, 0o600)
steam_env = os.environ.copy()
steam_env["QT_QPA_PLATFORM"] = "wayland"
while True:
with pipe_path.open(encoding='utf-8') as pipe:
subprocess.Popen(['steam', pipe.read().strip()], env=steam_env)
finally:
pipe_path.unlink(missing_ok=True)
'');
path = [
pkgs.gamemode
pkgs.steam
];
};