From 2c7b283aefd1327cece88e44119195fd1038db62 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 19 Jan 2026 16:11:23 -0500 Subject: [PATCH] Toggle hybrid GPU mode via supergfxctl (#4277) * Toggle hybrid GPU mode via supergfxctl Very useful for Asus G14 and other laptops with NVIDIA + AMD iGPU combos. * Use correct exit * Simplify * Wording * Revise switching process * Spacing * These are sudo actions * Make it exe * No need for extensions Matches existing style * Relying on the new config should be enough since we are restarting anyway * Prevent race condition * Reminder to add to OPR --- bin/omarchy-menu | 10 +++- bin/omarchy-toggle-hybrid-gpu | 55 +++++++++++++++++++ default/systemd/system-sleep/force-igpu | 18 ++++++ .../supergfxd.service.d/delay-start.conf | 6 ++ 4 files changed, 88 insertions(+), 1 deletion(-) create mode 100755 bin/omarchy-toggle-hybrid-gpu create mode 100755 default/systemd/system-sleep/force-igpu create mode 100644 default/systemd/system/supergfxd.service.d/delay-start.conf diff --git a/bin/omarchy-menu b/bin/omarchy-menu index a52ef40c..9852bdf6 100755 --- a/bin/omarchy-menu +++ b/bin/omarchy-menu @@ -88,10 +88,11 @@ show_learn_menu() { } show_trigger_menu() { - case $(menu "Trigger" " Capture\n Share\n󰔎 Toggle") in + case $(menu "Trigger" " Capture\n Share\n󰔎 Toggle\n Tweaks") in *Capture*) show_capture_menu ;; *Share*) show_share_menu ;; *Toggle*) show_toggle_menu ;; + *Tweaks*) show_tweaks_menu ;; *) show_main_menu ;; esac } @@ -143,6 +144,13 @@ show_toggle_menu() { esac } +show_tweaks_menu() { + case $(menu "Tweaks" " Toggle Hybrid GPU") in + *"Toggle Hybrid GPU"*) present_terminal omarchy-toggle-hybrid-gpu ;; + *) show_trigger_menu ;; + esac +} + show_style_menu() { case $(menu "Style" "󰸌 Theme\n Font\n Background\n Hyprland\n󱄄 Screensaver\n About") in *Theme*) show_theme_menu ;; diff --git a/bin/omarchy-toggle-hybrid-gpu b/bin/omarchy-toggle-hybrid-gpu new file mode 100755 index 00000000..c772395a --- /dev/null +++ b/bin/omarchy-toggle-hybrid-gpu @@ -0,0 +1,55 @@ +#!/bin/bash + +# Toggle dedicated vs integrated GPU mode via supergfxd (for hybrid gpu laptops, like Asus G14). +# Requires reboot to take effect. + +# Ensure supergfxctl has been installed +if omarchy-cmd-missing supergfxctl; then + # FIXME: Convert this to OPR instead of AUR + omarchy-pkg-aur-add supergfxctl + sudo systemctl enable supergfxd + sudo systemctl start supergfxd + + # Needed to deal with restoring to sleep where going through VFIO first means we don't need to reboot. + sudo sed -i "s/\"vfio_enable\": \".*\"/\"vfio_enable\": true/" /etc/supergfxd.conf +fi + +gpu_mode=$(supergfxctl -g) + +case "$gpu_mode" in +"Integrated") + if gum confirm "Enable dedicated GPU and reboot?"; then + # Switch to hybrid mode + sudo sed -i "s/\"mode\": \".*\"/\"mode\": \"Hybrid\"/" /etc/supergfxd.conf + + # Let hybrid mode be the default after system sleep + sudo rm -rf /usr/lib/systemd/system-sleep/force-igpu + + # Remove the startup delay override (not needed for Hybrid mode) + sudo rm -rf /etc/systemd/system/supergfxd.service.d/delay-start.conf + + omarchy-cmd-reboot + fi + ;; +"Hybrid") + if gum confirm "Use only integrated GPU and reboot?"; then + # Switch to integrated mode + sudo sed -i "s/\"mode\": \".*\"/\"mode\": \"Integrated\"/" /etc/supergfxd.conf + + # Force igpu mode after system sleep (or dgpu could get activated) + sudo mkdir -p /usr/lib/systemd/system-sleep + sudo cp -p $OMARCHY_PATH/default/systemd/system-sleep/force-igpu /usr/lib/systemd/system-sleep/ + + # Delay supergfxd startup to avoid race condition with display manager + # that can cause system freeze when booting in Integrated mode + sudo mkdir -p /etc/systemd/system/supergfxd.service.d + sudo cp -p $OMARCHY_PATH/default/systemd/system/supergfxd.service.d/delay-start.conf /etc/systemd/system/supergfxd.service.d/ + + omarchy-cmd-reboot + fi + ;; +*) + echo "Hybrid GPU not found or in unknown mode." + exit 1 + ;; +esac diff --git a/default/systemd/system-sleep/force-igpu b/default/systemd/system-sleep/force-igpu new file mode 100755 index 00000000..ab0d6d6c --- /dev/null +++ b/default/systemd/system-sleep/force-igpu @@ -0,0 +1,18 @@ +#!/bin/bash + +# Use the Vfio to Integrated trick to turn off NVIDIA dgpu when in integrated mode +# without needing to restart the computer. This is needed because computers like the Asus G14 +# will wake after suspend in Hybrid mode, even if the system was in Integrated mode before +# suspending. + +if [[ $1 == "post" ]]; then + # small delay so the device is fully re-enumerated + sleep 4 + + # force-bind dGPU to vfio (fully detached from nvidia) + /usr/bin/supergfxctl -m Vfio + sleep 1 + + # then go back to Integrated, which powers it off again + /usr/bin/supergfxctl -m Integrated +fi diff --git a/default/systemd/system/supergfxd.service.d/delay-start.conf b/default/systemd/system/supergfxd.service.d/delay-start.conf new file mode 100644 index 00000000..19fc2986 --- /dev/null +++ b/default/systemd/system/supergfxd.service.d/delay-start.conf @@ -0,0 +1,6 @@ +[Service] +# Delay startup to avoid race condition with display manager initialization +# when booting in Integrated mode. Without this delay, the system can freeze +# on boot because supergfxd tries to disable the dGPU while the display +# subsystem is still initializing. +ExecStartPre=/bin/sleep 5