OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
HASH      dce0046ad9df
DATE      2026-06-07
SUBJECT   sunshine/moonlite: module init
FILES     7 CHANGED
HASH      dce0046ad9df
DATE      2026-06-07
SUBJECT   sunshine/moonlite: module init
FILES     7 CHANGED
 

diff --git a/hosts/ooksdesk/default.nix b/hosts/ooksdesk/default.nix
index 843c16d..b8d3647 100644
--- a/hosts/ooksdesk/default.nix
+++ b/hosts/ooksdesk/default.nix
@@ -25,6 +25,7 @@
     workstation = {
       environment = "hyprland";
       theme = "minimal";
+      sunshine.enable = true;
       profiles = ["creative" "virtualization" "gaming" "media" "communication" "p
roductivity" "infra" "work"];
       default = {
         browser = "zen";

diff --git a/hosts/ooksdesk/default.nix b/ho
sts/ooksdesk/default.nix
index 843c16d..b8d3647 100644
--- a/hosts/ooksdesk/default.nix
+++ b/hosts/ooksdesk/default.nix
@@ -25,6 +25,7 @@
     workstation = {
       environment = "hyprland";
       theme = "minimal";
+      sunshine.enable = true;
       profiles = ["creative" "virtualizatio
n" "gaming" "media" "communication" "product
ivity" "infra" "work"];
       default = {
         browser = "zen";
 

diff --git a/modules/darwin/packages.nix b/modules/darwin/packages.nix
index a08ade7..bf50b0a 100644
--- a/modules/darwin/packages.nix
+++ b/modules/darwin/packages.nix
@@ -28,6 +28,7 @@ in {
         "obsidian"
         "microsoft-teams"
         "slack"
+        "moonlight"
       ]
       ++ optionals (default.terminal == "ghostty" || programs.ghostty.enable) ["g
hostty"]
       ++ optionals (default.browser == "firefox" || programs.firefox.enable) ["fi
refox"]

diff --git a/modules/darwin/packages.nix b/m
odules/darwin/packages.nix
index a08ade7..bf50b0a 100644
--- a/modules/darwin/packages.nix
+++ b/modules/darwin/packages.nix
@@ -28,6 +28,7 @@ in {
         "obsidian"
         "microsoft-teams"
         "slack"
+        "moonlight"
       ]
       ++ optionals (default.terminal == "gh
ostty" || programs.ghostty.enable) ["ghostty
"]
       ++ optionals (default.browser == "fir
efox" || programs.firefox.enable) ["firefox"
]
 

diff --git a/modules/home/nixos/hyprland/components/hypridle.nix b/modules/home/ni
xos/hyprland/components/hypridle.nix
index 7dbac3a..049ae6b 100644
--- a/modules/home/nixos/hyprland/components/hypridle.nix
+++ b/modules/home/nixos/hyprland/components/hypridle.nix
@@ -5,8 +5,8 @@
   config,
   ...
 }: let
-  inherit (lib) getExe getExe' mkIf;
-  inherit (osConfig.ooknet.workstation) environment;
+  inherit (lib) getExe getExe' mkIf optionals;
+  inherit (osConfig.ooknet.workstation) environment sunshine;
 
   dpms = "${getExe' osConfig.programs.hyprland.package "hyprctl"} dispatch dpms";
   lock = "${getExe' pkgs.systemd "loginctl"} lock-session";
@@ -20,17 +20,22 @@ in {
           lock_cmd = hyprlock;
           before_sleep_cmd = lock;
         };
-        listener = [
-          {
-            timeout = 300;
-            on-timeout = hyprlock;
-          }
-          {
-            timeout = 360;
-            on-timeout = "${dpms} off";
-            on-resume = "${dpms} on";
-          }
-        ];
+        listener =
+          [
+            {
+              timeout = 300;
+              on-timeout = hyprlock;
+            }
+          ]
+          # keep the display powered on while sunshine streaming is enabled
+          # wayland kms capture 503s on a dpms-off display and cant be woken remo
tely
+          ++ optionals (!sunshine.enable) [
+            {
+              timeout = 360;
+              on-timeout = "${dpms} off";
+              on-resume = "${dpms} on";
+            }
+          ];
       };
     };
   };

diff --git a/modules/home/nixos/hyprland/com
ponents/hypridle.nix b/modules/home/nixos/hy
prland/components/hypridle.nix
index 7dbac3a..049ae6b 100644
--- a/modules/home/nixos/hyprland/components
/hypridle.nix
+++ b/modules/home/nixos/hyprland/components
/hypridle.nix
@@ -5,8 +5,8 @@
   config,
   ...
 }: let
-  inherit (lib) getExe getExe' mkIf;
-  inherit (osConfig.ooknet.workstation) env
ironment;
+  inherit (lib) getExe getExe' mkIf optiona
ls;
+  inherit (osConfig.ooknet.workstation) env
ironment sunshine;
 
   dpms = "${getExe' osConfig.programs.hyprl
and.package "hyprctl"} dispatch dpms";
   lock = "${getExe' pkgs.systemd "loginctl"
} lock-session";
@@ -20,17 +20,22 @@ in {
           lock_cmd = hyprlock;
           before_sleep_cmd = lock;
         };
-        listener = [
-          {
-            timeout = 300;
-            on-timeout = hyprlock;
-          }
-          {
-            timeout = 360;
-            on-timeout = "${dpms} off";
-            on-resume = "${dpms} on";
-          }
-        ];
+        listener =
+          [
+            {
+              timeout = 300;
+              on-timeout = hyprlock;
+            }
+          ]
+          # keep the display powered on whi
le sunshine streaming is enabled
+          # wayland kms capture 503s on a d
pms-off display and cant be woken remotely
+          ++ optionals (!sunshine.enable) [
+            {
+              timeout = 360;
+              on-timeout = "${dpms} off";
+              on-resume = "${dpms} on";
+            }
+          ];
       };
     };
   };
 

