#!/bin/bash # GeForce NOW Linux Installer for Arch Linux / Hyprland (Omarchy-aware) # Installs the official NVIDIA GeForce NOW flatpak and wires it up for XWayland. set -e echo "=== GeForce NOW Installer for Arch Linux ===" echo "" if [ "$EUID" -eq 0 ]; then echo "ERROR: Do not run this script as root. Run as your normal user." exit 1 fi # 1/4 - Flatpak echo "[1/4] Checking for Flatpak..." if ! command -v flatpak &> /dev/null; then echo " Flatpak not found. Installing..." sudo pacman -S --noconfirm flatpak echo " Flatpak installed." else echo " Flatpak is already installed." fi # 2/4 - Flathub echo "[2/4] Checking Flathub repository..." if ! flatpak remotes --system | grep -q "flathub"; then echo " Adding Flathub repository..." sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo echo " Flathub added." else echo " Flathub is already configured." fi # 3/4 - Runtime echo "[3/4] Installing Flatpak runtime dependencies..." flatpak install -y --system flathub org.freedesktop.Platform//24.08 2>/dev/null || true # 4/4 - GeForce NOW echo "[4/4] Installing GeForce NOW..." flatpak remote-add --user --if-not-exists GeForceNOW https://international.download.nvidia.com/GFNLinux/flatpak/geforcenow.flatpakrepo flatpak install -y --user GeForceNOW com.nvidia.geforcenow # Force XWayland (Wayland-native breaks under Hyprland) echo "[+] Configuring for XWayland mode..." flatpak override --user --nosocket=wayland com.nvidia.geforcenow flatpak override --user --socket=x11 com.nvidia.geforcenow # Make Flatpak app .desktop entries discoverable by app launchers echo "[+] Configuring environment for Flatpak apps..." XDG_LINE="export XDG_DATA_DIRS=\"\${XDG_DATA_DIRS:-/usr/local/share:/usr/share}:/var/lib/flatpak/exports/share:\$HOME/.local/share/flatpak/exports/share\"" add_xdg_line() { local file="$1" [ -f "$file" ] || return 0 if ! grep -q "flatpak/exports/share" "$file" 2>/dev/null; then { echo "" echo "# Flatpak app directories for desktop entries and icons" echo "$XDG_LINE" } >> "$file" echo " Added to $file" fi } if [ -f "$HOME/.bash_profile" ]; then add_xdg_line "$HOME/.bash_profile" elif [ -f "$HOME/.profile" ]; then add_xdg_line "$HOME/.profile" fi add_xdg_line "$HOME/.zshrc" # Launcher script LAUNCHER_DIR="$HOME/.local/bin" mkdir -p "$LAUNCHER_DIR" cat > "$LAUNCHER_DIR/geforcenow" << 'LAUNCHER' #!/bin/bash # GeForce NOW launcher for Hyprland (XWayland) exec flatpak run --nosocket=wayland \ --env=SDL_VIDEODRIVER=x11 \ com.nvidia.geforcenow \ "$@" LAUNCHER chmod +x "$LAUNCHER_DIR/geforcenow" # Desktop entry override DESKTOP_DIR="$HOME/.local/share/applications" mkdir -p "$DESKTOP_DIR" rm -f "$DESKTOP_DIR/geforcenow.desktop" rm -f "$HOME/Desktop/com.nvidia.geforcenow.desktop" 2>/dev/null || true ICON_PATH="$HOME/.local/share/flatpak/exports/share/icons/hicolor/512x512/apps/com.nvidia.geforcenow.png" cat > "$DESKTOP_DIR/com.nvidia.geforcenow.desktop" << EOF [Desktop Entry] Version=1.0 Name=NVIDIA GeForce NOW GenericName=NVIDIA GeForce NOW Comment=Play games from the cloud with GeForce NOW Exec=$LAUNCHER_DIR/geforcenow Icon=$ICON_PATH Terminal=false Type=Application Categories=Network;Game; Keywords=nvidia;geforce;cloud;gaming;stream; StartupWMClass=GeForceNOW X-Flatpak=com.nvidia.geforcenow EOF update-desktop-database "$DESKTOP_DIR" 2>/dev/null || true # Hyprland window rule — append a marker block to ~/.config/hypr/hyprland.conf. # Idempotent: re-running strips the old block before appending a new one. # (Omarchy doesn't auto-source ~/.config/hypr/windowrules.conf, so we target # hyprland.conf directly.) HYPR_CONF="$HOME/.config/hypr/hyprland.conf" BEGIN_MARKER="# >>> geforcenow-native >>>" END_MARKER="# <<< geforcenow-native <<<" if [ -f "$HYPR_CONF" ]; then echo "[+] Adding Hyprland window rule for fullscreen launch..." # Strip any prior block sed -i "/$BEGIN_MARKER/,/$END_MARKER/d" "$HYPR_CONF" { echo "" echo "$BEGIN_MARKER" echo "# GeForce NOW - fullscreen on launch" echo "windowrule = fullscreen, class:^(GeForceNOW)$" echo "$END_MARKER" } >> "$HYPR_CONF" echo " Window rule injected into $HYPR_CONF" # Reload Hyprland if running hypr_root="${XDG_RUNTIME_DIR:-/run/user/$UID}/hypr" if [ -d "$hypr_root" ]; then for sock in "$hypr_root"/*/.socket.sock; do [ -e "$sock" ] || continue inst="${sock%/.socket.sock}"; inst="${inst##*/}" HYPRLAND_INSTANCE_SIGNATURE="$inst" hyprctl reload >/dev/null 2>&1 || true break done fi fi # Refresh Walker so the new .desktop entry shows up systemctl --user restart elephant.service 2>/dev/null || true echo "" echo "=== Installation Complete ===" echo "" echo "You can launch GeForce NOW by:" echo " 1. 'NVIDIA GeForce NOW' in your application launcher (Walker / rofi / etc.)" echo " 2. Running 'geforcenow' from terminal" echo "" echo "Note: The app runs in XWayland mode for Hyprland compatibility."