-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Refactor #4
Changes from all commits
1f1e679
49b46a1
09c6407
b8090da
34423e3
bcab9d3
0dbdf95
15febe9
ffefdba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| # Valve Index HMD: fix blank EDID | ||
| # Works around blank EDID bug that makes the kernel see the HMD as a 640x480 monitor. | ||
| # Sends a HID reboot command once per boot when the device is enumerated. | ||
| # /tmp is cleared on boot so the flag resets automatically. | ||
| # Trigger systemd service on device add. | ||
|
|
||
| KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="28de", ATTRS{idProduct}=="2300", ACTION=="add", RUN+="/bin/sh -c '(sleep 2; test -f /tmp/.valve-index-rebooted || { printf \"\\x16\\x01\" | cat - /dev/zero | head -c 64 > /dev/%k && touch /tmp/.valve-index-rebooted; }) &'" | ||
| ACTION=="add", SUBSYSTEM=="hidraw", KERNEL=="hidraw*", \ | ||
| ATTRS{idVendor}=="28de", ATTRS{idProduct}=="2300", \ | ||
| TAG+="systemd", ENV{SYSTEMD_WANTS}+="valve-index-hid-reboot@%k.service" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,8 +7,21 @@ set -euo pipefail | |
| # Config | ||
| # --------------------------------------------------------------------------- | ||
| RULE_FILE="99-valve-index-reboot.rules" | ||
| SCRIPT_FILE="valve-index-hid-reboot.sh" | ||
| SERVICE_FILE="valve-index-hid-reboot@.service" | ||
| HOOK_FILE="valve-index-hid-reboot" | ||
|
|
||
| RULE_DST="/etc/udev/rules.d/$RULE_FILE" | ||
| RULE_RAW_URL="https://raw.githubusercontent.com/MiguVT/fixvr/main/src/$RULE_FILE" | ||
| SCRIPT_DST="/usr/local/sbin/$SCRIPT_FILE" | ||
| SERVICE_DST="/etc/systemd/system/$SERVICE_FILE" | ||
| HOOK_DST="/etc/systemd/system-sleep/$HOOK_FILE" # Universal, distro-agnostic | ||
|
|
||
| RAW_BASE="https://raw.githubusercontent.com/MiguVT/fixvr/main/src" | ||
| RULE_RAW_URL="$RAW_BASE/$RULE_FILE" | ||
| SCRIPT_RAW_URL="$RAW_BASE/$SCRIPT_FILE" | ||
| SERVICE_RAW_URL="$RAW_BASE/$SERVICE_FILE" | ||
| HOOK_RAW_URL="$RAW_BASE/$HOOK_FILE" | ||
|
|
||
| AUR_PKG="fixvr-git" | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
|
|
@@ -30,6 +43,10 @@ die() { echo -e "${RED}[✗]${NC} $*" >&2; exit 1; } | |
| # Helpers | ||
| # --------------------------------------------------------------------------- | ||
| SUDO="" | ||
| _TMP_FILES=() # tracks temp files downloaded by find_or_download | ||
| _cleanup_tmp() { [[ ${#_TMP_FILES[@]} -gt 0 ]] && rm -f "${_TMP_FILES[@]}"; } | ||
| trap '_cleanup_tmp' EXIT | ||
|
|
||
| setup_sudo() { | ||
| if [[ $EUID -eq 0 ]]; then | ||
| SUDO="" | ||
|
|
@@ -40,17 +57,19 @@ setup_sudo() { | |
| fi | ||
| } | ||
|
|
||
| # Locate the rule file relative to this script (works when called from anywhere) | ||
| # Falls back to downloading from GitHub when run via curl | bash | ||
| find_rule_file() { | ||
| # Locate a file relative to this script, fallback to download from GitHub | ||
| find_or_download() { | ||
| local filename="$1" | ||
| local url="$2" | ||
|
|
||
| local script_dir | ||
| script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
|
|
||
| local candidates=( | ||
| "$script_dir/$RULE_FILE" # running from src/ | ||
| "$script_dir/../src/$RULE_FILE" # running from repo root | ||
| "$(pwd)/src/$RULE_FILE" # cwd is repo root | ||
| "$(pwd)/$RULE_FILE" # cwd is src/ | ||
| "$script_dir/$filename" # running from src/ | ||
| "$script_dir/../src/$filename" # running from repo root | ||
| "$(pwd)/src/$filename" # cwd is repo root | ||
| "$(pwd)/$filename" # cwd is src/ | ||
| ) | ||
|
|
||
| for f in "${candidates[@]}"; do | ||
|
|
@@ -60,21 +79,21 @@ find_rule_file() { | |
| fi | ||
| done | ||
|
|
||
| # Not found locally (e.g. run via curl | bash) — download from GitHub | ||
| warn "Rule file not found locally, downloading from GitHub…" >&2 | ||
| local tmp_rule | ||
| tmp_rule="$(mktemp "/tmp/${RULE_FILE}.XXXXXX")" | ||
| warn "File $filename not found locally, downloading from GitHub…" >&2 | ||
| local tmp_file | ||
| tmp_file="$(mktemp "/tmp/${filename}.XXXXXX")" | ||
| _TMP_FILES+=("$tmp_file") | ||
|
|
||
| if command -v curl &>/dev/null; then | ||
| curl -fsSL "$RULE_RAW_URL" -o "$tmp_rule" || die "Failed to download rule file from GitHub." | ||
| curl -fsSL "$url" -o "$tmp_file" || die "Failed to download $filename." | ||
| elif command -v wget &>/dev/null; then | ||
| wget -qO "$tmp_rule" "$RULE_RAW_URL" || die "Failed to download rule file from GitHub." | ||
| wget -qO "$tmp_file" "$url" || die "Failed to download $filename." | ||
| else | ||
| die "Rule file not found locally and neither curl nor wget is available." | ||
| die "Neither curl nor wget is available to download $filename." | ||
| fi | ||
|
|
||
| [[ -s "$tmp_rule" ]] || die "Downloaded rule file is empty." | ||
| printf '%s\n' "$tmp_rule" | ||
| [[ -s "$tmp_file" ]] || die "Downloaded $filename is empty." | ||
| printf '%s\n' "$tmp_file" | ||
| } | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
|
|
@@ -164,12 +183,12 @@ install_aur() { | |
|
|
||
| info "Using AUR helper: $aur_helper" | ||
| step "Installing $AUR_PKG…" | ||
|
|
||
| # When piped via `curl | bash`, standard input is hijacked. | ||
| # We must explicitly reconnect stdin to the terminal so the user can interact. | ||
| "$aur_helper" -S "$AUR_PKG" </dev/tty | ||
|
|
||
| info "Done! The udev rule was installed via the AUR package." | ||
| info "Done! The files were installed via the AUR package." | ||
| } | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
|
|
@@ -178,19 +197,34 @@ install_aur() { | |
| install_manual() { | ||
| setup_sudo | ||
|
|
||
| local rule_src | ||
| rule_src="$(find_rule_file)" | ||
| [[ -f "$rule_src" ]] || die "Rule file not found: $rule_src" | ||
| step "Rule file found: $rule_src" | ||
| if ! command -v systemctl &>/dev/null; then | ||
| die "systemd is required for this fix (the udev rule uses SYSTEMD_WANTS).\n Please use a systemd-based distro or install the files manually." | ||
| fi | ||
|
|
||
| local rule_src script_src service_src hook_src | ||
| rule_src="$(find_or_download "$RULE_FILE" "$RULE_RAW_URL")" | ||
| script_src="$(find_or_download "$SCRIPT_FILE" "$SCRIPT_RAW_URL")" | ||
| service_src="$(find_or_download "$SERVICE_FILE" "$SERVICE_RAW_URL")" | ||
| hook_src="$(find_or_download "$HOOK_FILE" "$HOOK_RAW_URL")" | ||
|
|
||
| step "Installing udev rule to $RULE_DST…" | ||
| $SUDO install -m 644 -o root -g root "$rule_src" "$RULE_DST" | ||
|
|
||
| step "Reloading udev rules…" | ||
| step "Installing script to $SCRIPT_DST…" | ||
| $SUDO install -m 755 -o root -g root "$script_src" "$SCRIPT_DST" | ||
|
|
||
| step "Installing systemd service to $SERVICE_DST…" | ||
| $SUDO install -m 644 -o root -g root "$service_src" "$SERVICE_DST" | ||
|
|
||
| step "Installing systemd sleep hook to $HOOK_DST…" | ||
| $SUDO install -m 755 -o root -g root "$hook_src" "$HOOK_DST" | ||
|
|
||
| step "Reloading systemd and udev…" | ||
| $SUDO systemctl daemon-reload | ||
| $SUDO udevadm control --reload-rules | ||
| $SUDO udevadm trigger --action=add --subsystem-match=hidraw | ||
|
Comment on lines
+222
to
225
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @copilot apply changes based on this feedback
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in commit ffefdba. Added a |
||
|
|
||
| info "Done! Reconnect your Valve Index to apply the fix." | ||
| info "Done! Reconnect your Valve Index or resume from sleep to apply the fix." | ||
| } | ||
|
|
||
| # --------------------------------------------------------------------------- | ||
|
|
@@ -208,10 +242,10 @@ echo | |
| if is_nixos; then | ||
| warn "NixOS detected. Manual file installation won't persist across rebuilds." | ||
| echo | ||
| echo -e " Add the udev rule declaratively in your NixOS configuration instead." | ||
| echo -e " Add the files declaratively in your NixOS configuration instead." | ||
| echo -e " See: ${CYAN}https://fixvr.miguvt.com/install#nixos${NC}" | ||
| echo | ||
| read -rp " Install manually to /etc/udev/rules.d/ anyway? [y/N] " yn </dev/tty | ||
| read -rp " Install manually anyway? [y/N] " yn </dev/tty | ||
| echo | ||
| case "$yn" in | ||
| [Yy]*) install_manual ;; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| #!/bin/sh | ||
| case "$1" in | ||
| post) | ||
| rm -f /run/.valve-index-rebooted | ||
| sleep 2 | ||
| /usr/local/sbin/valve-index-hid-reboot.sh | ||
| ;; | ||
| esac |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| #!/bin/sh | ||
| set -eu | ||
|
|
||
| VID="28de" | ||
| PID="2300" | ||
| FLAG="/run/.valve-index-rebooted" | ||
|
|
||
| for dev in /dev/hidraw*; do | ||
| [ -e "$dev" ] || continue | ||
| sys="/sys/class/hidraw/$(basename "$dev")/device" | ||
|
|
||
| v="$(cat "$sys/idVendor" 2>/dev/null || true)" | ||
| p="$(cat "$sys/idProduct" 2>/dev/null || true)" | ||
| v="${v#0x}" | ||
| p="${p#0x}" | ||
|
|
||
| if [ "$v" = "$VID" ] && [ "$p" = "$PID" ]; then | ||
| if printf '\x16\x01' | cat - /dev/zero | head -c 64 > "$dev"; then | ||
| : > "$FLAG" | ||
| exit 0 | ||
| else | ||
| echo "Failed to write reboot command to $dev" >&2 | ||
| exit 1 | ||
| fi | ||
| fi | ||
| done | ||
|
|
||
| exit 0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| [Unit] | ||
| Description=Valve Index HID reboot for /dev/%I | ||
| After=systemd-udevd.service | ||
| ConditionPathExists=/dev/%I | ||
|
|
||
| [Service] | ||
| Type=oneshot | ||
| ExecStart=/usr/bin/flock /run/valve-index-hid-reboot.lock /bin/sh -c 'sleep 2; if ! test -f /run/.valve-index-rebooted; then /usr/local/sbin/valve-index-hid-reboot.sh; fi' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot apply changes based on this feedback
cleanup tmp files with trap
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in commit 15febe9. Added a
_TMP_FILESarray that records each temp path immediately aftermktemp, and anEXITtrap calling_cleanup_tmptorm -fall tracked files when the script exits (normally or viadie).