diff --git a/modules/nixos/workstation/services/default.nix b/modules/nixos/workst
ation/services/default.nix
index a50d475..8a36d04 100644
--- a/modules/nixos/workstation/services/default.nix
+++ b/modules/nixos/workstation/services/default.nix
@@ -4,5 +4,6 @@
     ./gnome-services.nix
     ./geoclue.nix
     ./ollama.nix
+    ./sunshine.nix
   ];
 }

diff --git a/modules/nixos/workstation/servi
ces/default.nix b/modules/nixos/workstation/
services/default.nix
index a50d475..8a36d04 100644
--- a/modules/nixos/workstation/services/def
ault.nix
+++ b/modules/nixos/workstation/services/def
ault.nix
@@ -4,5 +4,6 @@
     ./gnome-services.nix
     ./geoclue.nix
     ./ollama.nix
+    ./sunshine.nix
   ];
 }
 

diff --git a/modules/nixos/workstation/services/sunshine.nix b/modules/nixos/works
tation/services/sunshine.nix
new file mode 100644
index 0000000..3242f57
--- /dev/null
+++ b/modules/nixos/workstation/services/sunshine.nix
@@ -0,0 +1,44 @@
+{
+  lib,
+  config,
+  pkgs,
+  ...
+}: let
+  inherit (lib) mkIf getExe';
+  inherit (config.ooknet.workstation) sunshine;
+
+  hyprctl = getExe' config.programs.hyprland.package "hyprctl";
+  systemctl = getExe' pkgs.systemd "systemctl";
+
+  # sunshine runs prep cmds without a shell, so wrap them in a script
+  # never fail the stream over a convenience cmd, hence the `|| true`
+  prepDo = pkgs.writeShellScript "sunshine-prep-do" ''
+    ${hyprctl} dispatch dpms on || true
+    ${systemctl} --user stop hypridle.service || true
+  '';
+  prepUndo = pkgs.writeShellScript "sunshine-prep-undo" ''
+    ${systemctl} --user start hypridle.service || true
+  '';
+in {
+  config = mkIf sunshine.enable {
+    services.sunshine = {
+      enable = true;
+      autoStart = true;
+      # CAP_SYS_ADMIN for KMS/DRM capture on wayland
+      capSysAdmin = true;
+      # reachable over the trusted tailscale0 interface, pair locally via https:/
/localhost:47990
+      openFirewall = false;
+      # wake the display and pause hypridle for the duration of a stream
+      # sunshine wants this as a json string, not a nix list
+      settings.global_prep_cmd = builtins.toJSON [
+        {
+          do = "${prepDo}";
+          undo = "${prepUndo}";
+        }
+      ];
+    };
+
+    # vainfo, to verify vaapi encode is picked up
+    environment.systemPackages = [pkgs.libva-utils];
+  };
+}

