Skip to content

Commit

Permalink
set display ddc brightness on seperate thread
Browse files Browse the repository at this point in the history
  • Loading branch information
tombayley committed Aug 28, 2024
1 parent 18b6be7 commit 43c7ff5
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 15 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore

Installer/Source/

# User-specific files
*.rsuser
*.suo
Expand Down
72 changes: 57 additions & 15 deletions NightGlow.MonitorConfig/PhysicalMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ public class PhysicalMonitor
private readonly Setting Brightness = new();
private readonly Setting Contrast = new();

// Brightness
private CancellationTokenSource _cancelTokenB = new CancellationTokenSource();
private readonly object _lockB = new object();

// Contrast
private CancellationTokenSource _cancelTokenC = new CancellationTokenSource();
private readonly object _lockC = new object();

public PhysicalMonitor(PHYSICAL_MONITOR monitor)
{
Monitor = monitor;
Expand All @@ -32,9 +40,15 @@ public Setting GetBrightness()

public void SetBrightness(uint value)
{
bool success = RetrySet(SetMonitorBrightness, GetBrightness, Monitor.hPhysicalMonitor, value);
if (success)
Brightness.Current = value;
lock (_lockB)
{
_cancelTokenB.Cancel();
_cancelTokenB.Dispose();
_cancelTokenB = new CancellationTokenSource();
var cancelToken = _cancelTokenB.Token;

Task.Run(() => RetrySet(SetMonitorBrightness, GetBrightness, Monitor.hPhysicalMonitor, value, Brightness, cancelToken), cancelToken);
}
}

public Setting GetContrast()
Expand All @@ -47,22 +61,50 @@ public Setting GetContrast()

public void SetContrast(uint value)
{
bool success = RetrySet(SetMonitorContrast, GetContrast, Monitor.hPhysicalMonitor, value);
if (success)
Contrast.Current = value;
lock (_lockC)
{
_cancelTokenC.Cancel();
_cancelTokenC.Dispose();
_cancelTokenC = new CancellationTokenSource();
var cancelToken = _cancelTokenC.Token;

Task.Run(() => RetrySet(SetMonitorContrast, GetContrast, Monitor.hPhysicalMonitor, value, Contrast, cancelToken), cancelToken);
}
}

private bool RetrySet(Func<nint, uint, bool> setFunction, Func<Setting> getFunction, nint monitor, uint value)
{
for (int attempt = 1; attempt <= DDC_ATTEMPTS; attempt++)
private static void RetrySet(
Func<nint, uint, bool> setFunction,
Func<Setting> getFunction,
nint monitor,
uint value,
Setting setting,
CancellationToken cancelToken
) {
try
{
// Sometimes setting a monitor value (e.g. brightness) will report as success,
// but monitor does not change brightness.
// Confirm value has been set by getting current value after doing the set.
if (setFunction(monitor, value) && getFunction().Current == value)
return true;
for (int attempt = 1; attempt <= DDC_ATTEMPTS; attempt++)
{
// Check for cancellation before attempting the operation
cancelToken.ThrowIfCancellationRequested();

// Sometimes setting a monitor value (e.g. brightness) will report as success,
// but monitor does not change brightness.
// Confirm value has been set by getting current value after doing the set.
if (setFunction(monitor, value) && getFunction().Current == value)
{
setting.Current = value;
return;
}
}
}
catch (TaskCanceledException)
{
Debug.WriteLine("Operation cancelled.");
}
catch (Exception ex)
{
Debug.WriteLine($"An error occurred: {ex.Message}");
}
return false;
}

private bool RetryGet(Func<nint, bool> getFunction, nint monitor)
Expand Down

0 comments on commit 43c7ff5

Please sign in to comment.