diff --git a/gamescope-session-plus/.config/environment.d/gamescope-session-plus.conf b/gamescope-session-plus/.config/environment.d/gamescope-session-plus.conf deleted file mode 100644 index 2426492..0000000 --- a/gamescope-session-plus/.config/environment.d/gamescope-session-plus.conf +++ /dev/null @@ -1,7 +0,0 @@ -# FIXME: "It works on my machine!" Look at ChorinOS/gamescope-session github for more config info - -# Force Output -OUTPUT_CONNECTOR="DP-1" - -# Enable VRR -ADAPTIVE_SYNC=1 diff --git a/hypr/.config/hypr/hyprland.conf b/hypr/.config/hypr/hyprland.conf index b5479fe..d66d013 100644 --- a/hypr/.config/hypr/hyprland.conf +++ b/hypr/.config/hypr/hyprland.conf @@ -47,5 +47,7 @@ env = XDG_MENU_PREFIX, plasma- # ? # env = WLR_NO_HARDWARE_CURSORS, 1 + + # Session Switcher Keybinding bind = SUPER, F12, exec, /home/kenji/.local/bin/switch-session.sh diff --git a/scripts/Hyperland-Steamos/install.sh b/scripts/Hyperland-Steamos/install.sh old mode 100644 new mode 100755 index 5887039..cd64cff --- a/scripts/Hyperland-Steamos/install.sh +++ b/scripts/Hyperland-Steamos/install.sh @@ -1,7 +1,7 @@ #!/bin/bash # # Seamless Hyprland <-> Gamescope Session Switcher for Arch Linux -# Updated: Walker, Infinite Loop, env.d Config, Color Reset, IWD Backend +# Updated: High Priority Scheduling (Fixes Stutter), Walker, Configurable Refresh Rate # set -e @@ -26,11 +26,19 @@ echo -e "${C_BLUE}============================================================== echo -e "${C_BLUE} Hyprland <-> Gamescope Session Switcher Setup for: ${C_YELLOW}$USER_NAME${C_NC}" echo -e "${C_BLUE}===================================================================${C_NC}\n" -# --- USER CHOICE FOR AUTOLOGIN --- +# --- USER INPUTS --- echo -e "${C_YELLOW}Configuration Choice:${C_NC}" echo "Do you want to enable automatic login? [y/N]: " read AUTOLOGIN_CHOICE +echo -e "\n${C_YELLOW}Monitor Configuration:${C_NC}" +echo "Enter your Refresh Rate (e.g., 60, 144, 165). Leave empty for auto:" +read USER_REFRESH +REFRESH_ARG="" +if [ -n "$USER_REFRESH" ]; then + REFRESH_ARG="-r $USER_REFRESH" +fi + # --- Script Variables --- HYPR_CONF="$USER_HOME/.config/hypr/hyprland.conf" SWITCH_SCRIPT_PATH="$USER_HOME/.local/bin/switch-session.sh" @@ -40,7 +48,6 @@ SERVICE_OVERRIDE_FILE="$SERVICE_OVERRIDE_DIR/override.conf" GS_ENV_DIR="$USER_HOME/.config/environment.d" GS_ENV_FILE="$GS_ENV_DIR/gamescope-session-plus.conf" -# UPDATED: Removed wofi, added walker to AUR packages OFFICIAL_PACKAGES=( "hyprland" "sddm" "uwsm" "networkmanager" ) AUR_PACKAGES=( "gamescope-git" "gamescope-session-git" "steam" "gamescope-session-steam-git" "mangohud" "walker" ) @@ -75,30 +82,35 @@ EOF systemctl --user daemon-reload #======================================================= -# STEP 4: CONFIGURE GAMESCOPE ENVIRONMENT (MONITOR FIX) +# STEP 4: CONFIGURE GAMESCOPE ENVIRONMENT #======================================================= echo -e "${C_BLUE}==> Configuring Gamescope Monitor Settings (DP-1)...${C_NC}" echo "Writing to: $GS_ENV_FILE" mkdir -p "$GS_ENV_DIR" +# We inject the Refresh Rate here cat > "$GS_ENV_FILE" < Configuring NetworkManager for SteamOS compatibility...${C_NC}" -# Create config to use iwd backend (prevents conflicts) sudo mkdir -p /etc/NetworkManager/conf.d sudo tee /etc/NetworkManager/conf.d/wifi_backend.conf > /dev/null < Installing Session Switching Workflow...${C_NC}" -# --- SDDM AUTOLOGIN (CONDITIONAL) --- if [[ "$AUTOLOGIN_CHOICE" =~ ^[Yy]$ ]]; then echo "--> Configuring SDDM for autologin..." sudo tee /etc/sddm.conf > /dev/null < /dev/null < Creating Session Launch Script (Infinite Loop)...${C_NC}" +echo -e "${C_BLUE}==> Creating Session Launch Script (Infinite Loop + High Priority)...${C_NC}" cat > "$XSESSION_PATH" <<'EOS' #!/bin/bash @@ -140,13 +150,10 @@ cat > "$XSESSION_PATH" <<'EOS' # Redirect logs for debugging exec > >(tee -a "$HOME/.xsession.log") 2>&1 -# Function to handle Wayland socket waiting wait_for_wayland() { local socket_path="$XDG_RUNTIME_DIR/wayland-1" local max_attempts=60 local attempt=1 - - echo "Waiting for Wayland socket at $socket_path" while [ $attempt -le $max_attempts ]; do if [ -e "$socket_path" ] && [ -S "$socket_path" ]; then return 0 @@ -161,7 +168,6 @@ wait_for_wayland() { while true; do echo "--- New Session Cycle Starting ---" - # 1. READ THE NEXT SESSION if [ -f "$HOME/.next-session" ]; then SESSION=$(cat "$HOME/.next-session") rm -f "$HOME/.next-session" @@ -169,39 +175,50 @@ while true; do SESSION="hyprland" fi - # 2. UPDATE ENVIRONMENT + # Update DBus for systemd dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY - # 3. LAUNCH THE SESSION (WITHOUT EXEC) if [[ "$SESSION" == *"gamescope-session-steam"* ]]; then - echo "Starting Gamescope session..." + echo "Starting Gamescope session (High Priority)..." - # Check for the executable + # Load environment config manually + if [ -f "$HOME/.config/environment.d/gamescope-session-plus.conf" ]; then + set -a + source "$HOME/.config/environment.d/gamescope-session-plus.conf" + set +a + fi + if command -v gamescope-session-plus &> /dev/null; then - # Run blocking, do not exec - export GAMESCOPECMD="/usr/bin/gamescope -O DP-1 --steam -e --" - gamescope-session-plus steam + + # EXPORT VARIABLES + export GAMESCOPECMD="/usr/bin/gamescope ${GAMESCOPE_ARGS:-"-O DP-1 --steam -e"}" + export OUTPUT_CONNECTOR="${OUTPUT_CONNECTOR:-"DP-1"}" + + # --- STUTTER FIX: SYSTEMD-RUN --- + # We wrap the command in systemd-run to give it Real-Time Priority + # This mimics how a real Service would run it, eliminating scheduling latency. + systemd-run --user --scope \ + --property=Nice=-20 \ + --property=Slice=app.slice \ + --unit=gamescope-session-manual \ + gamescope-session-plus steam -- -O DP-1 + unset GAMESCOPECMD + unset OUTPUT_CONNECTOR else echo "Error: gamescope-session-plus not found, falling back to Hyprland" SESSION="hyprland" fi fi - # Note: We use a separate 'if' here to catch the fallback above if [[ "$SESSION" != *"gamescope-session-steam"* ]]; then echo "Starting Hyprland session with UWSM..." - - # Run blocking, do not exec uwsm start hyprland-uwsm.desktop fi echo "Session exited. Looping..." - - # 4. CRASH PROTECTION sleep 2 done - EOS chmod +x "$XSESSION_PATH" @@ -212,34 +229,25 @@ echo -e "${C_BLUE}==> Creating Session Switching Helper...${C_NC}" mkdir -p "$(dirname "$SWITCH_SCRIPT_PATH")" cat > "$SWITCH_SCRIPT_PATH" <<'EOSWITCH' - #!/bin/bash export WAYLAND_DISPLAY="${WAYLAND_DISPLAY:-wayland-1}" export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" -choice=$(printf "🎮 SteamOS" | walker --dmenu \ - --placeholder "Switch Mode:" \ - # --width 400 \ - # --height 250 \ - # --cache-file /dev/null \ - # --style "$HOME/.config/wofi/style.css" \ - # --hide-scroll \ - # --no-actions \ - # --lines 2) - ) +# Walker in dmenu mode +choice=$(printf "🎮 SteamOS" | walker --dmenu --placeholder "Switch Mode") case "$choice" in "🎮 SteamOS") - # Validate we can write the session file + notify-send "Session Switcher" "Disabling Night Light..." -t 1000 + pkill hyprsunset + pkill wlsunset + pkill gammastep + sleep 1 if echo "gamescope-session-steam.desktop" > "$HOME/.next-session" 2>/dev/null; then notify-send "Session Switcher" "Switching to SteamOS..." -t 2000 - echo "Session file written successfully" - pkill hyprsunset - sleep 1 else notify-send "Session Switcher" "Error: Failed to write session file" -t 3000 - echo "Error: Cannot write to $HOME/.next-session" exit 1 fi ;; @@ -249,75 +257,40 @@ case "$choice" in ;; esac - -# Improved session cleanup with better reliability cleanup_session() { local max_wait=5 local wait_count=0 - # Detect current session more reliably if pgrep -x "gamescope" > /dev/null || pgrep -f "gamescope-session" > /dev/null; then echo "Detected Gamescope session, shutting down..." - - # Try graceful shutdown first systemctl --user stop gamescope-session-plus@steam 2>/dev/null || true sleep 1 - - # Force kill if still running if pgrep -x "gamescope" > /dev/null; then pkill -TERM gamescope sleep 0.5 pkill -KILL gamescope 2>/dev/null || true fi - - # Wait for processes to fully exit - while pgrep -x "gamescope" > /dev/null && [ $wait_count -lt $max_wait ]; do - sleep 1 - ((wait_count++)) - done - elif [ -n "$HYPRLAND_INSTANCE_SIGNATURE" ] || pgrep -x "Hyprland" > /dev/null; then echo "Detected Hyprland session, shutting down..." - - # Try hyprctl first if available if command -v hyprctl &> /dev/null && [ -n "$HYPRLAND_INSTANCE_SIGNATURE" ]; then hyprctl dispatch exit 2>/dev/null || true else - # Fallback to pkill pkill -TERM Hyprland 2>/dev/null || true fi - sleep 1 - - # Force kill if still running if pgrep -x "Hyprland" > /dev/null; then pkill -KILL Hyprland 2>/dev/null || true fi - - # Wait for processes to fully exit - while pgrep -x "Hyprland" > /dev/null && [ $wait_count -lt $max_wait ]; do - sleep 1 - ((wait_count++)) - done - else - echo "No specific session detected, attempting general cleanup..." - # Fallback cleanup pkill -u $USER Hyprland 2>/dev/null || true pkill -u $USER gamescope 2>/dev/null || true systemctl --user stop gamescope-session-plus@steam 2>/dev/null || true sleep 1 fi - - # Clean up any remaining compositor processes pkill -u $USER -f "gamescope-session" 2>/dev/null || true pkill -u $USER -f "steam" 2>/dev/null || true - - # Give time for cleanup sleep 0.5 } - -# Execute cleanup cleanup_session EOSWITCH chmod +x "$SWITCH_SCRIPT_PATH" @@ -326,14 +299,8 @@ chmod +x "$SWITCH_SCRIPT_PATH" # STEP 9: CONFIGURE HYPRLAND KEYBINDING #======================================================= echo -e "${C_BLUE}==> Configuring Hyprland Keybinding...${C_NC}" - -# Create hyprland config directory if it doesn't exist mkdir -p "$(dirname "$HYPR_CONF")" - -if [ ! -f "$HYPR_CONF" ]; then - echo "# Hyprland Configuration" > "$HYPR_CONF" - echo "" >> "$HYPR_CONF" -fi +if [ ! -f "$HYPR_CONF" ]; then echo "" > "$HYPR_CONF"; fi sed -i '/# Session Switcher Keybinding/d' "$HYPR_CONF" sed -i '/bind = SUPER, F12, exec,.*switch-session.sh/d' "$HYPR_CONF" @@ -346,23 +313,12 @@ EOF echo -e "${C_GREEN}Added SUPER+F12 keybinding to $HYPR_CONF${C_NC}" - #======================================================= # FINALIZATION #======================================================= echo -e "${C_GREEN}✅ Setup Complete! ✅${C_NC}\n" - -echo -e "${C_YELLOW}Important Fixes Applied:${C_NC}" -echo "1. REPLACED 'wofi' with 'walker'." -echo "2. CONFIGURED NetworkManager to use 'iwd' backend." -echo "3. UPDATED '.xsession' to use an infinite loop (prevents logout)." -echo "4. CREATED '~/.config/environment.d/gamescope-session-plus.conf' to force DP-1." -echo "5. MODIFIED Switch script to kill 'hyprsunset' before switching." - -echo -e "\n${C_YELLOW}A REBOOT IS REQUIRED to activate NetworkManager and the new Session structure.${C_NC}\n" - -if [ "$AUTOLOGIN_ENABLED" = true ]; then - echo -e "-> Autologin is enabled. System will boot directly into Hyprland." -else - echo -e "-> Autologin is disabled. Choose 'Auto Session Switcher' at login." -fi +echo -e "${C_YELLOW}Stutter Fixes Applied:${C_NC}" +echo "1. Wrapped gamescope in 'systemd-run' with Nice=-20 (Real-time Priority)." +echo "2. Configured Monitor Refresh Rate." +echo "3. Switched to 'Walker' for menu selection." +echo -e "\n${C_YELLOW}A REBOOT IS REQUIRED.${C_NC}\n"