Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.

Inbox
ReportR-2927GitHub issuePublicReceived

Laptop / Hybrid GPU Power Management Issue (NVIDIA, iGPU + dGPU)

Reported by itsmedardan · filed Sep 18, 2025Closed upstream on 2026-02-01 by dhh. GitHub close reason: completed. No closing PR or commit is recorded — "completed" alone is not evidence of a fix.

Received and recorded verbatim. Nothing has been checked yet.

At a glance

1 · What is claimed?
Only the report text below — no validator has restated it as checkable claims yet.
2 · What does it affect?
Not yet mapped to any requirement or component.
3 · Is it reproducible?
No validation has been run yet.
4 · What remains unclear?
  • Not validated yet: no claims, no reproducer.
5 · What happens next?
Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. No decision has been recorded yet.

Original report

Laptop / Hybrid GPU Power Management Issue (NVIDIA, iGPU + dGPU)revision 1 · captured 2026-10-04 11:35 UTC via poll

Overview

I've been thoroughly enjoying Omarchy over the past few weeks. However, I've noticed a significant drop in battery life on my laptop. The main culprit appears to be the NVIDIA dGPU, which remains active even when not in use. It does not enter low-power states such as sleep, suspend, or d3cold, resulting in unnecessary power drain.

My goal is to set up a proper hybrid GPU configuration, where the Intel iGPU handles all general rendering tasks, and the NVIDIA dGPU is only activated on-demand for specific applications (e.g., via prime-run). I have achieved this setup successfully in the past on Arch Linux using tools like envycontrol and prime-run.


❌ Current Behavior

  • The NVIDIA dGPU remains active at all times, even when no applications explicitly require it.
  • Running sudo lsof /dev/nvidia* 2>/dev/null shows Hyprland, Walker, and other apps using the dGPU.
  • nvtop confirms that walker is utilizing the dGPU.
  • I have followed the official Hyprland Multi-GPU Guide, and I'm currently using:
  • And also using envycontrol -s hybrid

✅ Expected Behavior

  1. iGPU as Default - All regular rendering tasks, including the Wayland compositor (Hyprland), should default to the Intel iGPU.
  2. dGPU On-Demand - The NVIDIA dGPU should only be activated when launching applications with prime-run or other explicit offloading methods.
  3. dGPU Power Saving - When idle, the NVIDIA dGPU should transition into a low-power state (e.g., d3cold), conserving battery life.

Steps I have taken and guide

📦 1. Create Persistent GPU Symlinks with udev

This prevents /dev/dri/card0, /dev/dri/card1 shuffling between reboots.

🔧 Script: gpu-symlinks.sh

#!/bin/bash

declare -A GPU_SYMLINKS=(
    ["Intel"]="intel-igpu"
    ["AMD"]="amd-igpu"
    ["NVIDIA"]="nvidia-dgpu"
)

UDEV_DIR="/etc/udev/rules.d"
GPU_LIST=$(lspci -d ::03xx)

if [ -z "$GPU_LIST" ]; then
    echo "No GPUs detected!"
    exit 1
fi

for VENDOR in "${!GPU_SYMLINKS[@]}"; do
    PCI_ID=$(echo "$GPU_LIST" | grep "$VENDOR" | head -n1 | cut -f1 -d' ')
    [ -z "$PCI_ID" ] && continue

    SYMLINK_NAME="${GPU_SYMLINKS[$VENDOR]}"
    RULE_PATH="$UDEV_DIR/${SYMLINK_NAME}-dev-path.rules"

    echo "Creating udev rule for $VENDOR GPU at $PCI_ID → /dev/dri/$SYMLINK_NAME"

    UDEV_RULE=$(cat <<EOF
KERNEL=="card*", \\
KERNELS=="0000:$PCI_ID", \\
SUBSYSTEM=="drm", \\
SUBSYSTEMS=="pci", \\
SYMLINK+="dri/$SYMLINK_NAME"
EOF
    )

    echo "$UDEV_RULE" | sudo tee "$RULE_PATH" > /dev/null
done

echo "Reloading udev rules..."
sudo udevadm control --reload
sudo udevadm trigger

✅ Result

/dev/dri/intel-igpu     -> card0
/dev/dri/nvidia-dgpu    -> card1

These symlinks always point to the correct GPU regardless of boot order.

⚙️ 2. Configure Hyprland to Use iGPU
In your ~/.config/uwsm/env-hyprland or systemd environment for Hyprland:

export AQ_DRM_DEVICES="/dev/dri/intel-igpu:/dev/dri/nvidia-dgpu"

This sets iGPU as the primary renderer and allows fallback to dGPU (for external monitors or specific apps).

🧪 3. Set EnvyControl to Hybrid Mode

sudo pacman -S envycontrol
sudo envycontrol -s hybrid

This enables dynamic GPU offloading: iGPU is default, dGPU available for apps via offload.

🎮 4. Run Apps on the NVIDIA dGPU (When Needed)
Use prime-run or explicit environment variables:

prime-run blender
prime-run resolve
prime-run steam

Manual example:

__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia blender

🛑 5. Don’t Force NVIDIA Globally in Hyprland
Avoid this in your Hyprland config:

# ❌ Do NOT use when running on iGPU
# env = NVD_BACKEND,direct
# env = LIBVA_DRIVER_NAME,nvidia
# env = __GLX_VENDOR_LIBRARY_NAME,nvidia

These force NVIDIA rendering globally and can break iGPU setups.

🔋 6. Optional: Enable NVIDIA Power Management
To auto-disable dGPU when not in use:

sudo pacman -S nvidia-prime

Create config:

sudo tee /etc/modprobe.d/nvidia-power-management.conf <<EOF
options nvidia NVreg_DynamicPowerManagement=0x02
EOF

