Refactor color temperature operation handling

Introduced `ColorTemperatureOperation` class to manage pending color temperature changes. Updated `MainViewModel` to process operations for specific monitors, improving efficiency and separation of concerns.

Added `PendingColorTemperatureOperation` property to `PowerDisplayProperties` for tracking operations. Enhanced IPC messaging with `MonitorId` and `ColorTemperature` in `PowerDisplayActionMessage`.

Refactored `PowerDisplayViewModel` and `PowerDisplayPage` to directly apply color temperature to specified monitors. Improved logging for better traceability.
This commit is contained in:
Yu Leng
2025-11-19 16:16:04 +08:00
parent a48e999963
commit fc54172e13
7 changed files with 80 additions and 34 deletions

View File

@@ -21,6 +21,7 @@ namespace PowerDisplay.Serialization
[JsonSerializable(typeof(MonitorStateFile))]
[JsonSerializable(typeof(MonitorStateEntry))]
[JsonSerializable(typeof(PowerDisplaySettings))]
[JsonSerializable(typeof(ColorTemperatureOperation))]
// MonitorInfo and related types (Settings.UI.Library)
[JsonSerializable(typeof(MonitorInfo))]

View File

@@ -481,49 +481,47 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
}
/// <summary>
/// Apply color temperature from settings (triggered by custom action from Settings UI)
/// This is called when user explicitly changes color temperature in Settings UI,
/// NOT when other settings change. Reads current settings and applies only color temperature.
/// Apply color temperature to a specific monitor (triggered by custom action from Settings UI)
/// This is called when user explicitly changes color temperature in Settings UI.
/// Reads the pending operation from settings and applies it directly.
/// </summary>
public async void ApplyColorTemperatureFromSettings()
{
try
{
Logger.LogInfo("[Settings] Processing color temperature update from Settings UI");
var settings = _settingsUtils.GetSettingsOrDefault<PowerDisplaySettings>("PowerDisplay");
var updateTasks = new List<Task>();
foreach (var monitorVm in Monitors)
// Check if there's a pending color temperature operation
var pendingOp = settings.Properties.PendingColorTemperatureOperation;
if (pendingOp != null && !string.IsNullOrEmpty(pendingOp.MonitorId))
{
var hardwareId = monitorVm.HardwareId;
var monitorSettings = settings.Properties.Monitors.FirstOrDefault(m => m.HardwareId == hardwareId);
Logger.LogInfo($"[Settings] Processing pending color temperature operation: Monitor '{pendingOp.MonitorId}' -> 0x{pendingOp.ColorTemperature:X2}");
if (monitorSettings == null)
// Find the monitor by internal name (ID)
var monitorVm = Monitors.FirstOrDefault(m => m.Id == pendingOp.MonitorId);
if (monitorVm != null)
{
continue;
}
// Apply color temperature if changed
if (monitorSettings.ColorTemperature > 0 &&
monitorSettings.ColorTemperature != monitorVm.ColorTemperature)
{
Logger.LogInfo($"[Settings] Applying color temperature for {hardwareId}: 0x{monitorSettings.ColorTemperature:X2}");
var task = ApplyColorTemperatureAsync(monitorVm, monitorSettings.ColorTemperature);
updateTasks.Add(task);
}
}
// Wait for all updates to complete
if (updateTasks.Count > 0)
{
await Task.WhenAll(updateTasks);
Logger.LogInfo($"[Settings] Completed {updateTasks.Count} color temperature updates");
// Apply color temperature directly
await ApplyColorTemperatureAsync(monitorVm, pendingOp.ColorTemperature);
Logger.LogInfo($"[Settings] Successfully applied color temperature to monitor '{pendingOp.MonitorId}'");
}
else
{
Logger.LogInfo("[Settings] No color temperature changes detected");
Logger.LogWarning($"[Settings] Monitor not found: {pendingOp.MonitorId}");
}
// Clear the pending operation
settings.Properties.PendingColorTemperatureOperation = null;
_settingsUtils.SaveSettings(
System.Text.Json.JsonSerializer.Serialize(settings, AppJsonContext.Default.PowerDisplaySettings),
PowerDisplaySettings.ModuleName);
Logger.LogInfo("[Settings] Cleared pending color temperature operation");
}
else
{
Logger.LogInfo("[Settings] No pending color temperature operation");
}
}
catch (Exception ex)

View File

@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
namespace Microsoft.PowerToys.Settings.UI.Library
{
/// <summary>
/// Represents a pending color temperature change operation
/// </summary>
public class ColorTemperatureOperation
{
[JsonPropertyName("monitor_id")]
public string MonitorId { get; set; }
[JsonPropertyName("color_temperature")]
public int ColorTemperature { get; set; }
}
}

View File

@@ -27,6 +27,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("value")]
public string Value { get; set; }
[JsonPropertyName("monitor_id")]
public string MonitorId { get; set; }
[JsonPropertyName("color_temperature")]
public int ColorTemperature { get; set; }
}
}
}

View File

@@ -35,5 +35,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("restore_settings_on_startup")]
public bool RestoreSettingsOnStartup { get; set; }
/// <summary>
/// Pending color temperature operation from Settings UI.
/// This is cleared after PowerDisplay processes it.
/// </summary>
[JsonPropertyName("pending_color_temperature_operation")]
public ColorTemperatureOperation PendingColorTemperatureOperation { get; set; }
}
}

View File

@@ -139,10 +139,9 @@ namespace Microsoft.PowerToys.Settings.UI.Views
monitor.ColorTemperature = newValue.Value;
_previousColorTemperatureValues[monitor.HardwareId] = newValue.Value;
// Trigger custom action to apply color temperature to hardware
// This is separate from the settings save to avoid unwanted hardware updates
// when other settings (like RestoreSettingsOnStartup) change
ViewModel.TriggerApplyColorTemperature();
// Send IPC message to PowerDisplay with monitor ID and new color temperature value
// PowerDisplay will apply it directly to the specified monitor only
ViewModel.ApplyColorTemperatureToMonitor(monitor.InternalName, newValue.Value);
}
else
{

View File

@@ -355,11 +355,24 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
}
/// <summary>
/// Trigger PowerDisplay.exe to apply color temperature from settings file
/// Trigger PowerDisplay.exe to apply color temperature to a specific monitor
/// Called after user confirms color temperature change in Settings UI
/// </summary>
public void TriggerApplyColorTemperature()
/// <param name="monitorInternalName">Internal name (ID) of the monitor</param>
/// <param name="colorTemperature">Color temperature value to apply</param>
public void ApplyColorTemperatureToMonitor(string monitorInternalName, int colorTemperature)
{
// Set the pending operation in settings
_settings.Properties.PendingColorTemperatureOperation = new ColorTemperatureOperation
{
MonitorId = monitorInternalName,
ColorTemperature = colorTemperature,
};
// Save settings to persist the operation
SettingsUtils.SaveSettings(_settings.ToJsonString(), PowerDisplaySettings.ModuleName);
// Send IPC message to trigger PowerDisplay to process the operation
var actionMessage = new PowerDisplayActionMessage
{
Action = new PowerDisplayActionMessage.ActionData
@@ -368,6 +381,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
{
ActionName = "ApplyColorTemperature",
Value = string.Empty,
MonitorId = monitorInternalName,
ColorTemperature = colorTemperature,
},
},
};