# Omarchy / Hyprland Fix for ASUS ROG Zephyrus G14 (AMD iGPU + NVIDIA dGPU)

> Source: <https://gist.github.com/codyoss/a506c49ed5212c5b3e40614a7ac4c435>
> Published: 2026-09-01 05:19:18+00:00

| #!/usr/bin/env bash | |
| # ============================================================================== | |
| # Omarchy / Hyprland Setup & Fix for ASUS ROG Zephyrus G14 | |
| # Hardware: AMD Ryzen AI 9 HX 370 (Radeon 890M iGPU) + NVIDIA GeForce RTX dGPU | |
| # Display: 14" 2.8K/3K 120Hz OLED Panel (eDP-1) | |
| # ============================================================================== | |
| # This script resolves: | |
| # 1. Aquamarine atomic DRM commit freeze ([AQ] atomic drm request: failed to commit) | |
| # by setting AQ_NO_ATOMIC=1 across UWSM, PAM, and shell environments. | |
| # 2. Invisible/frozen cursor on legacy DRM by forcing software cursor fallback. | |
| # 3. Colon-safe, persistent GPU device routing via udev symlinks (/dev/dri/amd-igpu). | |
| # 4. Omarchy Lua configuration errors in monitors.lua (proper 1.5x HiDPI scaling). | |
| # 5. Early KMS module loading in mkinitcpio and Limine bootloader DRM modesetting. | |
| # | |
| # Usage: | |
| # curl -sL <your-new-gist-raw-url> | bash | |
| # ============================================================================== | |
| set -eo pipefail | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| BOLD='\033[1m' | |
| NC='\033[0m' | |
| info() { echo -e "${BLUE}[INFO]${NC} $*"; } | |
| success() { echo -e "${GREEN}[SUCCESS]${NC} $*"; } | |
| warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } | |
| error() { echo -e "${RED}[ERROR]${NC} $*"; } | |
| echo -e "${BOLD}${BLUE}======================================================${NC}" | |
| echo -e "${BOLD}${BLUE} Omarchy / Hyprland G14 Hybrid Graphics Fix ${NC}" | |
| echo -e "${BOLD}${BLUE}======================================================${NC}" | |
| # ------------------------------------------------------------------------------ | |
| # 1. GPU Detection & Persistent Udev Symlinks | |
| # ------------------------------------------------------------------------------ | |
| info "Detecting AMD iGPU and NVIDIA dGPU PCI addresses..." | |
| AMD_PCI=$(lspci -D -d 1002::03xx 2>/dev/null | awk '{print $1}' | head -n 1 || true) | |
| NVIDIA_PCI=$(lspci -D -d 10de::03xx 2>/dev/null | awk '{print $1}' | head -n 1 || true) | |
| # Fallback detection via VGA/3D controller strings if class filter missed | |
| if [[ -z "$AMD_PCI" ]]; then | |
| AMD_PCI=$(lspci -D 2>/dev/null | grep -i -E "VGA|3D|Display" | grep -i -E "AMD|ATI" | awk '{print $1}' | head -n 1 || true) | |
| fi | |
| if [[ -z "$NVIDIA_PCI" ]]; then | |
| NVIDIA_PCI=$(lspci -D 2>/dev/null | grep -i -E "VGA|3D|Display" | grep -i "NVIDIA" | awk '{print $1}' | head -n 1 || true) | |
| fi | |
| info "Detected AMD iGPU at PCI: ${AMD_PCI:-'Not found'}" | |
| info "Detected NVIDIA dGPU at PCI: ${NVIDIA_PCI:-'Not found'}" | |
| UDEV_RULE_FILE="/etc/udev/rules.d/99-hyprland-drm.rules" | |
| if command -v sudo &>/dev/null && [[ -n "$AMD_PCI" ]]; then | |
| info "Configuring persistent udev rules in ${UDEV_RULE_FILE}..." | |
| sudo bash -c "cat << 'UDEV' > ${UDEV_RULE_FILE} | |
| # Persistent symlinks for Hyprland/Aquamarine (avoids colon-delimiter PCI path bug) | |
| KERNEL==\"card*\", SUBSYSTEM==\"drm\", SUBSYSTEMS==\"pci\", KERNELS==\"${AMD_PCI}\", SYMLINK+=\"dri/amd-igpu\" | |
| UDEV" | |
| if [[ -n "$NVIDIA_PCI" ]]; then | |
| sudo bash -c "cat << UDEV >> ${UDEV_RULE_FILE} | |
| KERNEL==\"card*\", SUBSYSTEM==\"drm\", SUBSYSTEMS==\"pci\", KERNELS==\"${NVIDIA_PCI}\", SYMLINK+=\"dri/nvidia-dgpu\" | |
| UDEV" | |
| fi | |
| sudo udevadm control --reload-rules 2>/dev/null || true | |
| sudo udevadm trigger --subsystem-match=drm 2>/dev/null || true | |
| # Create immediate symlinks right now | |
| AMD_CARD=$(readlink -f "/dev/dri/by-path/pci-${AMD_PCI}-card" 2>/dev/null || true) | |
| if [[ -n "${AMD_CARD}" && -e "${AMD_CARD}" ]]; then | |
| sudo ln -sfn "${AMD_CARD}" /dev/dri/amd-igpu | |
| fi | |
| if [[ -n "$NVIDIA_PCI" ]]; then | |
| NVIDIA_CARD=$(readlink -f "/dev/dri/by-path/pci-${NVIDIA_PCI}-card" 2>/dev/null || true) | |
| if [[ -n "${NVIDIA_CARD}" && -e "${NVIDIA_CARD}" ]]; then | |
| sudo ln -sfn "${NVIDIA_CARD}" /dev/dri/nvidia-dgpu | |
| fi | |
| fi | |
| success "Udev rules and /dev/dri symlinks configured." | |
| fi | |
| # Set target primary display device | |
| if [[ -e /dev/dri/amd-igpu ]]; then | |
| AQ_DEVICES="/dev/dri/amd-igpu" | |
| else | |
| AQ_DEVICES="/dev/dri/card0" | |
| fi | |
| info "Using primary display device: ${AQ_DEVICES}" | |
| # ------------------------------------------------------------------------------ | |
| # 2. Configure UWSM & Session Environment Variables | |
| # ------------------------------------------------------------------------------ | |
| info "Configuring environment variables for Aquamarine and software cursor..." | |
| set_env_var() { | |
| local file="$1" | |
| local key="$2" | |
| local val="$3" | |
| mkdir -p "$(dirname "$file")" | |
| touch "$file" | |
| sed -i "/^export ${key}=/d" "$file" | |
| sed -i "/^${key}=/d" "$file" | |
| echo "export ${key}=\"${val}\"" >> "$file" | |
| } | |
| # UWSM Hyprland environment (~/.config/uwsm/env-hyprland) | |
| set_env_var "${HOME}/.config/uwsm/env-hyprland" "AQ_NO_ATOMIC" "1" | |
| set_env_var "${HOME}/.config/uwsm/env-hyprland" "WLR_NO_HARDWARE_CURSORS" "1" | |
| set_env_var "${HOME}/.config/uwsm/env-hyprland" "AQ_DRM_DEVICES" "${AQ_DEVICES}" | |
| # UWSM General environment (~/.config/uwsm/env) | |
| set_env_var "${HOME}/.config/uwsm/env" "AQ_NO_ATOMIC" "1" | |
| set_env_var "${HOME}/.config/uwsm/env" "WLR_NO_HARDWARE_CURSORS" "1" | |
| # Shell Profile (~/.bash_profile) | |
| set_env_var "${HOME}/.bash_profile" "AQ_NO_ATOMIC" "1" | |
| set_env_var "${HOME}/.bash_profile" "WLR_NO_HARDWARE_CURSORS" "1" | |
| # System-wide environment (/etc/environment for display managers like greetd/sddm) | |
| if command -v sudo &>/dev/null; then | |
| sudo bash -c 'touch /etc/environment | |
| sed -i "/^AQ_NO_ATOMIC=/d" /etc/environment | |
| sed -i "/^WLR_NO_HARDWARE_CURSORS=/d" /etc/environment | |
| echo "AQ_NO_ATOMIC=1" >> /etc/environment | |
| echo "WLR_NO_HARDWARE_CURSORS=1" >> /etc/environment' | |
| fi | |
| success "Environment variables written to UWSM, bash_profile, and /etc/environment." | |
| # ------------------------------------------------------------------------------ | |
| # 3. Configure Omarchy Hyprland Lua Files | |
| # ------------------------------------------------------------------------------ | |
| info "Configuring Omarchy Hyprland Lua settings..." | |
| HYPR_DIR="${HOME}/.config/hypr" | |
| mkdir -p "${HYPR_DIR}" | |
| # Write valid Lua syntax to monitors.lua (OLED 2880x1800@120Hz at 1.5x scale) | |
| cat << 'EOF' > "${HYPR_DIR}/monitors.lua" | |
| -- Omarchy Monitor Configuration | |
| local omarchy_monitor_scale = 1.5 | |
| local omarchy_gdk_scale = 1.5 | |
| hl.env("GDK_SCALE", tostring(omarchy_gdk_scale)) | |
| hl.monitor({ | |
| output = "eDP-1", | |
| mode = "2880x1800@120", | |
| position = "0x0", | |
| scale = omarchy_monitor_scale | |
| }) | |
| EOF | |
| success "Configured ${HYPR_DIR}/monitors.lua" | |
| # Clean up any legacy or invalid calls in hyprland.lua | |
| if [[ -f "${HYPR_DIR}/hyprland.lua" ]]; then | |
| sed -i '/hl.cursor/,/})/d' "${HYPR_DIR}/hyprland.lua" | |
| sed -i '/no_hardware_cursors/d' "${HYPR_DIR}/hyprland.lua" | |
| sed -i '/AQ_DRM_DEVICES/d' "${HYPR_DIR}/hyprland.lua" | |
| sed -i '/by-path/d' "${HYPR_DIR}/hyprland.lua" | |
| success "Cleaned up ${HYPR_DIR}/hyprland.lua" | |
| fi | |
| # ------------------------------------------------------------------------------ | |
| # 4. Early KMS Initramfs & Bootloader Options | |
| # ------------------------------------------------------------------------------ | |
| if command -v sudo &>/dev/null; then | |
| # mkinitcpio early KMS | |
| MKINITCPIO="/etc/mkinitcpio.conf" | |
| if [[ -f "${MKINITCPIO}" ]]; then | |
| info "Configuring early KMS modules in ${MKINITCPIO}..." | |
| if ! grep -q "amdgpu" "${MKINITCPIO}" || ! grep -q "nvidia_drm" "${MKINITCPIO}"; then | |
| sudo cp "${MKINITCPIO}" "${MKINITCPIO}.bak.$(date +%s)" | |
| sudo sed -i 's/^MODULES=(.*/MODULES=(amdgpu nvidia nvidia_modeset nvidia_uvm nvidia_drm)/' "${MKINITCPIO}" | |
| info "Regenerating initramfs images (mkinitcpio -P)..." | |
| sudo mkinitcpio -P || warn "mkinitcpio encountered a non-fatal warning; continuing." | |
| success "Initramfs early KMS updated." | |
| else | |
| success "Early KMS modules already present in ${MKINITCPIO}." | |
| fi | |
| fi | |
| # Limine bootloader kernel parameters | |
| LIMINE_CONF="/etc/default/limine" | |
| if [[ -f "${LIMINE_CONF}" ]]; then | |
| if ! grep -q "nvidia_drm.modeset=1" "${LIMINE_CONF}"; then | |
| info "Adding nvidia_drm modeset parameters to ${LIMINE_CONF}..." | |
| sudo sed -i 's/APPEND="/APPEND="nvidia_drm.modeset=1 nvidia_drm.fbdev=1 /' "${LIMINE_CONF}" || true | |
| success "Limine configuration updated." | |
| fi | |
| fi | |
| fi | |
| # ------------------------------------------------------------------------------ | |
| # 5. Summary & Completion | |
| # ------------------------------------------------------------------------------ | |
| echo -e "${BOLD}${GREEN}======================================================${NC}" | |
| echo -e "${BOLD}${GREEN} Setup Completed Successfully! ${NC}" | |
| echo -e "${BOLD}${GREEN}======================================================${NC}" | |
| echo -e "Applied settings:" | |
| echo -e " • ${BOLD}AQ_NO_ATOMIC=1${NC} (Bypasses AMD Strix Point DRM atomic commit bug)" | |
| echo -e " • ${BOLD}WLR_NO_HARDWARE_CURSORS=1${NC} (Prevents cursor freezes on legacy DRM)" | |
| echo -e " • ${BOLD}AQ_DRM_DEVICES=${AQ_DEVICES}${NC}" | |
| echo -e " • ${BOLD}monitors.lua${NC} configured for 2880x1800@120Hz with 1.5x HiDPI scale" | |
| echo -e "" | |
| echo -e "To apply all kernel and module changes, restart your laptop:" | |
| echo -e " ${YELLOW}sudo reboot${NC}" |