Start persistence daemon:

sudo systemctl enable nvidia-persistenced.service
sudo systemctl start nvidia-persistenced.service

Check power state:

cat /proc/driver/nvidia/gpus/0000*/power
View raw text
## Overview

I've been thoroughly enjoying **Omarchy** over the past few weeks. However, I've noticed a significant drop in battery life on my laptop. The main culprit appears to be the **NVIDIA dGPU**, which remains active even when not in use. It does **not** enter low-power states such as `sleep`, `suspend`, or `d3cold`, resulting in unnecessary power drain.

My goal is to set up a proper **hybrid GPU configuration**, where the **Intel iGPU** handles all general rendering tasks, and the **NVIDIA dGPU** is only activated on-demand for specific applications (e.g., via `prime-run`). I have achieved this setup successfully in the past on **Arch Linux** using tools like `envycontrol` and `prime-run`.

---

## ❌ Current Behavior

- The **NVIDIA dGPU remains active at all times**, even when no applications explicitly require it.
- Running `sudo lsof /dev/nvidia* 2>/dev/null` shows Hyprland, Walker, and other apps using the dGPU.
- `nvtop` confirms that `walker` is utilizing the dGPU.
- I have followed the official [Hyprland Multi-GPU Guide](https://wiki.hypr.land/Configuring/Multi-GPU/), and I'm currently using:
- And also using `envycontrol -s hybrid`

---

## ✅ Expected Behavior

1. **iGPU as Default** - All regular rendering tasks, including the Wayland compositor (Hyprland), should default to the Intel iGPU.
2. **dGPU On-Demand** - The NVIDIA dGPU should only be activated when launching applications with prime-run or other explicit offloading methods.
3. **dGPU Power Saving** - When idle, the NVIDIA dGPU should transition into a low-power state (e.g., d3cold), conserving battery life.

## Steps I have taken and guide

## 📦 1. Create Persistent GPU Symlinks with `udev`

This prevents `/dev/dri/card0`, `/dev/dri/card1` shuffling between reboots.

### 🔧 Script: `gpu-symlinks.sh`

```bash
#!/bin/bash

declare -A GPU_SYMLINKS=(
    ["Intel"]="intel-igpu"
    ["AMD"]="amd-igpu"
    ["NVIDIA"]="nvidia-dgpu"
)

UDEV_DIR="/etc/udev/rules.d"
GPU_LIST=$(lspci -d ::03xx)

if [ -z "$GPU_LIST" ]; then
    echo "No GPUs detected!"
    exit 1
fi

for VENDOR in "${!GPU_SYMLINKS[@]}"; do
    PCI_ID=$(echo "$GPU_LIST" | grep "$VENDOR" | head -n1 | cut -f1 -d' ')
    [ -z "$PCI_ID" ] && continue

    SYMLINK_NAME="${GPU_SYMLINKS[$VENDOR]}"
    RULE_PATH="$UDEV_DIR/${SYMLINK_NAME}-dev-path.rules"

    echo "Creating udev rule for $VENDOR GPU at $PCI_ID → /dev/dri/$SYMLINK_NAME"

    UDEV_RULE=$(cat <<EOF
KERNEL=="card*", \\
KERNELS=="0000:$PCI_ID", \\
SUBSYSTEM=="drm", \\
SUBSYSTEMS=="pci", \\
SYMLINK+="dri/$SYMLINK_NAME"
EOF
    )

    echo "$UDEV_RULE" | sudo tee "$RULE_PATH" > /dev/null
done

echo "Reloading udev rules..."
sudo udevadm control --reload
sudo udevadm trigger
```
✅ Result
```text
/dev/dri/intel-igpu     -> card0
/dev/dri/nvidia-dgpu    -> card1
```
These symlinks always point to the correct GPU regardless of boot order.

⚙️ 2. Configure Hyprland to Use iGPU
In your `~/.config/uwsm/env-hyprland` or systemd environment for Hyprland:
```bash
export AQ_DRM_DEVICES="/dev/dri/intel-igpu:/dev/dri/nvidia-dgpu"
```
This sets iGPU as the primary renderer and allows fallback to dGPU (for external monitors or specific apps).

🧪 3. Set EnvyControl to Hybrid Mode
```bash
sudo pacman -S envycontrol
sudo envycontrol -s hybrid
```
This enables dynamic GPU offloading: iGPU is default, dGPU available for apps via offload.

🎮 4. Run Apps on the NVIDIA dGPU (When Needed)
Use `prime-run` or explicit environment variables:
```bash
prime-run blender
prime-run resolve
prime-run steam
```
Manual example:
```bash
__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia blender
```

🛑 5. Don’t Force NVIDIA Globally in Hyprland
Avoid this in your Hyprland config:
```text
# ❌ Do NOT use when running on iGPU
# env = NVD_BACKEND,direct
# env = LIBVA_DRIVER_NAME,nvidia
# env = __GLX_VENDOR_LIBRARY_NAME,nvidia
```
These force NVIDIA rendering globally and can break iGPU setups.

🔋 6. Optional: Enable NVIDIA Power Management
To auto-disable dGPU when not in use:
```bash
sudo pacman -S nvidia-prime
```
Create config:
```bash
sudo tee /etc/modprobe.d/nvidia-power-management.conf <<EOF
options nvidia NVreg_DynamicPowerManagement=0x02
EOF
```
Start persistence daemon:
```bash
sudo systemctl enable nvidia-persistenced.service
sudo systemctl start nvidia-persistenced.service
```
Check power state:
```bash
cat /proc/driver/nvidia/gpus/0000*/power
```

Validation

Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.

Linked

Not linked to any known issue, other report or change yet.

Decision

Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.

No decision has been recorded yet.