Enhances gaming sessions with gamescope commands

- Refactors monitor handling by computing primary monitor parameters
- Introduces new shell scripts for gamescope-run and steam-session integration
- Updates desktop entries to launch Steam and Heroic within gamescope
- Removes deprecated gaming session script from the global gaming configuration
- Simplifies monitor options and adds primary monitor utility in shared libraries
- Adjusts host-specific monitor configurations and README hardware details
This commit is contained in:
Chris Toph 2025-06-20 17:41:08 -04:00
parent 12ac221b46
commit 894cc4444c
7 changed files with 177 additions and 83 deletions

View file

@ -4,6 +4,81 @@
lib,
...
}:
let
primaryMonitor = lib.custom.getPrimaryMonitor (config.monitors or [ ]);
WIDTH = primaryMonitor.width or 1980;
HEIGHT = primaryMonitor.height or 1080;
REFRESH_RATE = primaryMonitor.refreshRate or 60;
VRR = primaryMonitor.vrr or false;
HDR = primaryMonitor.hdr or false;
# INFO: Example working commands for running games in steam-session
## Rivals ##
# SteamDeck=1 LD_PRELOAD="" PROTON_ENABLE_NVAPI=1 PROTON_ENABLE_WAYLAND=1 VKD3D_DISABLE_EXTENSIONS=VK_KHR_present_wait gamemoderun %command% -PSOCompileMode=1 -dx12
## Stats Overlay ##
# gamemoderun mangohud %command%
## gamescope-run ##
# GAMESCOPE_EXTRA_OPTS="--force-grab-cursor"; gamescope-run gamemoderun mangohud %command%
gamescope-base-script = pkgs.writeShellScript "gamescope-base" ''
# Session configuration
export CAP_SYS_NICE="eip"
export DXVK_HDR="1"
export ENABLE_GAMESCOPE_WSI="1"
export ENABLE_HDR_WSI="1"
export AMD_VULKAN_ICD=RADV
export RADV_PERFTEST=aco
export SDL_VIDEODRIVER="wayland"
# Steam environment variables for better compatibility
export STEAM_FORCE_DESKTOPUI_SCALING=1
export STEAM_GAMEPADUI=1
export STEAM_GAMESCOPE_CLIENT=1
# Default resolution settings
WIDTH=${toString WIDTH}
HEIGHT=${toString HEIGHT}
REFRESH_RATE=${toString REFRESH_RATE}
# Build gamescope options
GAMESCOPE_OPTS="--fade-out-duration 200 -w $WIDTH -h $HEIGHT -r $REFRESH_RATE -f"
GAMESCOPE_OPTS="$GAMESCOPE_OPTS --expose-wayland --backend sdl --rt --immediate-flips"
${lib.optionalString HDR ''GAMESCOPE_OPTS="$GAMESCOPE_OPTS --hdr-enabled --hdr-debug-force-output --hdr-itm-enable"''}
${lib.optionalString VRR ''GAMESCOPE_OPTS="$GAMESCOPE_OPTS --adaptive-sync"''}
# Allow extra options to be passed
GAMESCOPE_OPTS="$GAMESCOPE_OPTS $GAMESCOPE_EXTRA_OPTS"
# Execute gamescope with provided command
exec ${lib.getExe pkgs.gamescope} $GAMESCOPE_OPTS -- "$@"
'';
gamescope-run = pkgs.writeShellScriptBin "gamescope-run" ''
if [ $# -eq 0 ]; then
echo "Usage: gamescope-run <command> [args...]"
echo "Examples:"
echo " gamescope-run heroic"
echo " gamescope-run steam"
echo " gamescope-run lutris"
exit 1
fi
exec ${gamescope-base-script} "$@"
'';
steam-session-script = pkgs.writeShellScript "steam-session-script" ''
# Check launch mode parameter
case "$1" in
"desktop")
# Launch Steam in desktop mode within gamescope
exec ${gamescope-base-script} ${lib.getExe pkgs.steam}
;;
"bigpicture"|*)
# Default: Launch Steam in Big Picture mode
exec ${gamescope-base-script} ${lib.getExe pkgs.steam} -tenfoot -steamdeck -gamepadui
;;
esac
'';
in
{
imports = lib.custom.scanPaths ./.;
@ -11,6 +86,7 @@
prismlauncher
steam-run
heroic
gamescope-run
# modrinth-app
];
@ -27,4 +103,42 @@
alpha = lib.mkForce 0.75;
};
};
xdg.desktopEntries = {
steam = {
name = "Steam Desktop (Gamescope)";
comment = "Steam in Gamescope Session";
exec = "${steam-session-script} desktop";
icon = "steam";
type = "Application";
terminal = false;
categories = [ "Game" ];
actions = {
desktop = {
name = "Steam Big Picture (Gamescope)";
exec = "${steam-session-script} bigpicture";
};
regular = {
name = "Steam Desktop (No Gamescope)";
exec = "${lib.getExe pkgs.steam}";
};
};
};
"com.heroicgameslauncher.hgl.desktop" = {
name = "Heroic Games Launcher (Gamescope)";
comment = "Heroic in Gamescope Session";
exec = "${lib.getExe gamescope-run} heroic";
icon = "com.heroicgameslauncher.hgl";
type = "Application";
terminal = false;
categories = [ "Game" ];
actions = {
regular = {
name = "Heroic (No Gamescope)";
exec = "${lib.getExe pkgs.heroic}";
};
};
};
};
}

