Refactor: Simplify codebase and remove unused methods

Removed unused methods across multiple files, including `GetContrastAsync`, `GetVolumeAsync`, and `SaveCurrentSettingsAsync` in `DdcCiController.cs` and `WmiController.cs`. Simplified the `IMonitorController` interface by removing redundant methods.

Replaced `ProcessThemeChangeAsync` with a synchronous `ProcessThemeChange` in `LightSwitchListener.cs`. Changed `ParseVcpCodesToIntegers` visibility to private in `MonitorFeatureHelper.cs` and removed related helper methods.

Eliminated retry logic by removing `ExecuteWithRetryAsync` in `RetryHelper.cs`. Simplified `SetBrightnessAsync` in `MonitorManager.cs` using a generic helper. Streamlined `DisplayName` in `MonitorViewModel.cs` and removed unnecessary property change notifications.

These changes reduce complexity, improve maintainability, and streamline the codebase by removing unused or redundant functionality.
This commit is contained in:
Yu Leng
2025-11-27 22:43:28 +08:00
parent 1c33cf0348
commit 12916deca0
11 changed files with 12 additions and 358 deletions

View File

@@ -143,24 +143,12 @@ namespace PowerDisplay.Common.Drivers.DDC
cancellationToken); cancellationToken);
} }
/// <summary>
/// Get monitor contrast
/// </summary>
public Task<BrightnessInfo> GetContrastAsync(Monitor monitor, CancellationToken cancellationToken = default)
=> GetVcpFeatureAsync(monitor, NativeConstants.VcpCodeContrast, cancellationToken);
/// <summary> /// <summary>
/// Set monitor contrast /// Set monitor contrast
/// </summary> /// </summary>
public Task<MonitorOperationResult> SetContrastAsync(Monitor monitor, int contrast, CancellationToken cancellationToken = default) public Task<MonitorOperationResult> SetContrastAsync(Monitor monitor, int contrast, CancellationToken cancellationToken = default)
=> SetVcpFeatureAsync(monitor, NativeConstants.VcpCodeContrast, contrast, 0, 100, cancellationToken); => SetVcpFeatureAsync(monitor, NativeConstants.VcpCodeContrast, contrast, 0, 100, cancellationToken);
/// <summary>
/// Get monitor volume
/// </summary>
public Task<BrightnessInfo> GetVolumeAsync(Monitor monitor, CancellationToken cancellationToken = default)
=> GetVcpFeatureAsync(monitor, NativeConstants.VcpCodeVolume, cancellationToken);
/// <summary> /// <summary>
/// Set monitor volume /// Set monitor volume
/// </summary> /// </summary>
@@ -441,37 +429,6 @@ namespace PowerDisplay.Common.Drivers.DDC
} }
} }
/// <summary>
/// Save current settings
/// </summary>
public async Task<MonitorOperationResult> SaveCurrentSettingsAsync(Monitor monitor, CancellationToken cancellationToken = default)
{
return await Task.Run(
() =>
{
if (monitor.Handle == IntPtr.Zero)
{
return MonitorOperationResult.Failure("Invalid monitor handle");
}
try
{
if (SaveCurrentSettings(monitor.Handle))
{
return MonitorOperationResult.Success();
}
var lastError = GetLastError();
return MonitorOperationResult.Failure($"Failed to save settings", (int)lastError);
}
catch (Exception ex)
{
return MonitorOperationResult.Failure($"Exception saving settings: {ex.Message}");
}
},
cancellationToken);
}
/// <summary> /// <summary>
/// Discover supported monitors /// Discover supported monitors
/// </summary> /// </summary>
@@ -640,17 +597,6 @@ namespace PowerDisplay.Common.Drivers.DDC
cancellationToken); cancellationToken);
} }
/// <summary>
/// Validate monitor connection status.
/// Uses quick VCP read instead of full capabilities retrieval.
/// </summary>
public async Task<bool> ValidateConnectionAsync(Monitor monitor, CancellationToken cancellationToken = default)
{
return await Task.Run(
() => monitor.Handle != IntPtr.Zero && DdcCiNative.QuickConnectionCheck(monitor.Handle),
cancellationToken);
}
/// <summary> /// <summary>
/// Get physical monitors with retry logic to handle Windows API occasionally returning NULL handles /// Get physical monitors with retry logic to handle Windows API occasionally returning NULL handles
/// </summary> /// </summary>

View File

@@ -264,31 +264,6 @@ namespace PowerDisplay.Common.Drivers.WMI
cancellationToken); cancellationToken);
} }
/// <summary>
/// Validate monitor connection status
/// </summary>
public async Task<bool> ValidateConnectionAsync(Monitor monitor, CancellationToken cancellationToken = default)
{
return await Task.Run(
() =>
{
try
{
// Try to read current brightness to validate connection
using var connection = new WmiConnection(WmiNamespace);
var query = $"SELECT CurrentBrightness FROM {BrightnessQueryClass} WHERE InstanceName='{monitor.InstanceName}'";
var results = connection.CreateQuery(query).ToList();
return results.Count > 0;
}
catch (Exception ex)
{
Logger.LogWarning($"WMI ValidateConnection failed for {monitor.InstanceName}: {ex.Message}");
return false;
}
},
cancellationToken);
}
/// <summary> /// <summary>
/// Get user-friendly name from WMI object /// Get user-friendly name from WMI object
/// </summary> /// </summary>
@@ -348,69 +323,12 @@ namespace PowerDisplay.Common.Drivers.WMI
} }
} }
/// <summary>
/// Check if administrator privileges are required
/// </summary>
public static bool RequiresElevation()
{
try
{
using var connection = new WmiConnection(WmiNamespace);
var query = $"SELECT * FROM {BrightnessMethodClass}";
var results = connection.CreateQuery(query).ToList();
foreach (var obj in results)
{
// Try to call method to check permissions
try
{
using (WmiMethod method = obj.GetMethod("WmiSetBrightness"))
using (WmiMethodParameters inParams = method.CreateInParameters())
{
inParams.SetPropertyValue("Timeout", "0");
inParams.SetPropertyValue("Brightness", "50");
obj.ExecuteMethod<uint>(method, inParams, out WmiMethodParameters outParams);
return false; // If successful, no elevation required
}
}
catch (UnauthorizedAccessException)
{
return true; // Administrator privileges required
}
catch (Exception ex)
{
// Other errors may not be permission issues
Logger.LogDebug($"WMI RequiresElevation check error: {ex.Message}");
return false;
}
}
}
catch (Exception ex)
{
// Cannot determine, assume privileges required
Logger.LogWarning($"WMI RequiresElevation check failed: {ex.Message}");
return true;
}
return false;
}
// Extended features not supported by WMI // Extended features not supported by WMI
public Task<BrightnessInfo> GetContrastAsync(Monitor monitor, CancellationToken cancellationToken = default)
{
return Task.FromResult(BrightnessInfo.Invalid);
}
public Task<MonitorOperationResult> SetContrastAsync(Monitor monitor, int contrast, CancellationToken cancellationToken = default) public Task<MonitorOperationResult> SetContrastAsync(Monitor monitor, int contrast, CancellationToken cancellationToken = default)
{ {
return Task.FromResult(MonitorOperationResult.Failure("Contrast control not supported via WMI")); return Task.FromResult(MonitorOperationResult.Failure("Contrast control not supported via WMI"));
} }
public Task<BrightnessInfo> GetVolumeAsync(Monitor monitor, CancellationToken cancellationToken = default)
{
return Task.FromResult(BrightnessInfo.Invalid);
}
public Task<MonitorOperationResult> SetVolumeAsync(Monitor monitor, int volume, CancellationToken cancellationToken = default) public Task<MonitorOperationResult> SetVolumeAsync(Monitor monitor, int volume, CancellationToken cancellationToken = default)
{ {
return Task.FromResult(MonitorOperationResult.Failure("Volume control not supported via WMI")); return Task.FromResult(MonitorOperationResult.Failure("Volume control not supported via WMI"));
@@ -443,11 +361,6 @@ namespace PowerDisplay.Common.Drivers.WMI
return Task.FromResult(string.Empty); return Task.FromResult(string.Empty);
} }
public Task<MonitorOperationResult> SaveCurrentSettingsAsync(Monitor monitor, CancellationToken cancellationToken = default)
{
return Task.FromResult(MonitorOperationResult.Failure("Save settings not supported via WMI"));
}
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);

View File

@@ -53,22 +53,6 @@ namespace PowerDisplay.Common.Interfaces
/// <returns>List of monitors</returns> /// <returns>List of monitors</returns>
Task<IEnumerable<Monitor>> DiscoverMonitorsAsync(CancellationToken cancellationToken = default); Task<IEnumerable<Monitor>> DiscoverMonitorsAsync(CancellationToken cancellationToken = default);
/// <summary>
/// Validates monitor connection status
/// </summary>
/// <param name="monitor">Monitor object</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Whether the monitor is connected</returns>
Task<bool> ValidateConnectionAsync(Monitor monitor, CancellationToken cancellationToken = default);
/// <summary>
/// Gets monitor contrast
/// </summary>
/// <param name="monitor">Monitor object</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Contrast information</returns>
Task<BrightnessInfo> GetContrastAsync(Monitor monitor, CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// Sets monitor contrast /// Sets monitor contrast
/// </summary> /// </summary>
@@ -78,14 +62,6 @@ namespace PowerDisplay.Common.Interfaces
/// <returns>Operation result</returns> /// <returns>Operation result</returns>
Task<MonitorOperationResult> SetContrastAsync(Monitor monitor, int contrast, CancellationToken cancellationToken = default); Task<MonitorOperationResult> SetContrastAsync(Monitor monitor, int contrast, CancellationToken cancellationToken = default);
/// <summary>
/// Gets monitor volume
/// </summary>
/// <param name="monitor">Monitor object</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Volume information</returns>
Task<BrightnessInfo> GetVolumeAsync(Monitor monitor, CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// Sets monitor volume /// Sets monitor volume
/// </summary> /// </summary>
@@ -137,14 +113,6 @@ namespace PowerDisplay.Common.Interfaces
/// <returns>Capabilities string</returns> /// <returns>Capabilities string</returns>
Task<string> GetCapabilitiesStringAsync(Monitor monitor, CancellationToken cancellationToken = default); Task<string> GetCapabilitiesStringAsync(Monitor monitor, CancellationToken cancellationToken = default);
/// <summary>
/// Saves current settings to monitor
/// </summary>
/// <param name="monitor">Monitor object</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Operation result</returns>
Task<MonitorOperationResult> SaveCurrentSettingsAsync(Monitor monitor, CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// Releases resources /// Releases resources
/// </summary> /// </summary>

View File

@@ -106,7 +106,7 @@ namespace PowerDisplay.Common.Services
Logger.LogInfo($"{LogPrefix} Theme change event received"); Logger.LogInfo($"{LogPrefix} Theme change event received");
// Process the theme change // Process the theme change
_ = Task.Run(() => ProcessThemeChangeAsync(), CancellationToken.None); _ = Task.Run(() => ProcessThemeChange(), CancellationToken.None);
} }
} }
@@ -118,7 +118,7 @@ namespace PowerDisplay.Common.Services
} }
} }
private async Task ProcessThemeChangeAsync() private void ProcessThemeChange()
{ {
try try
{ {
@@ -149,8 +149,6 @@ namespace PowerDisplay.Common.Services
{ {
Logger.LogError($"{LogPrefix} Failed to process theme change: {ex.Message}"); Logger.LogError($"{LogPrefix} Failed to process theme change: {ex.Message}");
} }
await Task.CompletedTask;
} }
/// <summary> /// <summary>

View File

@@ -5,7 +5,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using ManagedCommon;
using PowerDisplay.Common.Drivers; using PowerDisplay.Common.Drivers;
namespace PowerDisplay.Common.Utils namespace PowerDisplay.Common.Utils
@@ -74,7 +73,7 @@ namespace PowerDisplay.Common.Utils
/// Parse VCP codes from string list to integer set /// Parse VCP codes from string list to integer set
/// Handles both hex formats: "0x10" and "10" /// Handles both hex formats: "0x10" and "10"
/// </summary> /// </summary>
public static HashSet<int> ParseVcpCodesToIntegers(IReadOnlyList<string>? vcpCodes) private static HashSet<int> ParseVcpCodesToIntegers(IReadOnlyList<string>? vcpCodes)
{ {
var result = new HashSet<int>(); var result = new HashSet<int>();
@@ -105,22 +104,5 @@ namespace PowerDisplay.Common.Utils
return result; return result;
} }
/// <summary>
/// Check if a specific VCP code is supported
/// </summary>
public static bool SupportsVcpCode(IReadOnlyList<string>? vcpCodes, int vcpCode)
{
var parsed = ParseVcpCodesToIntegers(vcpCodes);
return parsed.Contains(vcpCode);
}
/// <summary>
/// Format VCP code for display (e.g., 0x10 -> "0x10")
/// </summary>
public static string FormatVcpCode(int vcpCode)
{
return $"0x{vcpCode:X2}";
}
} }
} }

View File

@@ -4,7 +4,6 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using ManagedCommon; using ManagedCommon;
namespace PowerDisplay.Common.Utils namespace PowerDisplay.Common.Utils
@@ -25,86 +24,6 @@ namespace PowerDisplay.Common.Utils
/// </summary> /// </summary>
public const int DefaultMaxRetries = 3; public const int DefaultMaxRetries = 3;
/// <summary>
/// Executes an async operation with retry logic.
/// </summary>
/// <typeparam name="T">The return type of the operation.</typeparam>
/// <param name="operation">The async operation to execute.</param>
/// <param name="isValid">Predicate to determine if the result is valid.</param>
/// <param name="maxRetries">Maximum number of retry attempts (default: 3).</param>
/// <param name="delayMs">Delay between retries in milliseconds (default: 100).</param>
/// <param name="operationName">Optional name for logging purposes.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>The result of the operation, or default if all retries failed.</returns>
public static async Task<T?> ExecuteWithRetryAsync<T>(
Func<Task<T?>> operation,
Func<T?, bool> isValid,
int maxRetries = DefaultMaxRetries,
int delayMs = DefaultRetryDelayMs,
string? operationName = null,
CancellationToken cancellationToken = default)
{
for (int attempt = 0; attempt < maxRetries; attempt++)
{
cancellationToken.ThrowIfCancellationRequested();
try
{
var result = await operation();
if (isValid(result))
{
if (attempt > 0 && !string.IsNullOrEmpty(operationName))
{
Logger.LogDebug($"[Retry] {operationName} succeeded on attempt {attempt + 1}");
}
return result;
}
if (attempt < maxRetries - 1)
{
if (!string.IsNullOrEmpty(operationName))
{
Logger.LogWarning($"[Retry] {operationName} returned invalid result on attempt {attempt + 1}, retrying...");
}
await Task.Delay(delayMs, cancellationToken);
}
}
catch (OperationCanceledException)
{
throw;
}
catch (Exception ex)
{
if (attempt < maxRetries - 1)
{
if (!string.IsNullOrEmpty(operationName))
{
Logger.LogWarning($"[Retry] {operationName} failed on attempt {attempt + 1}: {ex.Message}, retrying...");
}
await Task.Delay(delayMs, cancellationToken);
}
else
{
if (!string.IsNullOrEmpty(operationName))
{
Logger.LogWarning($"[Retry] {operationName} failed after {maxRetries} attempts: {ex.Message}");
}
}
}
}
if (!string.IsNullOrEmpty(operationName))
{
Logger.LogWarning($"[Retry] {operationName} failed after {maxRetries} attempts");
}
return default;
}
/// <summary> /// <summary>
/// Executes a synchronous operation with retry logic. /// Executes a synchronous operation with retry logic.
/// </summary> /// </summary>

View File

@@ -225,15 +225,5 @@ namespace PowerDisplay.Common.Utils
{ {
return CodeNames.TryGetValue(code, out var name) ? name : $"Unknown (0x{code:X2})"; return CodeNames.TryGetValue(code, out var name) ? name : $"Unknown (0x{code:X2})";
} }
/// <summary>
/// Check if a VCP code has a known name
/// </summary>
public static bool HasName(byte code) => CodeNames.ContainsKey(code);
/// <summary>
/// Get all known VCP codes
/// </summary>
public static IEnumerable<byte> GetAllKnownCodes() => CodeNames.Keys;
} }
} }

View File

@@ -188,12 +188,5 @@ namespace PowerDisplay.Common.Utils
return $"0x{value:X2}"; return $"0x{value:X2}";
} }
/// <summary>
/// Check if a VCP code has value name mappings
/// </summary>
/// <param name="vcpCode">VCP code to check</param>
/// <returns>True if value names are available</returns>
public static bool HasValueNames(byte vcpCode) => ValueNames.ContainsKey(vcpCode);
} }
} }

View File

@@ -53,8 +53,6 @@ namespace PowerDisplay.Commands
Logger.LogError($"Command execution failed: {ex.Message}"); Logger.LogError($"Command execution failed: {ex.Message}");
} }
} }
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
} }
/// <summary> /// <summary>
@@ -103,7 +101,5 @@ namespace PowerDisplay.Commands
Logger.LogError($"Command<T> execution failed: {ex.Message}"); Logger.LogError($"Command<T> execution failed: {ex.Message}");
} }
} }
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
} }
} }

View File

@@ -356,45 +356,13 @@ namespace PowerDisplay.Core
/// <summary> /// <summary>
/// Set brightness of the specified monitor /// Set brightness of the specified monitor
/// </summary> /// </summary>
public async Task<MonitorOperationResult> SetBrightnessAsync(string monitorId, int brightness, CancellationToken cancellationToken = default) public Task<MonitorOperationResult> SetBrightnessAsync(string monitorId, int brightness, CancellationToken cancellationToken = default)
{ => ExecuteMonitorOperationAsync(
var monitor = GetMonitor(monitorId); monitorId,
if (monitor == null) brightness,
{ (ctrl, mon, val, ct) => ctrl.SetBrightnessAsync(mon, val, ct),
Logger.LogError($"Monitor not found: {monitorId}"); (mon, val) => mon.UpdateStatus(val, true),
return MonitorOperationResult.Failure("Monitor not found"); cancellationToken);
}
var controller = await GetControllerForMonitorAsync(monitor, cancellationToken);
if (controller == null)
{
Logger.LogError($"No controller available for monitor {monitorId}");
return MonitorOperationResult.Failure("No controller available for this monitor");
}
try
{
var result = await controller.SetBrightnessAsync(monitor, brightness, cancellationToken);
if (result.IsSuccess)
{
// Update monitor status
monitor.UpdateStatus(brightness, true);
}
else
{
// If setting fails, monitor may be unavailable
monitor.IsAvailable = false;
}
return result;
}
catch (Exception ex)
{
monitor.IsAvailable = false;
return MonitorOperationResult.Failure($"Exception setting brightness: {ex.Message}");
}
}
/// <summary> /// <summary>
/// Set brightness of all monitors /// Set brightness of all monitors

View File

@@ -275,22 +275,9 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable
public int MonitorNumber => _monitor.MonitorNumber; public int MonitorNumber => _monitor.MonitorNumber;
/// <summary> /// <summary>
/// Gets the display name - includes monitor number when multiple monitors are visible /// Gets the display name
/// </summary> /// </summary>
public string DisplayName public string DisplayName => Name;
{
get
{
// Check if there's more than one visible monitor and MonitorNumber is valid
// Set the limit to zero for debugging.
/* if (_mainViewModel != null && _mainViewModel.Monitors.Count > 0 && MonitorNumber > 0)
{
return $"{Name} {MonitorNumber}";
} */
return Name;
}
}
public string Manufacturer => _monitor.Manufacturer; public string Manufacturer => _monitor.Manufacturer;
@@ -573,12 +560,6 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// Notify percentage properties when actual values change
if (propertyName == nameof(Contrast))
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ContrastPercent)));
}
} }
private void OnMainViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e) private void OnMainViewModelPropertyChanged(object? sender, PropertyChangedEventArgs e)