mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 19:57:57 +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>
|
/// <summary>
|
||||||
/// Serializable state for JSON persistence
|
/// 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>
|
/// </summary>
|
||||||
private sealed class MonitorStateFile
|
private sealed class MonitorStateFile
|
||||||
{
|
{
|
||||||
@@ -116,13 +118,20 @@ namespace PowerDisplay.Helpers
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Update monitor parameter in memory (lock-free, non-blocking)
|
/// Update monitor parameter in memory (lock-free, non-blocking)
|
||||||
|
/// Uses HardwareId as the stable key
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void UpdateMonitorParameter(string monitorId, string property, int value)
|
public void UpdateMonitorParameter(string hardwareId, string property, int value)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Get or create parameter entry
|
if (string.IsNullOrEmpty(hardwareId))
|
||||||
var parameters = _parameters.GetOrAdd(monitorId, _ => new MonitorParameters());
|
{
|
||||||
|
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)
|
// Update the specific property (volatile write)
|
||||||
switch (property)
|
switch (property)
|
||||||
@@ -147,7 +156,7 @@ namespace PowerDisplay.Helpers
|
|||||||
// Mark as dirty (will be saved in next timer cycle)
|
// Mark as dirty (will be saved in next timer cycle)
|
||||||
_isDirty = true;
|
_isDirty = true;
|
||||||
|
|
||||||
Logger.LogTrace($"[State] Updated {property}={value} for monitor '{monitorId}'");
|
Logger.LogTrace($"[State] Updated {property}={value} for monitor HardwareId='{hardwareId}'");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -156,11 +165,16 @@ namespace PowerDisplay.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get saved parameters for a monitor
|
/// Get saved parameters for a monitor using HardwareId
|
||||||
/// </summary>
|
/// </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);
|
return (parameters.Brightness, parameters.ColorTemperature, parameters.Contrast, parameters.Volume);
|
||||||
}
|
}
|
||||||
@@ -168,11 +182,11 @@ namespace PowerDisplay.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if state exists for a monitor
|
/// Check if state exists for a monitor (by HardwareId)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HasMonitorState(string monitorId)
|
public bool HasMonitorState(string hardwareId)
|
||||||
{
|
{
|
||||||
return _parameters.ContainsKey(monitorId);
|
return !string.IsNullOrEmpty(hardwareId) && _parameters.ContainsKey(hardwareId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -195,10 +209,10 @@ namespace PowerDisplay.Helpers
|
|||||||
{
|
{
|
||||||
foreach (var kvp in state.Monitors)
|
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 entry = kvp.Value;
|
||||||
|
|
||||||
var parameters = _parameters.GetOrAdd(monitorId, _ => new MonitorParameters());
|
var parameters = _parameters.GetOrAdd(monitorKey, _ => new MonitorParameters());
|
||||||
parameters.Brightness = entry.Brightness;
|
parameters.Brightness = entry.Brightness;
|
||||||
parameters.ColorTemperature = entry.ColorTemperature;
|
parameters.ColorTemperature = entry.ColorTemperature;
|
||||||
parameters.Contrast = entry.Contrast;
|
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] 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)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -487,14 +487,14 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable
|
|||||||
|
|
||||||
foreach (var monitorVm in Monitors)
|
foreach (var monitorVm in Monitors)
|
||||||
{
|
{
|
||||||
var internalName = GetInternalName(monitorVm);
|
var hardwareId = monitorVm.HardwareId;
|
||||||
Logger.LogInfo($"[Startup] Processing monitor: '{monitorVm.Name}', InternalName: '{internalName}'");
|
Logger.LogInfo($"[Startup] Processing monitor: '{monitorVm.Name}', HardwareId: '{hardwareId}'");
|
||||||
|
|
||||||
// Find and apply corresponding saved settings from state file
|
// Find and apply corresponding saved settings from state file using stable HardwareId
|
||||||
var savedState = _stateManager.GetMonitorParameters(internalName);
|
var savedState = _stateManager.GetMonitorParameters(hardwareId);
|
||||||
if (savedState.HasValue)
|
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)
|
if (savedState.Value.Brightness >= monitorVm.MinBrightness && savedState.Value.Brightness <= monitorVm.MaxBrightness)
|
||||||
@@ -503,7 +503,7 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable
|
|||||||
}
|
}
|
||||||
else
|
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
|
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)
|
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)
|
else if (!monitorVm.ShowVolume)
|
||||||
{
|
{
|
||||||
Logger.LogInfo($"[Startup] Volume not supported on '{internalName}', skipping");
|
Logger.LogInfo($"[Startup] Volume not supported on HardwareId '{hardwareId}', skipping");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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);
|
ApplyFeatureVisibility(monitorVm, settings, internalName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -634,7 +635,7 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Find the monitor VM to get the converted internal name
|
// Find the monitor VM to get the stable HardwareId
|
||||||
var monitorVm = GetMonitorViewModel(monitorId);
|
var monitorVm = GetMonitorViewModel(monitorId);
|
||||||
if (monitorVm == null)
|
if (monitorVm == null)
|
||||||
{
|
{
|
||||||
@@ -642,13 +643,13 @@ public class MainViewModel : INotifyPropertyChanged, IDisposable
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use converted internal name for consistency with Settings UI
|
// Use stable HardwareId as the key for state persistence
|
||||||
var internalName = GetInternalName(monitorVm);
|
var hardwareId = monitorVm.HardwareId;
|
||||||
|
|
||||||
// Update parameter in state file (lock-free, non-blocking)
|
// 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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user