diff --git a/modules/nixos/workstation/servi
ces/sunshine.nix b/modules/nixos/workstation
/services/sunshine.nix
new file mode 100644
index 0000000..3242f57
--- /dev/null
+++ b/modules/nixos/workstation/services/sun
shine.nix
@@ -0,0 +1,44 @@
+{
+  lib,
+  config,
+  pkgs,
+  ...
+}: let
+  inherit (lib) mkIf getExe';
+  inherit (config.ooknet.workstation) sunsh
ine;
+
+  hyprctl = getExe' config.programs.hyprlan
d.package "hyprctl";
+  systemctl = getExe' pkgs.systemd "systemc
tl";
+
+  # sunshine runs prep cmds without a shell
, so wrap them in a script
+  # never fail the stream over a convenienc
e cmd, hence the `|| true`
+  prepDo = pkgs.writeShellScript "sunshine-
prep-do" ''
+    ${hyprctl} dispatch dpms on || true
+    ${systemctl} --user stop hypridle.servi
ce || true
+  '';
+  prepUndo = pkgs.writeShellScript "sunshin
e-prep-undo" ''
+    ${systemctl} --user start hypridle.serv
ice || true
+  '';
+in {
+  config = mkIf sunshine.enable {
+    services.sunshine = {
+      enable = true;
+      autoStart = true;
+      # CAP_SYS_ADMIN for KMS/DRM capture o
n wayland
+      capSysAdmin = true;
+      # reachable over the trusted tailscal
e0 interface, pair locally via https://local
host:47990
+      openFirewall = false;
+      # wake the display and pause hypridle
 for the duration of a stream
+      # sunshine wants this as a json strin
g, not a nix list
+      settings.global_prep_cmd = builtins.t
oJSON [
+        {
+          do = "${prepDo}";
+          undo = "${prepUndo}";
+        }
+      ];
+    };
+
+    # vainfo, to verify vaapi encode is pic
ked up
+    environment.systemPackages = [pkgs.libv
a-utils];
+  };
+}
 

diff --git a/modules/options/workstation/default.nix b/modules/options/workstation
/default.nix
index 4dcb4d7..2f4e5ca 100644
--- a/modules/options/workstation/default.nix
+++ b/modules/options/workstation/default.nix
@@ -21,6 +21,7 @@ in {
     silentBoot = {
       enable = mkEnableOption "Enable silent boot with plymouth";
     };
+    sunshine.enable = mkEnableOption "Sunshine game/desktop streaming host";
     environment = mkOption {
       type = nullOr (enum ["hyprland" "gnome" "aerospace"]);
       default = "hyprland";

diff --git a/modules/options/workstation/def
ault.nix b/modules/options/workstation/defau
lt.nix
index 4dcb4d7..2f4e5ca 100644
--- a/modules/options/workstation/default.ni
x
+++ b/modules/options/workstation/default.ni
x
@@ -21,6 +21,7 @@ in {
     silentBoot = {
       enable = mkEnableOption "Enable silen
t boot with plymouth";
     };
+    sunshine.enable = mkEnableOption "Sunsh
ine game/desktop streaming host";
     environment = mkOption {
       type = nullOr (enum ["hyprland" "gnom
e" "aerospace"]);
       default = "hyprland";
 

diff --git a/outputs/ook/lib/services.nix b/outputs/ook/lib/services.nix
index a0dedf6..63ba9d2 100644
--- a/outputs/ook/lib/services.nix
+++ b/outputs/ook/lib/services.nix
@@ -11,7 +11,10 @@
   mkTrayService = exec: {
     Unit = {
       Requires = ["tray.target"];
-      After = ["graphical-session-pre.target" "tray.target"];
+      # graphical-session.target needs an explicit After, without it systemd inje
cts an
+      # implicit Before=graphical-session.target which loops back through
+      # tray.target -> waybar -> graphical-session.target and breaks session star
tup
+      After = ["graphical-session.target" "graphical-session-pre.target" "tray.ta
rget"];
       PartOf = ["graphical-session.target"];
     };
     Service = {

diff --git a/outputs/ook/lib/services.nix b/
outputs/ook/lib/services.nix
index a0dedf6..63ba9d2 100644
--- a/outputs/ook/lib/services.nix
+++ b/outputs/ook/lib/services.nix
@@ -11,7 +11,10 @@
   mkTrayService = exec: {
     Unit = {
       Requires = ["tray.target"];
-      After = ["graphical-session-pre.targe
t" "tray.target"];
+      # graphical-session.target needs an e
xplicit After, without it systemd injects an
+      # implicit Before=graphical-session.t
arget which loops back through
+      # tray.target -> waybar -> graphical-
session.target and breaks session startup
+      After = ["graphical-session.target" "
graphical-session-pre.target" "tray.target"]
;
       PartOf = ["graphical-session.target"]
;
     };
     Service = {
 
[ BACK TO LOG ]
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET