Skip to content

Commit 9316103

Browse files
committed
feat: log pause/resume events to changes.log with reason + foreground process
1 parent 901b64c commit 9316103

4 files changed

Lines changed: 71 additions & 4 deletions

File tree

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ Fields:
254254
| Field | Meaning |
255255
|---|---|
256256
| **timestamp** | Local time of the apply |
257-
| **source** | `manual` (you clicked Apply) or `auto` (silent auto-apply during a poll tick) |
257+
| **source** | `manual` (you clicked Apply) · `auto` (silent auto-apply during a poll tick) · `ui` (preference toggle in Settings) · `pause` (polling paused/resumed for fullscreen, benchmark, or manual pause) |
258258
| **STATUS** | `OK` if the after-read matched the target; `FAILED` otherwise (UAC declined, registry locked, etc.) |
259259
| **Mechanism** | The exact registry path + value type, or the Win32 / DLL function called for non-registry settings |
260260
| **Before** | The raw bytes / number / string GamerGuardian read before the write, plus a parenthesized friendly description |
@@ -290,6 +290,20 @@ A silent auto-apply that fixed Game Mode after a Windows update reset it:
290290
Verify : (Get-ItemProperty 'HKCU:\Software\Microsoft\GameBar' -Name AutoGameModeEnabled).AutoGameModeEnabled
291291
```
292292

293+
A pause / resume cycle while a fullscreen game runs:
294+
295+
```
296+
[2026-05-06 19:42:01] [pause ] PAUSED fullscreen (Cyberpunk2077)
297+
[2026-05-06 21:18:14] [pause ] RESUMED was: fullscreen (Cyberpunk2077)
298+
```
299+
300+
A preference toggle in the Settings UI:
301+
302+
```
303+
[2026-05-06 22:42:15] [ui ] PREF Fullscreen optimizations (global) | Monitor: False -> True
304+
[2026-05-06 22:42:16] [ui ] PREF Fullscreen optimizations (global) | AutoApply: False -> True
305+
```
306+
293307
A failed Apply where the user cancelled the UAC prompt:
294308

295309
```

src/GamerGuardian/Native/Shell32.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ public static bool IsFullscreenAppActive()
6666
return IsForegroundBorderlessFullscreen();
6767
}
6868

69+
public static string? GetForegroundProcessName()
70+
{
71+
try
72+
{
73+
var hwnd = GetForegroundWindow();
74+
if (hwnd == IntPtr.Zero) return null;
75+
GetWindowThreadProcessId(hwnd, out var pid);
76+
if (pid == 0) return null;
77+
using var p = System.Diagnostics.Process.GetProcessById((int)pid);
78+
return p.ProcessName;
79+
}
80+
catch { return null; }
81+
}
82+
6983
private static bool IsForegroundBorderlessFullscreen()
7084
{
7185
try

src/GamerGuardian/Services/ChangeLogger.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,22 @@ public static void LogPreferenceChange(string settingName, string field, string
5454
catch { }
5555
}
5656

57+
/// <summary>
58+
/// Records the start or end of a polling pause (fullscreen / benchmark / user).
59+
/// </summary>
60+
public static void LogPauseEvent(string action, string reason)
61+
{
62+
try
63+
{
64+
var dir = Path.GetDirectoryName(LogPath);
65+
if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir);
66+
RotateIfNeeded();
67+
var line = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] [pause ] {action,-7} {reason}";
68+
File.AppendAllText(LogPath, line + Environment.NewLine, Encoding.UTF8);
69+
}
70+
catch { }
71+
}
72+
5773
private static string Format(ApplyResult r, string source)
5874
{
5975
var status = r.Verified ? "OK" : "FAILED";

src/GamerGuardian/Services/MonitorService.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public sealed class MonitorService : IDisposable
1414
private bool _running;
1515
private int _ticksSinceTrim;
1616
private bool _userPaused;
17+
private string? _activePauseReason;
1718

1819
public bool IsUserPaused => _userPaused;
1920
public event Action<bool>? PauseChanged;
@@ -63,9 +64,31 @@ private async Task TickAsync()
6364
}
6465
try
6566
{
66-
if (_userPaused) return;
67-
if (Shell32.IsFullscreenAppActive()) return;
68-
if (BenchmarkDetector.GetRunningBenchmark() is not null) return;
67+
string? pauseReason = null;
68+
if (_userPaused)
69+
{
70+
pauseReason = "user (manual pause via tray)";
71+
}
72+
else if (Shell32.IsFullscreenAppActive())
73+
{
74+
var fg = Shell32.GetForegroundProcessName();
75+
pauseReason = string.IsNullOrEmpty(fg) ? "fullscreen" : $"fullscreen ({fg})";
76+
}
77+
else if (BenchmarkDetector.GetRunningBenchmark() is { } bench)
78+
{
79+
pauseReason = $"benchmark ({bench})";
80+
}
81+
82+
if (pauseReason != _activePauseReason)
83+
{
84+
if (pauseReason != null)
85+
ChangeLogger.LogPauseEvent("PAUSED", pauseReason);
86+
else if (_activePauseReason != null)
87+
ChangeLogger.LogPauseEvent("RESUMED", $"was: {_activePauseReason}");
88+
_activePauseReason = pauseReason;
89+
}
90+
91+
if (pauseReason != null) return;
6992

7093
var config = _store.Load();
7194
var drifted = new List<DriftItem>();

0 commit comments

Comments
 (0)