diff --git a/apps/artcraft-launcher/src/main.rs b/apps/artcraft-launcher/src/main.rs
--- a/apps/artcraft-launcher/src/main.rs
+++ b/apps/artcraft-launcher/src/main.rs
@@ -178,7 +178,8 @@ fn wgpu_options() -> eframe::WgpuConfiguration {
             setup.instance_descriptor.backends = backends;
         } else {
             setup.instance_descriptor.backends = Backends::DX12 | Backends::GL;
-            let integrated = setup.power_preference == PowerPreference::LowPower;
+            let integrated =
+                prefer_integrated(PowerPreference::from_env(), artcraft_launcher_native::graphics::windows_gpu_preference(), setup.power_preference);
             setup.native_adapter_selector = Some(Arc::new(move |adapters, surface| {
                 adapters
                     .iter()
@@ -208,6 +209,27 @@ fn pin_dx12_compiler(config: &mut eframe::WgpuConfiguration, env_choice: Option<
     }
 }
 
+/// Whether the integrated GPU should come before the discrete one on Windows: what
+/// `WGPU_POWER_PREF` says if it is set (a developer's override, as everywhere), else the choice
+/// Windows recorded for this exe under Settings → Graphics (#399: "Power saving" there used to
+/// change nothing, and a hybrid laptop's discrete GPU stayed awake for a launcher that only needs
+/// to draw its window), else wgpu's default preference.
+#[cfg(any(windows, test))]
+fn prefer_integrated(
+    env: Option<eframe::wgpu::PowerPreference>,
+    windows: Option<artcraft_launcher_native::graphics::GpuPreference>,
+    default: eframe::wgpu::PowerPreference,
+) -> bool {
+    use artcraft_launcher_native::graphics::GpuPreference;
+    use eframe::wgpu::PowerPreference;
+    match (env, windows) {
+        (Some(env), _) => env == PowerPreference::LowPower,
+        (None, Some(GpuPreference::PowerSaving)) => true,
+        (None, Some(GpuPreference::HighPerformance)) => false,
+        (None, None) => default == PowerPreference::LowPower,
+    }
+}
+
 /// wgpu's own adapter order (by device type, then enumeration order), except that any Direct3D 12
 /// adapter, the WARP software one included, comes before GL. wgpu ranks WARP last, so on GPUs with
 /// no D3D12 driver (Intel HD 4000, Radeon TeraScale) it picked the GL one, whose legacy driver
@@ -995,6 +1017,22 @@ mod tests {
         assert!(matches!(compiler(Some(Dx12Compiler::default_dynamic_dxc())), Dx12Compiler::DynamicDxc { .. }));
     }
 
+    /// Windows' Graphics setting for the exe decides between the GPUs unless `WGPU_POWER_PREF`
+    /// is set; without either, wgpu's default preference stands (#399).
+    #[test]
+    fn windows_graphics_setting_picks_the_gpu_unless_the_environment_does() {
+        use artcraft_launcher_native::graphics::GpuPreference::{HighPerformance, PowerSaving};
+        use eframe::wgpu::PowerPreference::{HighPerformance as High, LowPower, None as NoPref};
+        assert!(prefer_integrated(None, Some(PowerSaving), High));
+        assert!(!prefer_integrated(None, Some(HighPerformance), LowPower));
+        assert!(!prefer_integrated(None, None, High));
+        assert!(prefer_integrated(None, None, LowPower));
+        assert!(!prefer_integrated(None, None, NoPref));
+        // The environment overrides the setting either way.
+        assert!(prefer_integrated(Some(LowPower), Some(HighPerformance), High));
+        assert!(!prefer_integrated(Some(High), Some(PowerSaving), LowPower));
+    }
+
     #[test]
     fn warp_beats_a_gl_gpu_but_not_a_d3d12_gpu() {
         use eframe::wgpu::{Backend, DeviceType};
diff --git a/crates/native/src/graphics.rs b/crates/native/src/graphics.rs
new file mode 100644
--- /dev/null
+++ b/crates/native/src/graphics.rs
@@ -0,0 +1,49 @@
+//! What the system says about which GPU an app should draw with.
+
+/// Windows' per-app choice under Settings → System → Display → Graphics.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum GpuPreference {
+    /// "Power saving": the integrated GPU.
+    PowerSaving,
+    /// "High performance": the discrete GPU.
+    HighPerformance,
+}
+
+/// The choice Windows recorded for this executable, if any. Settings keeps it under
+/// `HKCU\Software\Microsoft\DirectX\UserGpuPreferences`, one value per exe path, as
+/// `GpuPreference=1;` (power saving) or `GpuPreference=2;` (high performance). `None` for
+/// "Let Windows decide" or an exe nothing was recorded for (#399).
+#[cfg(windows)]
+pub fn windows_gpu_preference() -> Option<GpuPreference> {
+    use winreg::RegKey;
+    use winreg::enums::HKEY_CURRENT_USER;
+    let exe = std::env::current_exe().ok()?;
+    let key = RegKey::predef(HKEY_CURRENT_USER).open_subkey(r"Software\Microsoft\DirectX\UserGpuPreferences").ok()?;
+    let value: String = key.get_value(exe.as_os_str()).ok()?;
+    parse_gpu_preference(&value)
+}
+
+/// Reads one `UserGpuPreferences` value: `key=value;` pairs, of which `GpuPreference` counts.
+pub fn parse_gpu_preference(value: &str) -> Option<GpuPreference> {
+    value.split(';').map(str::trim).find_map(|pair| pair.strip_prefix("GpuPreference=")).and_then(|n| match n.trim() {
+        "1" => Some(GpuPreference::PowerSaving),
+        "2" => Some(GpuPreference::HighPerformance),
+        _ => None,
+    })
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn reads_windows_gpu_preference_values() {
+        assert_eq!(parse_gpu_preference("GpuPreference=1;"), Some(GpuPreference::PowerSaving));
+        assert_eq!(parse_gpu_preference("GpuPreference=2;"), Some(GpuPreference::HighPerformance));
+        assert_eq!(parse_gpu_preference("SwapEffectUpgradeEnable=1;GpuPreference=1;"), Some(GpuPreference::PowerSaving));
+        // "Let Windows decide", an unknown number, and nonsense.
+        for value in ["GpuPreference=0;", "GpuPreference=7;", "", "SwapEffectUpgradeEnable=1;", "GpuPreference=", "garbage"] {
+            assert_eq!(parse_gpu_preference(value), None, "{value:?}");
+        }
+    }
+}
diff --git a/crates/native/src/lib.rs b/crates/native/src/lib.rs
--- a/crates/native/src/lib.rs
+++ b/crates/native/src/lib.rs
@@ -11,6 +11,7 @@ pub mod backend;
 pub mod desktop_entry;
 pub mod detect;
 pub mod feed_throttle;
+pub mod graphics;
 pub mod http;
 pub mod install;
 pub mod login;