View file

@ -2,10 +2,11 @@
{
imports = lib.custom.scanPaths ./.;
# home.file.".config/monitors_source" = {
# source = ./monitors.xml;
# onChange = ''
# cp $HOME/.config/monitors_source $HOME/.config/monitors.xml
# '';
# };
# home.file.".config/monitors_source" = {
# source = ./monitors.xml;
# onChange = ''
# cp $HOME/.config/monitors_source $HOME/.config/monitors.xml
# chmod 755 $HOME/.config/monitors.xml
# '';
# };
}

View file

@ -30,6 +30,40 @@
};
};
monitors = [
{
name = "DP-2";
primary = true;
width = 3840;
height = 2160;
refreshRate = 60;
x = 0;
y = 0;
scale = 1.0;
transform = 0;
enabled = true;
hdr = true;
vrr = true;
}
{
name = "HDMI-1";
primary = false;
width = 1920;
height = 1080;
refreshRate = 60;
x = 1920; # Positioned to the right of DP-1
y = 0;
scale = 1.0;
transform = 1;
enabled = true;
}
];
## TODO:
## I want to automate this monitors.xml
## But dk how to do it properly yet.
## So for now ill still use this for the gnome config
home.file.".config/monitors_source" = {
source = ./monitors.xml;
onChange = ''

View file

@ -5,69 +5,6 @@
inputs,
...
}:
let
# TODO: Automate when I figure out monitors.nix
WIDTH = 3840;
HEIGHT = 2160;
REFRESH_RATE = 120;
HDR = true;
gamescope-session-script = pkgs.writeShellScript "gamescope-session-script" ''
# Session configuration
export CAP_SYS_NICE="eip"
export DXVK_HDR="1"
export ENABLE_GAMESCOPE_WSI="1"
export ENABLE_HDR_WSI="1"
export AMD_VULKAN_ICD=RADV
export RADV_PERFTEST=aco
export SDL_VIDEODRIVER="wayland"
# Steam environment variables for better compatibility
export STEAM_FORCE_DESKTOPUI_SCALING=1
export STEAM_GAMEPADUI=1
export STEAM_GAMESCOPE_CLIENT=1
# export STEAM_DIRECT_COMPATIBILITY_TOOLS=1
# Default resolution settings - adjust to your display
WIDTH=${toString WIDTH}
HEIGHT=${toString HEIGHT}
REFRESH_RATE=${toString REFRESH_RATE}
# Gamescope options
GAMESCOPE_OPTS="--fade-out-duration 200 -w $WIDTH -h $HEIGHT -r $REFRESH_RATE -f"
GAMESCOPE_OPTS="$GAMESCOPE_OPTS --expose-wayland --backend sdl"
GAMESCOPE_OPTS="$GAMESCOPE_OPTS --rt --adaptive-sync --immediate-flips"
${
if HDR then
''GAMESCOPE_OPTS="$GAMESCOPE_OPTS --hdr-enabled --hdr-debug-force-output --hdr-itm-enable"''
else
""
}
# Launch Steam in Big Picture mode
${lib.getExe pkgs.gamescope} $GAMESCOPE_OPTS --steam -- ${lib.getExe pkgs.steam} -tenfoot -steamdeck -gamepadui
'';
# INFO: Example working commands for running games in steam-session
## Rivals ##
# SteamDeck=1 LD_PRELOAD="" PROTON_ENABLE_NVAPI=1 PROTON_ENABLE_WAYLAND=1 VKD3D_DISABLE_EXTENSIONS=VK_KHR_present_wait gamemoderun %command% -dx12n
## Stats Overlay ##
# gamemoderun mangohud %command%
steam-session = pkgs.writeTextDir "share/applications/steam-session.desktop" ''
[Desktop Entry]
Name=Steam Session
Comment=Launch Steam in Gamescope (nested mode)
Exec=${gamescope-session-script}
Icon=steam
Terminal=false
Type=Application
Categories=Game;
'';
in
{
hardware.graphics = {
@ -80,7 +17,6 @@ in
lact
gamescope
# gamescope-wsi
steam-session
];
systemd = {

View file

@ -34,4 +34,18 @@
to = if builtins.isAttrs smtp then recipient else smtp.user;
in
"mailtos://_?user=${smtpUser}&pass=${smtpPass}&smtp=${smtpHost}&from=${smtpFrom}&to=${to}";
# Get the primary monitor from a list of monitors
# Falls back to first monitor if no primary is set
getPrimaryMonitor =
monitors:
let
primaryMonitors = builtins.filter (m: m.primary or false) monitors;
in
if builtins.length primaryMonitors > 0 then
builtins.head primaryMonitors
else if builtins.length monitors > 0 then
builtins.head monitors
else
null;
}

View file

@ -13,10 +13,6 @@
type = lib.types.bool;
default = false;
};
noBar = lib.mkOption {
type = lib.types.bool;
default = false;
};
width = lib.mkOption {
type = lib.types.int;
example = 1920;
@ -44,22 +40,21 @@
transform = lib.mkOption {
type = lib.types.int;
default = 0;
description = "Screen orientation: 0 = landscape, 1 = portrait left, 2 = portrait right, 3 = landscape flipped";
};
enabled = lib.mkOption {
type = lib.types.bool;
default = true;
};
workspace = lib.mkOption {
type = lib.types.nullOr lib.types.str;
description = "Defines a workspace that should persist on this monitor.";
default = null;
hdr = lib.mkOption {
type = lib.types.bool;
default = false;
};
vrr = lib.mkOption {
type = lib.types.int;
description = "Variable Refresh Rate aka Adaptive Sync aka AMD FreeSync.\nValues are oriented towards hyprland's vrr values which are:\n0 = off, 1 = on, 2 = fullscreen only\nhttps://wiki.hyprland.org/Configuring/Variables/#misc";
default = 0;
type = lib.types.bool;
description = "Variable Refresh Rate aka Adaptive Sync aka AMD FreeSync.";
default = false;
};
};
}
);

View file

@ -90,7 +90,7 @@ Each system in `hosts/nixos/<hostname>/` contains:
| ---------- | ------------- | ---------------------- | --------------------------- | -------------------------------- |
| **rune** | Desktop | My workstation | Ryzen 9 7900X3D, RX 9070 XT | Gaming, Development, VMs |
| **gojo** | Desktop | Giovanni's workstation | Ryzen 7 7800X3D, RX 7900 XT | Gaming, Development |
| **haze** | Desktop | Cesar's workstation | Ryzen 7, RX 6950 XT | Gaming, Development |
| **haze** | Desktop | Cesar's workstation | Ryzen 5 7600x, RX 7600 | Gaming, Development |
| **caenus** | Server | Oracle VPS | ARM 4vCPU, 24GB RAM, 200GB | FRP, Public IP |
| **sock** | Server | Backup & Storage | Intel N150 | Komodo (Docker), Backups, Newt |
| **cloud** | LXC Container | Storage & NFS | 4C/4GB | File storage, NFS, Newt |