|
1 | 1 | using GamerGuardian.Models; |
| 2 | +using GamerGuardian.Services; |
2 | 3 | using Microsoft.Win32; |
3 | 4 |
|
4 | 5 | namespace GamerGuardian.Monitors; |
5 | 6 |
|
6 | 7 | public sealed class VrrMonitor : IMonitoredSetting |
7 | 8 | { |
8 | 9 | public string Id => "vrr"; |
9 | | - private const string SubKey = @"Software\Microsoft\DirectX\UserGpuPreferences"; |
10 | | - private const string ValueName = "DirectXUserGlobalSettings"; |
11 | | - private const string Key = "VRROptimizeEnable"; |
| 10 | + private const string SubKey = @"SYSTEM\CurrentControlSet\Control\GraphicsDrivers"; |
| 11 | + private const string ValueName = "VRROptimizeEnable"; |
12 | 12 |
|
13 | 13 | public IEnumerable<DriftItem> CheckDrift(AppConfig config) |
14 | 14 | { |
15 | 15 | var pref = config.Global.Vrr; |
16 | 16 |
|
17 | | - var current = ReadCurrent(); |
18 | | - if (current is null) yield break; |
19 | | - if (current.Value == pref.DesiredOn) yield break; |
| 17 | + using var k = Registry.LocalMachine.OpenSubKey(SubKey, writable: false); |
| 18 | + if (k?.GetValue(ValueName) is not int rawValue) yield break; |
| 19 | + var current = rawValue != 0; |
| 20 | + if (current == pref.DesiredOn) yield break; |
20 | 21 |
|
21 | 22 | bool desired = pref.DesiredOn; |
| 23 | + uint desiredRaw = desired ? 1u : 0u; |
22 | 24 | yield return new DriftItem( |
23 | 25 | SettingId: Id, |
24 | 26 | DisplayKey: "global", |
25 | 27 | DisplayLabel: "Global", |
26 | | - Description: "Variable Refresh Rate (Windows)", |
27 | | - CurrentValue: current.Value ? "On" : "Off", |
| 28 | + Description: "Variable Refresh Rate (DirectX)", |
| 29 | + CurrentValue: current ? "On" : "Off", |
28 | 30 | DesiredValue: desired ? "On" : "Off", |
29 | 31 | AutoApply: pref.AutoApply, |
30 | | - Apply: () => Task.Run(() => Apply(desired)), |
| 32 | + Apply: () => Task.Run(() => ElevatedRegistry.SetHklmDword(SubKey, ValueName, desiredRaw)), |
31 | 33 | IsMonitored: pref.Monitor, |
32 | | - RawBefore: $"VRROptimizeEnable={(current.Value ? "1" : "0")}", |
33 | | - RawDesired: $"VRROptimizeEnable={(desired ? "1" : "0")}"); |
| 34 | + RawBefore: rawValue.ToString(), |
| 35 | + RawDesired: desiredRaw.ToString()); |
34 | 36 | } |
35 | 37 |
|
36 | 38 | public static bool? ReadCurrent() |
37 | 39 | { |
38 | | - using var k = Registry.CurrentUser.OpenSubKey(SubKey, writable: false); |
39 | | - var raw = k?.GetValue(ValueName) as string; |
40 | | - if (string.IsNullOrEmpty(raw)) return null; |
41 | | - var pairs = ParsePairs(raw); |
42 | | - if (!pairs.TryGetValue(Key, out var v)) return null; |
43 | | - return v == "1"; |
44 | | - } |
45 | | - |
46 | | - public static void Apply(bool on) |
47 | | - { |
48 | | - using var k = Registry.CurrentUser.CreateSubKey(SubKey, writable: true)!; |
49 | | - var raw = (k.GetValue(ValueName) as string) ?? string.Empty; |
50 | | - var pairs = ParsePairs(raw); |
51 | | - pairs[Key] = on ? "1" : "0"; |
52 | | - k.SetValue(ValueName, BuildPairs(pairs), RegistryValueKind.String); |
53 | | - } |
54 | | - |
55 | | - private static Dictionary<string, string> ParsePairs(string raw) |
56 | | - { |
57 | | - var d = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); |
58 | | - foreach (var part in raw.Split(';', StringSplitOptions.RemoveEmptyEntries)) |
59 | | - { |
60 | | - var idx = part.IndexOf('='); |
61 | | - if (idx <= 0) continue; |
62 | | - d[part[..idx]] = part[(idx + 1)..]; |
63 | | - } |
64 | | - return d; |
65 | | - } |
66 | | - |
67 | | - private static string BuildPairs(Dictionary<string, string> pairs) |
68 | | - { |
69 | | - var sb = new System.Text.StringBuilder(); |
70 | | - foreach (var kv in pairs) |
71 | | - sb.Append(kv.Key).Append('=').Append(kv.Value).Append(';'); |
72 | | - return sb.ToString(); |
| 40 | + using var k = Registry.LocalMachine.OpenSubKey(SubKey, writable: false); |
| 41 | + if (k?.GetValue(ValueName) is int v) return v != 0; |
| 42 | + return null; |
73 | 43 | } |
74 | 44 | } |
0 commit comments