v0.1.2 — TUI hardening, hybrid PRIME offload, installer cleanup
Settings TUI (bin/deckshift-settings): - Don't crash when the saved OUTPUT_CONNECTOR is no longer plugged in (stale connector → empty mode list → grep + pipefail killed the script) - Add [hybrid-nvidia] GPU mode for NVIDIA dGPU + AMD/Intel iGPU laptops: sets __NV_PRIME_RENDER_OFFLOAD / __VK_LAYER_NV_optimus / __GLX_VENDOR_LIBRARY_NAME so games inside gamescope render on NVIDIA while gamescope itself runs on the iGPU (necessary on hybrid laptops where eDP is wired to the iGPU) - Add [hybrid-amd] GPU mode for AMD dGPU + AMD/Intel iGPU laptops: sub-menu to pick the dGPU, then sets DRI_PRIME + MESA_VK_DEVICE_SELECT - Single GPU-mode line in the status panel covering all five states (auto / NVIDIA direct / AMD direct / hybrid-nvidia / hybrid-amd) - Switch GPU selection to clear-then-set so mode-switching never leaves stale flags behind Installer (deckshift.sh): - Drop monitor / resolution / refresh selection from the installer entirely; display keys are owned by the TUI now. Avoids stale OUTPUT_CONNECTOR values when the configured display is later unplugged - Switch gamescope-session-plus.conf writer from heredoc-overwrite to per-key set/unset (sed-based, mirrors flush_pending in the TUI) so the installer is idempotent and re-runs preserve user-set display values - Strip stale opposite-GPU keys when re-running on a changed GPU (e.g. NVIDIA → AMD swap clears VULKAN_ADAPTER / GBM_BACKEND) - Fix switch-to-desktop: replace racy `stop sddm` + disowned `start sddm` with a single atomic `systemctl restart sddm`. The disowned start was getting killed by user-session teardown before SDDM came back up, leaving the user on a black screen after Super+Shift+R
This commit is contained in:
parent
43af0b3344
commit
f2de4a3744
2 changed files with 188 additions and 162 deletions
|
|
@ -145,6 +145,13 @@ refresh_monitor_data() {
|
|||
fi
|
||||
HYPR_MODES=$(hyprctl monitors all -j 2>/dev/null \
|
||||
| jq -r --arg n "$target" '.[] | select(.name==$n) | .availableModes[]?')
|
||||
# Configured connector might not currently be plugged in (e.g. external
|
||||
# display unplugged). Bail out cleanly so the rest of the function doesn't
|
||||
# run grep against empty input and trip pipefail under set -e.
|
||||
if [[ -z "$HYPR_MODES" ]]; then
|
||||
HYPR_NATIVE=""; HYPR_MAX_REFRESH=""
|
||||
return
|
||||
fi
|
||||
HYPR_NATIVE=$(echo "$HYPR_MODES" | head -1 | sed 's/@.*//')
|
||||
# Max refresh AT NATIVE resolution, rounded to integer Hz for display.
|
||||
# (Reporting the max across all modes would mislead — e.g. a 4K@60 panel
|
||||
|
|
@ -213,13 +220,30 @@ list_gpus() {
|
|||
# ------------------------------------------------------------------------------
|
||||
|
||||
show_state() {
|
||||
local connector width height refresh vk_adapter dri_prime
|
||||
local connector width height refresh vk_adapter dri_prime prime_offload mesa_vk_select
|
||||
connector=$(effective OUTPUT_CONNECTOR)
|
||||
width=$(effective SCREEN_WIDTH)
|
||||
height=$(effective SCREEN_HEIGHT)
|
||||
refresh=$(effective CUSTOM_REFRESH_RATES)
|
||||
vk_adapter=$(effective VULKAN_ADAPTER)
|
||||
dri_prime=$(effective DRI_PRIME)
|
||||
prime_offload=$(effective __NV_PRIME_RENDER_OFFLOAD)
|
||||
mesa_vk_select=$(effective MESA_VK_DEVICE_SELECT)
|
||||
|
||||
# Single GPU-mode line — shows the active mode rather than half-empty rows,
|
||||
# since the modes are mutually exclusive. AMD hybrid is identified by both
|
||||
# DRI_PRIME and MESA_VK_DEVICE_SELECT being set (the TUI sets both together);
|
||||
# plain DRI_PRIME without MESA_VK_DEVICE_SELECT is "AMD/Intel direct".
|
||||
local gpu_mode="<auto>"
|
||||
if [[ -n "$prime_offload" ]]; then
|
||||
gpu_mode="Hybrid PRIME offload (NVIDIA via iGPU)"
|
||||
elif [[ -n "$dri_prime" && -n "$mesa_vk_select" ]]; then
|
||||
gpu_mode="Hybrid PRIME offload (AMD via iGPU → ${mesa_vk_select})"
|
||||
elif [[ -n "$vk_adapter" ]]; then
|
||||
gpu_mode="NVIDIA direct (${vk_adapter})"
|
||||
elif [[ -n "$dri_prime" ]]; then
|
||||
gpu_mode="AMD/Intel direct (${dri_prime})"
|
||||
fi
|
||||
|
||||
local pending_label=""
|
||||
has_pending_changes && pending_label=" $(gum style --foreground 214 '(unsaved changes)')"
|
||||
|
|
@ -235,8 +259,7 @@ Gaming Mode display settings${pending_label}:
|
|||
Monitor : ${monitor_label}
|
||||
Resolution : ${width:-?}x${height:-?}
|
||||
Refresh rate : ${refresh:-<auto>} Hz
|
||||
GPU (NVIDIA) : ${vk_adapter:-<not set>}
|
||||
GPU (AMD) : ${dri_prime:-<not set>}
|
||||
GPU mode : ${gpu_mode}
|
||||
|
||||
Config file : ${CONF}
|
||||
EOF
|
||||
|
|
@ -365,6 +388,23 @@ choose_refresh_rate() {
|
|||
pending_set CUSTOM_REFRESH_RATES "$rate"
|
||||
}
|
||||
|
||||
# Keys this menu owns. Cleared at the start of every selection so switching
|
||||
# between modes never leaves stale flags behind.
|
||||
GPU_MODE_KEYS=(
|
||||
VULKAN_ADAPTER GBM_BACKEND DRI_PRIME
|
||||
__NV_PRIME_RENDER_OFFLOAD __VK_LAYER_NV_optimus __GLX_VENDOR_LIBRARY_NAME
|
||||
MESA_VK_DEVICE_SELECT MESA_VK_DEVICE_SELECT_FORCE_DEFAULT_DEVICE
|
||||
)
|
||||
|
||||
# Convert a PCI slot like "01:00.0" or "0000:c3:00.0" to the DRI_PRIME tag
|
||||
# format ("pci-0000_01_00_0"). Used by AMD/Intel paths.
|
||||
_pci_slot_to_dri_tag() {
|
||||
local slot="$1"
|
||||
local tag="pci-$(echo "$slot" | sed 's/[:.]/_/g')"
|
||||
[[ "$tag" != pci-0000* ]] && tag="pci-0000_${tag#pci-}"
|
||||
echo "$tag"
|
||||
}
|
||||
|
||||
choose_gpu() {
|
||||
local choice
|
||||
mapfile -t gpus < <(list_gpus)
|
||||
|
|
@ -372,41 +412,105 @@ choose_gpu() {
|
|||
gum style --foreground 196 "No GPUs detected via lspci"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Hybrid detection. Two patterns:
|
||||
# - hybrid-nvidia: NVIDIA dGPU + (AMD or Intel) iGPU. eDP usually on iGPU.
|
||||
# Games offload to NVIDIA via __NV_PRIME_RENDER_OFFLOAD env vars.
|
||||
# - hybrid-amd: 2+ non-NVIDIA GPUs (AMD+AMD or AMD+Intel). User picks which
|
||||
# is the dGPU; games offload via DRI_PRIME + MESA_VK_DEVICE_SELECT.
|
||||
local has_nvidia=false has_igpu=false
|
||||
local non_nvidia_count=0
|
||||
local entry slot vendor_dev kind label
|
||||
for entry in "${gpus[@]}"; do
|
||||
IFS='|' read -r slot vendor_dev kind label <<<"$entry"
|
||||
case "$kind" in
|
||||
nvidia) has_nvidia=true ;;
|
||||
amd|intel|other)
|
||||
has_igpu=true
|
||||
non_nvidia_count=$((non_nvidia_count + 1))
|
||||
;;
|
||||
esac
|
||||
done
|
||||
local hybrid_nvidia_available=false hybrid_amd_available=false
|
||||
$has_nvidia && $has_igpu && hybrid_nvidia_available=true
|
||||
(( non_nvidia_count >= 2 )) && hybrid_amd_available=true
|
||||
|
||||
local -a labels=()
|
||||
$hybrid_nvidia_available && labels+=("[hybrid-nvidia] NVIDIA render-offload via iGPU — for hybrid laptops (eDP on iGPU)")
|
||||
$hybrid_amd_available && labels+=("[hybrid-amd] AMD/Intel render-offload — pick which GPU to offload games to")
|
||||
for entry in "${gpus[@]}"; do
|
||||
IFS='|' read -r slot vendor_dev kind label <<<"$entry"
|
||||
labels+=("[$kind] $label ($vendor_dev @ $slot)")
|
||||
done
|
||||
labels+=("(clear GPU override — let system decide)")
|
||||
|
||||
choice=$(printf '%s\n' "${labels[@]}" | gchoose --header "Select GPU for Gaming Mode")
|
||||
[[ -z "$choice" ]] && return 0
|
||||
if [[ "$choice" == "(clear"* ]]; then
|
||||
pending_unset VULKAN_ADAPTER
|
||||
pending_unset DRI_PRIME
|
||||
pending_unset GBM_BACKEND
|
||||
|
||||
# Wipe every GPU-mode key first; each branch sets only what it needs.
|
||||
local k
|
||||
for k in "${GPU_MODE_KEYS[@]}"; do pending_unset "$k"; done
|
||||
|
||||
case "$choice" in
|
||||
"[hybrid-nvidia]"*)
|
||||
pending_set __NV_PRIME_RENDER_OFFLOAD 1
|
||||
pending_set __VK_LAYER_NV_optimus NVIDIA_only
|
||||
pending_set __GLX_VENDOR_LIBRARY_NAME nvidia
|
||||
return 0
|
||||
fi
|
||||
local idx=0 selected=""
|
||||
for label in "${labels[@]}"; do
|
||||
if [[ "$label" == "$choice" ]]; then
|
||||
selected="${gpus[$idx]}"
|
||||
;;
|
||||
"[hybrid-amd]"*)
|
||||
# Sub-menu — pick which AMD/Intel GPU is the render target (dGPU).
|
||||
local -a t_labels=() t_entries=()
|
||||
for entry in "${gpus[@]}"; do
|
||||
IFS='|' read -r slot vendor_dev kind label <<<"$entry"
|
||||
case "$kind" in
|
||||
amd|intel|other)
|
||||
t_labels+=("[$kind] $label ($vendor_dev @ $slot)")
|
||||
t_entries+=("$entry")
|
||||
;;
|
||||
esac
|
||||
done
|
||||
local t_choice t_entry=""
|
||||
t_choice=$(printf '%s\n' "${t_labels[@]}" | gchoose --header "Pick dGPU (render target) — usually the discrete one")
|
||||
[[ -z "$t_choice" ]] && return 0
|
||||
local i
|
||||
for ((i=0; i<${#t_labels[@]}; i++)); do
|
||||
if [[ "${t_labels[$i]}" == "$t_choice" ]]; then
|
||||
t_entry="${t_entries[$i]}"
|
||||
break
|
||||
fi
|
||||
idx=$((idx + 1))
|
||||
done
|
||||
[[ -z "$t_entry" ]] && return 0
|
||||
IFS='|' read -r slot vendor_dev kind label <<<"$t_entry"
|
||||
pending_set DRI_PRIME "$(_pci_slot_to_dri_tag "$slot")"
|
||||
pending_set MESA_VK_DEVICE_SELECT "$vendor_dev"
|
||||
pending_set MESA_VK_DEVICE_SELECT_FORCE_DEFAULT_DEVICE 1
|
||||
return 0
|
||||
;;
|
||||
"(clear"*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Direct GPU selection — match the chosen label back to its gpus[] entry.
|
||||
local selected=""
|
||||
for entry in "${gpus[@]}"; do
|
||||
IFS='|' read -r slot vendor_dev kind label <<<"$entry"
|
||||
if [[ "[$kind] $label ($vendor_dev @ $slot)" == "$choice" ]]; then
|
||||
selected="$entry"
|
||||
break
|
||||
fi
|
||||
done
|
||||
[[ -z "$selected" ]] && return 0
|
||||
|
||||
IFS='|' read -r slot vendor_dev kind label <<<"$selected"
|
||||
case "$kind" in
|
||||
nvidia)
|
||||
pending_set VULKAN_ADAPTER "$vendor_dev"
|
||||
pending_set GBM_BACKEND "nvidia-drm"
|
||||
pending_unset DRI_PRIME
|
||||
pending_set GBM_BACKEND nvidia-drm
|
||||
;;
|
||||
amd|intel|other)
|
||||
local dri_tag="pci-$(echo "$slot" | sed 's/[:.]/_/g')"
|
||||
[[ "$dri_tag" != pci-0000* ]] && dri_tag="pci-0000_${dri_tag#pci-}"
|
||||
pending_set DRI_PRIME "$dri_tag"
|
||||
pending_unset VULKAN_ADAPTER
|
||||
pending_unset GBM_BACKEND
|
||||
pending_set DRI_PRIME "$(_pci_slot_to_dri_tag "$slot")"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
|
|
|||
204
deckshift.sh
204
deckshift.sh
|
|
@ -1349,11 +1349,10 @@ setup_session_switching() {
|
|||
local user_home
|
||||
user_home=$(eval echo "~$current_user")
|
||||
|
||||
local monitor_width=1920
|
||||
local monitor_height=1080
|
||||
local monitor_refresh=60
|
||||
local monitor_output=""
|
||||
|
||||
# GPU detection only — the installer no longer chooses a monitor, resolution
|
||||
# or refresh rate. Those are user choices, made later via Walker → "DeckShift
|
||||
# Settings". This avoids stale OUTPUT_CONNECTOR values when displays are
|
||||
# unplugged and lets the user pick whatever fits their setup.
|
||||
local -a dgpu_monitors=()
|
||||
local dgpu_card=""
|
||||
local dgpu_type=""
|
||||
|
|
@ -1370,10 +1369,9 @@ setup_session_switching() {
|
|||
NEEDS_REBOOT=1
|
||||
return 1
|
||||
fi
|
||||
# No dGPU - check for APU
|
||||
# No dGPU - check for AMD APU as a viable Gaming Mode GPU
|
||||
local apu_card=""
|
||||
local apu_monitors=()
|
||||
local card_name driver_link driver conn_dir conn_name status resolution mode_file
|
||||
local card_name driver_link driver
|
||||
|
||||
for card_path in /sys/class/drm/card[0-9]*; do
|
||||
card_name=$(basename "$card_path")
|
||||
|
|
@ -1384,39 +1382,19 @@ setup_session_switching() {
|
|||
|
||||
if [[ "$driver" == "amdgpu" ]] && is_amd_igpu_card "$card_path"; then
|
||||
apu_card="$card_name"
|
||||
# Find monitors connected to APU
|
||||
for connector in "$card_path"/"$card_name"-*/status; do
|
||||
[[ -f "$connector" ]] || continue
|
||||
conn_dir=$(dirname "$connector")
|
||||
conn_name=$(basename "$conn_dir")
|
||||
conn_name=${conn_name#card*-}
|
||||
[[ "$conn_name" == Writeback* ]] && continue
|
||||
status=$(cat "$connector" 2>/dev/null)
|
||||
if [[ "$status" == "connected" ]]; then
|
||||
resolution=""
|
||||
mode_file="$conn_dir/modes"
|
||||
[[ -f "$mode_file" ]] && [[ -s "$mode_file" ]] && resolution=$(head -1 "$mode_file" 2>/dev/null)
|
||||
apu_monitors+=("$conn_name|$resolution")
|
||||
fi
|
||||
done
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -n "$apu_card" && ${#apu_monitors[@]} -gt 0 ]]; then
|
||||
if [[ -n "$apu_card" ]]; then
|
||||
echo ""
|
||||
info "No discrete GPU found, but detected AMD APU ($apu_card)"
|
||||
echo ""
|
||||
echo " This system has an AMD APU which can run Gaming Mode."
|
||||
echo " Detected monitors: ${#apu_monitors[@]}"
|
||||
echo ""
|
||||
read -p " Set up Gaming Mode for APU? [Y/n]: " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||||
# Use APU as the gaming GPU
|
||||
dgpu_card="$apu_card"
|
||||
dgpu_type="AMD APU"
|
||||
dgpu_monitors=("${apu_monitors[@]}")
|
||||
info "Configuring Gaming Mode for AMD APU"
|
||||
else
|
||||
info "Skipping APU Gaming Mode setup"
|
||||
|
|
@ -1424,60 +1402,14 @@ setup_session_switching() {
|
|||
fi
|
||||
else
|
||||
err "No discrete GPU (dGPU) or AMD APU found!"
|
||||
echo " Gaming mode requires a supported GPU with a connected display."
|
||||
echo " Gaming mode requires a supported GPU."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
info "Found $dgpu_type on $dgpu_card"
|
||||
|
||||
if [[ ${#dgpu_monitors[@]} -eq 0 ]]; then
|
||||
err "No monitors connected to dGPU!"
|
||||
echo ""
|
||||
echo " Gaming mode requires a monitor connected to the discrete GPU."
|
||||
echo " Please connect an external monitor to your dGPU port (HDMI/DP/USB-C)"
|
||||
echo " and re-run this installer."
|
||||
echo ""
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ${#dgpu_monitors[@]} -eq 1 ]]; then
|
||||
local entry="${dgpu_monitors[0]}"
|
||||
monitor_output="${entry%%|*}"
|
||||
local res="${entry##*|}"
|
||||
if [[ -n "$res" ]]; then
|
||||
monitor_width="${res%%x*}"
|
||||
monitor_height="${res##*x}"
|
||||
monitor_height="${monitor_height%%@*}"
|
||||
[[ "$res" == *@* ]] && monitor_refresh="${res##*@}" && monitor_refresh="${monitor_refresh%%.*}"
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo " Multiple monitors connected to $dgpu_type:"
|
||||
local i=1
|
||||
for entry in "${dgpu_monitors[@]}"; do
|
||||
local name="${entry%%|*}"
|
||||
local res="${entry##*|}"
|
||||
echo " $i) $name ${res:+($res)}"
|
||||
((i++))
|
||||
done
|
||||
echo ""
|
||||
read -p "Select monitor for Gaming Mode [1-${#dgpu_monitors[@]}]: " selection
|
||||
if [[ ! "$selection" =~ ^[0-9]+$ ]] || ((selection < 1 || selection > ${#dgpu_monitors[@]})); then
|
||||
selection=1
|
||||
fi
|
||||
local entry="${dgpu_monitors[$((selection-1))]}"
|
||||
monitor_output="${entry%%|*}"
|
||||
local res="${entry##*|}"
|
||||
if [[ -n "$res" ]]; then
|
||||
monitor_width="${res%%x*}"
|
||||
monitor_height="${res##*x}"
|
||||
monitor_height="${monitor_height%%@*}"
|
||||
[[ "$res" == *@* ]] && monitor_refresh="${res##*@}" && monitor_refresh="${monitor_refresh%%.*}"
|
||||
fi
|
||||
fi
|
||||
|
||||
info "Selected dGPU display: ${monitor_output} (${monitor_width}x${monitor_height}@${monitor_refresh}Hz)"
|
||||
info "Display selection (monitor / resolution / refresh) is left to the user."
|
||||
info "After install, launch Walker → 'DeckShift Settings' to configure."
|
||||
|
||||
info "Checking for old custom session files to clean up..."
|
||||
|
||||
|
|
@ -1923,83 +1855,72 @@ UDISKS_POLKIT
|
|||
|
||||
# Gamescope Session Configuration
|
||||
#
|
||||
# This config file tells gamescope-session-plus (from ChimeraOS) how to
|
||||
# set up the gaming display. It includes:
|
||||
# - Resolution and refresh rate (auto-detected from your monitor)
|
||||
# - Which display output to use (e.g. HDMI-1, DP-2)
|
||||
# - GPU-specific settings (NVIDIA vs AMD have different requirements)
|
||||
# The installer writes only GPU-specific and static keys here. Display keys
|
||||
# (SCREEN_WIDTH, SCREEN_HEIGHT, CUSTOM_REFRESH_RATES, OUTPUT_CONNECTOR) are
|
||||
# NOT written by the installer — they are owned by the user and managed via
|
||||
# the settings TUI (Walker → "DeckShift Settings"). This keeps existing user
|
||||
# selections intact across re-runs and avoids preselecting values that may
|
||||
# not match the user's setup.
|
||||
#
|
||||
# NVIDIA gets: GBM_BACKEND=nvidia-drm, VULKAN_ADAPTER pointing to the GPU
|
||||
# AMD gets: ADAPTIVE_SYNC=1 (FreeSync), ENABLE_GAMESCOPE_HDR=1 (HDR support)
|
||||
#
|
||||
# NVIDIA is capped at 2560x1440 due to Gamescope limitations with NVIDIA GPUs.
|
||||
info "Creating gamescope-session-plus configuration..."
|
||||
# NVIDIA gets: VULKAN_ADAPTER + GBM_BACKEND=nvidia-drm
|
||||
# AMD gets: ADAPTIVE_SYNC=1 + ENABLE_GAMESCOPE_HDR=1
|
||||
# Intel: no extra display flags (adaptive sync / HDR unreliable on Intel)
|
||||
info "Updating gamescope-session-plus configuration..."
|
||||
local env_dir="${user_home}/.config/environment.d"
|
||||
local gamescope_conf="${env_dir}/gamescope-session-plus.conf"
|
||||
|
||||
mkdir -p "$env_dir"
|
||||
touch "$gamescope_conf"
|
||||
|
||||
local output_connector=""
|
||||
[[ -n "$monitor_output" ]] && output_connector="OUTPUT_CONNECTOR=$monitor_output"
|
||||
# Per-key updater — replaces in place if present, appends if missing.
|
||||
# Same shape as the TUI's flush_pending so the two never fight.
|
||||
set_conf_key() {
|
||||
local key="$1" value="$2"
|
||||
if grep -qE "^${key}=" "$gamescope_conf"; then
|
||||
sed -i "s|^${key}=.*|${key}=${value}|" "$gamescope_conf"
|
||||
else
|
||||
echo "${key}=${value}" >> "$gamescope_conf"
|
||||
fi
|
||||
}
|
||||
unset_conf_key() {
|
||||
sed -i "/^$1=/d" "$gamescope_conf"
|
||||
}
|
||||
|
||||
local nvidia_device_id=""
|
||||
if [[ "$dgpu_type" == "NVIDIA" ]]; then
|
||||
nvidia_device_id=$(/usr/bin/lspci -nn | grep -i nvidia | grep -oP '\[10de:\K[0-9a-fA-F]+' | head -1)
|
||||
if [ "$monitor_width" -gt 2560 ]; then
|
||||
monitor_width=2560
|
||||
fi
|
||||
if [ "$monitor_height" -gt 1440 ]; then
|
||||
monitor_height=1440
|
||||
fi
|
||||
fi
|
||||
# Static keys — apply on every install, every GPU.
|
||||
set_conf_key STEAM_ALLOW_DRIVE_UNMOUNT 1
|
||||
set_conf_key FCITX_NO_WAYLAND_DIAGNOSE 1
|
||||
set_conf_key SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS 0
|
||||
|
||||
# GPU-specific keys — set the right ones, clear stale ones from a prior
|
||||
# install on a different GPU (e.g. user swapped NVIDIA → AMD).
|
||||
case "$dgpu_type" in
|
||||
"NVIDIA")
|
||||
local vulkan_adapter=""
|
||||
[[ -n "$nvidia_device_id" ]] && vulkan_adapter="VULKAN_ADAPTER=10de:${nvidia_device_id}"
|
||||
cat > "$gamescope_conf" << GAMESCOPE_CONF
|
||||
SCREEN_WIDTH=${monitor_width}
|
||||
SCREEN_HEIGHT=${monitor_height}
|
||||
CUSTOM_REFRESH_RATES=${monitor_refresh}
|
||||
${output_connector}
|
||||
${vulkan_adapter}
|
||||
GBM_BACKEND=nvidia-drm
|
||||
STEAM_ALLOW_DRIVE_UNMOUNT=1
|
||||
FCITX_NO_WAYLAND_DIAGNOSE=1
|
||||
SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS=0
|
||||
GAMESCOPE_CONF
|
||||
local nvidia_device_id
|
||||
nvidia_device_id=$(/usr/bin/lspci -nn | grep -i nvidia | grep -oP '\[10de:\K[0-9a-fA-F]+' | head -1)
|
||||
[[ -n "$nvidia_device_id" ]] && set_conf_key VULKAN_ADAPTER "10de:${nvidia_device_id}"
|
||||
set_conf_key GBM_BACKEND nvidia-drm
|
||||
unset_conf_key ADAPTIVE_SYNC
|
||||
unset_conf_key ENABLE_GAMESCOPE_HDR
|
||||
unset_conf_key DRI_PRIME
|
||||
;;
|
||||
"Intel")
|
||||
# Intel doesn't get ADAPTIVE_SYNC / HDR by default — most Intel iGPUs
|
||||
# don't support adaptive sync, and gamescope HDR on Intel is unreliable.
|
||||
# Users with Intel Arc + a VRR display can enable both via the settings TUI.
|
||||
cat > "$gamescope_conf" << GAMESCOPE_CONF
|
||||
SCREEN_WIDTH=${monitor_width}
|
||||
SCREEN_HEIGHT=${monitor_height}
|
||||
CUSTOM_REFRESH_RATES=${monitor_refresh}
|
||||
${output_connector}
|
||||
STEAM_ALLOW_DRIVE_UNMOUNT=1
|
||||
FCITX_NO_WAYLAND_DIAGNOSE=1
|
||||
SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS=0
|
||||
GAMESCOPE_CONF
|
||||
unset_conf_key VULKAN_ADAPTER
|
||||
unset_conf_key GBM_BACKEND
|
||||
unset_conf_key ADAPTIVE_SYNC
|
||||
unset_conf_key ENABLE_GAMESCOPE_HDR
|
||||
;;
|
||||
*)
|
||||
# AMD dGPU and AMD APU — adaptive sync (FreeSync) and HDR are well supported.
|
||||
cat > "$gamescope_conf" << GAMESCOPE_CONF
|
||||
SCREEN_WIDTH=${monitor_width}
|
||||
SCREEN_HEIGHT=${monitor_height}
|
||||
CUSTOM_REFRESH_RATES=${monitor_refresh}
|
||||
${output_connector}
|
||||
ADAPTIVE_SYNC=1
|
||||
ENABLE_GAMESCOPE_HDR=1
|
||||
STEAM_ALLOW_DRIVE_UNMOUNT=1
|
||||
FCITX_NO_WAYLAND_DIAGNOSE=1
|
||||
SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS=0
|
||||
GAMESCOPE_CONF
|
||||
set_conf_key ADAPTIVE_SYNC 1
|
||||
set_conf_key ENABLE_GAMESCOPE_HDR 1
|
||||
unset_conf_key VULKAN_ADAPTER
|
||||
unset_conf_key GBM_BACKEND
|
||||
;;
|
||||
esac
|
||||
|
||||
info "Created $gamescope_conf"
|
||||
unset -f set_conf_key unset_conf_key
|
||||
|
||||
info "Updated $gamescope_conf (display keys left for the TUI)"
|
||||
|
||||
# NVIDIA Gamescope Wrapper
|
||||
#
|
||||
|
|
@ -2319,10 +2240,11 @@ sleep 2
|
|||
|
||||
sudo -n chvt 2 2>/dev/null || true
|
||||
sleep 0.5
|
||||
sudo -n systemctl stop sddm 2>/dev/null || true
|
||||
sleep 1
|
||||
sudo -n systemctl start sddm &
|
||||
disown
|
||||
# Atomic restart — stop+start (with stop and start as separate sudo calls)
|
||||
# was unreliable: stop/start aren't NOPASSWD-allowed individually (only
|
||||
# `restart` is), and the disowned `start` could be killed by session teardown
|
||||
# before SDDM actually came back up, leaving the user on a black screen.
|
||||
sudo -n systemctl restart sddm
|
||||
exit 0
|
||||
SWITCH_DESKTOP
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue