mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
Refactor MonitorStateManager and MainViewModel to use HardwareId for stable identification; update logging for clarity and consistency.
This commit is contained in:
@@ -71,6 +71,8 @@ namespace PowerDisplay.Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Serializable state for JSON persistence
|
||||
/// Dictionary key should be HardwareId (e.g., "GSM5C6D") for stable identification
|
||||
/// Legacy files may have used InternalName (e.g., "DISPLAY1_0_3") which will still load but won't match after reconnection
|
||||
/// </summary>
|
||||
private sealed class MonitorStateFile
|
||||
{
|
||||
@@ -116,13 +118,20 @@ namespace PowerDisplay.Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Update monitor parameter in memory (lock-free, non-blocking)
|
||||
/// Uses HardwareId as the stable key
|
||||
/// </summary>
|
||||
public void UpdateMonitorParameter(string monitorId, string property, int value)
|
||||
public void UpdateMonitorParameter(string hardwareId, string property, int value)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get or create parameter entry
|
||||
var parameters = _parameters.GetOrAdd(monitorId, _ => new MonitorParameters());
|
||||
if (string.IsNullOrEmpty(hardwareId))
|
||||
{
|
||||
Logger.LogWarning($"Cannot update monitor parameter: HardwareId is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get or create parameter entry using HardwareId
|
||||
var parameters = _parameters.GetOrAdd(hardwareId, _ => new MonitorParameters());
|
||||
|
||||
// Update the specific property (volatile write)
|
||||
switch (property)
|
||||
@@ -147,7 +156,7 @@ namespace PowerDisplay.Helpers
|
||||
// Mark as dirty (will be saved in next timer cycle)
|
||||
_isDirty = true;
|
||||
|
||||
Logger.LogTrace($"[State] Updated {property}={value} for monitor '{monitorId}'");
|
||||
Logger.LogTrace($"[State] Updated {property}={value} for monitor HardwareId='{hardwareId}'");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -156,11 +165,16 @@ namespace PowerDisplay.Helpers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get saved parameters for a monitor
|
||||
/// Get saved parameters for a monitor using HardwareId
|
||||
/// </summary>
|
||||
public (int Brightness, int ColorTemperature, int Contrast, int Volume)? GetMonitorParameters(string monitorId)
|
||||
public (int Brightness, int ColorTemperature, int Contrast, int Volume)? GetMonitorParameters(string hardwareId)
|
||||
{
|
||||
if (_parameters.TryGetValue(monitorId, out var parameters))
|
||||
if (string.IsNullOrEmpty(hardwareId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_parameters.TryGetValue(hardwareId, out var parameters))
|
||||
{
|
||||
return (parameters.Brightness, parameters.ColorTemperature, parameters.Contrast, parameters.Volume);
|
||||
}
|
||||
@@ -168,11 +182,11 @@ namespace PowerDisplay.Helpers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if state exists for a monitor
|
||||
/// Check if state exists for a monitor (by HardwareId)
|
||||
/// </summary>
|
||||
public bool HasMonitorState(string monitorId)
|
||||
public bool HasMonitorState(string hardwareId)
|
||||
{
|
||||
return _parameters.ContainsKey(monitorId);
|
||||
return !string.IsNullOrEmpty(hardwareId) && _parameters.ContainsKey(hardwareId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -195,10 +209,10 @@ namespace PowerDisplay.Helpers
|
||||
{
|
||||
foreach (var kvp in state.Monitors)
|
||||
{
|
||||
var monitorId = kvp.Key;
|
||||
var monitorKey = kvp.Key; // Should be HardwareId (e.g., "GSM5C6D")
|
||||
var entry = kvp.Value;
|
||||
|
||||
var parameters = _parameters.GetOrAdd(monitorId, _ => new MonitorParameters());
|
||||
var parameters = _parameters.GetOrAdd(monitorKey, _ => new MonitorParameters());
|
||||
parameters.Brightness = entry.Brightness;
|
||||
parameters.ColorTemperature = entry.ColorTemperature;
|
||||
parameters.Contrast = entry.Contrast;
|
||||
@@ -206,6 +220,7 @@ namespace PowerDisplay.Helpers
|
||||
}
|
||||
|
||||
Logger.LogInfo($"[State] Loaded state for {state.Monitors.Count} monitors from {_stateFilePath}");
|
||||
Logger.LogInfo($"[State] Monitor keys in state file: {string.Join(", ", state.Monitors.Keys)}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -487,14 +487,14 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
|
||||
foreach (var monitorVm in Monitors)
|
||||
{
|
||||
var internalName = GetInternalName(monitorVm);
|
||||
Logger.LogInfo($"[Startup] Processing monitor: '{monitorVm.Name}', InternalName: '{internalName}'");
|
||||
var hardwareId = monitorVm.HardwareId;
|
||||
Logger.LogInfo($"[Startup] Processing monitor: '{monitorVm.Name}', HardwareId: '{hardwareId}'");
|
||||
|
||||
// Find and apply corresponding saved settings from state file
|
||||
var savedState = _stateManager.GetMonitorParameters(internalName);
|
||||
// Find and apply corresponding saved settings from state file using stable HardwareId
|
||||
var savedState = _stateManager.GetMonitorParameters(hardwareId);
|
||||
if (savedState.HasValue)
|
||||
{
|
||||
Logger.LogInfo($"[Startup] Restoring state for '{internalName}': Brightness={savedState.Value.Brightness}, ColorTemp={savedState.Value.ColorTemperature}");
|
||||
Logger.LogInfo($"[Startup] Restoring state for HardwareId '{hardwareId}': Brightness={savedState.Value.Brightness}, ColorTemp={savedState.Value.ColorTemperature}");
|
||||
|
||||
// 验证并应用保存的值(跳过无效值)
|
||||
if (savedState.Value.Brightness >= monitorVm.MinBrightness && savedState.Value.Brightness <= monitorVm.MaxBrightness)
|
||||
@@ -503,7 +503,7 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning($"[Startup] Invalid brightness value {savedState.Value.Brightness} for '{internalName}', skipping");
|
||||
Logger.LogWarning($"[Startup] Invalid brightness value {savedState.Value.Brightness} for HardwareId '{hardwareId}', skipping");
|
||||
}
|
||||
|
||||
// 色温值必须有效且在范围内
|
||||
@@ -515,7 +515,7 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning($"[Startup] Invalid color temperature value {savedState.Value.ColorTemperature} for '{internalName}', skipping");
|
||||
Logger.LogWarning($"[Startup] Invalid color temperature value {savedState.Value.ColorTemperature} for HardwareId '{hardwareId}', skipping");
|
||||
}
|
||||
|
||||
// 对比度值验证 - 只在硬件支持的情况下才应用
|
||||
@@ -527,7 +527,7 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
}
|
||||
else if (!monitorVm.ShowContrast)
|
||||
{
|
||||
Logger.LogInfo($"[Startup] Contrast not supported on '{internalName}', skipping");
|
||||
Logger.LogInfo($"[Startup] Contrast not supported on HardwareId '{hardwareId}', skipping");
|
||||
}
|
||||
|
||||
// 音量值验证 - 只在硬件支持的情况下才应用
|
||||
@@ -539,15 +539,16 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
}
|
||||
else if (!monitorVm.ShowVolume)
|
||||
{
|
||||
Logger.LogInfo($"[Startup] Volume not supported on '{internalName}', skipping");
|
||||
Logger.LogInfo($"[Startup] Volume not supported on HardwareId '{hardwareId}', skipping");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogInfo($"[Startup] No saved state for '{internalName}' - keeping current hardware values");
|
||||
Logger.LogInfo($"[Startup] No saved state for HardwareId '{hardwareId}' - keeping current hardware values");
|
||||
}
|
||||
|
||||
// Apply feature visibility settings
|
||||
// Apply feature visibility settings (still need InternalName for Settings UI matching)
|
||||
var internalName = GetInternalName(monitorVm);
|
||||
ApplyFeatureVisibility(monitorVm, settings, internalName);
|
||||
}
|
||||
|
||||
@@ -634,7 +635,7 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
// Find the monitor VM to get the converted internal name
|
||||
// Find the monitor VM to get the stable HardwareId
|
||||
var monitorVm = GetMonitorViewModel(monitorId);
|
||||
if (monitorVm == null)
|
||||
{
|
||||
@@ -642,13 +643,13 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
return;
|
||||
}
|
||||
|
||||
// Use converted internal name for consistency with Settings UI
|
||||
var internalName = GetInternalName(monitorVm);
|
||||
// Use stable HardwareId as the key for state persistence
|
||||
var hardwareId = monitorVm.HardwareId;
|
||||
|
||||
// Update parameter in state file (lock-free, non-blocking)
|
||||
_stateManager.UpdateMonitorParameter(internalName, property, value);
|
||||
_stateManager.UpdateMonitorParameter(hardwareId, property, value);
|
||||
|
||||
Logger.LogTrace($"[State] Queued setting change for '{internalName}': {property}={value}");
|
||||
Logger.LogTrace($"[State] Queued setting change for HardwareId '{hardwareId}': {property}={value}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user