diff --git a/install/user/all.sh b/install/user/all.sh index c9057284..1da564d4 100644 --- a/install/user/all.sh +++ b/install/user/all.sh @@ -7,6 +7,7 @@ run_logged "$OMARCHY_INSTALL/user/hardware/asus/fix-audio-mixer.sh" run_logged "$OMARCHY_INSTALL/user/hardware/asus/fix-mic.sh" run_logged "$OMARCHY_INSTALL/user/hardware/framework/fix-f13-amd-audio-input.sh" run_logged "$OMARCHY_INSTALL/user/hardware/dell/xps13-text-scaling.sh" +run_logged "$OMARCHY_INSTALL/user/hardware/fix-nouveau-cursor.sh" run_logged "$OMARCHY_INSTALL/user/default-keyring.sh" run_logged "$OMARCHY_INSTALL/user/mise.sh" diff --git a/install/user/hardware/fix-nouveau-cursor.sh b/install/user/hardware/fix-nouveau-cursor.sh new file mode 100644 index 00000000..3b819432 --- /dev/null +++ b/install/user/hardware/fix-nouveau-cursor.sh @@ -0,0 +1,28 @@ +# Disable hardware cursors when the nouveau driver is in use. +# +# The nouveau DRM driver does not display the hardware cursor plane on many +# older NVIDIA GPUs, leaving the mouse pointer invisible under Hyprland. +# Skip the fix when the proprietary driver was configured: supported GPUs can +# still use nouveau during installation before switching drivers on reboot. +nvidia_config="${OMARCHY_NVIDIA_MODPROBE_CONFIG:-/etc/modprobe.d/nvidia.conf}" + +if [[ ! -f $nvidia_config ]] && + omarchy-cmd-present lspci && + LC_ALL=C lspci -k | grep -qi 'Kernel driver in use: nouveau'; then + looknfeel="$HOME/.config/hypr/looknfeel.lua" + + if [[ -f $looknfeel ]] && ! grep -q 'no_hardware_cursors' "$looknfeel"; then + echo "Detected nouveau driver. Forcing software cursors so the mouse pointer stays visible." + + cat >>"$looknfeel" <<'EOF' + +-- nouveau does not display the hardware cursor plane on many older NVIDIA GPUs, +-- leaving the pointer invisible on the physical display. Render it in software. +hl.config({ + cursor = { + no_hardware_cursors = true, + }, +}) +EOF + fi +fi diff --git a/test/shell.d/nouveau-cursor-test.sh b/test/shell.d/nouveau-cursor-test.sh new file mode 100644 index 00000000..6f47f976 --- /dev/null +++ b/test/shell.d/nouveau-cursor-test.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +test_tmp=$(mktemp -d) +trap 'rm -rf "$test_tmp"' EXIT + +mkdir -p "$test_tmp/bin" "$test_tmp/home/.config/hypr" +cat >"$test_tmp/bin/lspci" <<'SH' +#!/bin/bash +printf '%s\n' "Kernel driver in use: ${TEST_VIDEO_DRIVER:-nouveau}" +SH +chmod +x "$test_tmp/bin/lspci" + +looknfeel="$test_tmp/home/.config/hypr/looknfeel.lua" +printf '%s\n' '-- User look and feel' >"$looknfeel" + +run_fix() { + HOME="$test_tmp/home" \ + PATH="$test_tmp/bin:$ROOT/bin:$PATH" \ + OMARCHY_NVIDIA_MODPROBE_CONFIG="$test_tmp/nvidia.conf" \ + TEST_VIDEO_DRIVER="${1:-nouveau}" \ + bash -euo pipefail -c 'source "$ROOT/install/user/hardware/fix-nouveau-cursor.sh"' +} + +run_fix >/dev/null +grep -F 'no_hardware_cursors = true' "$looknfeel" >/dev/null +pass "nouveau hardware setup enables software cursors" + +run_fix >/dev/null +(( $(grep -c 'no_hardware_cursors = true' "$looknfeel") == 1 )) || fail "nouveau cursor setup is idempotent" +pass "nouveau cursor setup is idempotent" + +printf '%s\n' '-- User look and feel' >"$looknfeel" +run_fix i915 >/dev/null +if grep -q 'no_hardware_cursors' "$looknfeel"; then + fail "nouveau cursor setup ignores other video drivers" +fi +pass "nouveau cursor setup ignores other video drivers" + +touch "$test_tmp/nvidia.conf" +run_fix >/dev/null +if grep -q 'no_hardware_cursors' "$looknfeel"; then + fail "nouveau cursor setup skips proprietary NVIDIA installs" +fi +pass "nouveau cursor setup skips proprietary NVIDIA installs"