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(MonitorStateFile))]
[JsonSerializable(typeof(MonitorStateEntry))] [JsonSerializable(typeof(MonitorStateEntry))]
[JsonSerializable(typeof(PowerDisplaySettings))] [JsonSerializable(typeof(PowerDisplaySettings))]
[JsonSerializable(typeof(ColorTemperatureOperation))]
// MonitorInfo and related types (Settings.UI.Library) // MonitorInfo and related types (Settings.UI.Library)
[JsonSerializable(typeof(MonitorInfo))] [JsonSerializable(typeof(MonitorInfo))]

View File

@@ -481,49 +481,47 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
} }
/// <summary> /// <summary>
/// Apply color temperature from settings (triggered by custom action from Settings UI) /// 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, /// 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. /// Reads the pending operation from settings and applies it directly.
/// </summary> /// </summary>
public async void ApplyColorTemperatureFromSettings() public async void ApplyColorTemperatureFromSettings()
{ {
try try
{ {
Logger.LogInfo("[Settings] Processing color temperature update from Settings UI");
var settings = _settingsUtils.GetSettingsOrDefault<PowerDisplaySettings>("PowerDisplay"); 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; Logger.LogInfo($"[Settings] Processing pending color temperature operation: Monitor '{pendingOp.MonitorId}' -> 0x{pendingOp.ColorTemperature:X2}");
var monitorSettings = settings.Properties.Monitors.FirstOrDefault(m => m.HardwareId == hardwareId);
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 directly
await ApplyColorTemperatureAsync(monitorVm, pendingOp.ColorTemperature);
Logger.LogInfo($"[Settings] Successfully applied color temperature to monitor '{pendingOp.MonitorId}'");
}
else
{
Logger.LogWarning($"[Settings] Monitor not found: {pendingOp.MonitorId}");
} }
// Apply color temperature if changed // Clear the pending operation
if (monitorSettings.ColorTemperature > 0 && settings.Properties.PendingColorTemperatureOperation = null;
monitorSettings.ColorTemperature != monitorVm.ColorTemperature) _settingsUtils.SaveSettings(
{ System.Text.Json.JsonSerializer.Serialize(settings, AppJsonContext.Default.PowerDisplaySettings),
Logger.LogInfo($"[Settings] Applying color temperature for {hardwareId}: 0x{monitorSettings.ColorTemperature:X2}"); PowerDisplaySettings.ModuleName);
Logger.LogInfo("[Settings] Cleared pending color temperature operation");
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");
} }
else else
{ {
Logger.LogInfo("[Settings] No color temperature changes detected"); Logger.LogInfo("[Settings] No pending color temperature operation");
} }
} }
catch (Exception ex) 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")] [JsonPropertyName("value")]
public string Value { get; set; } 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")] [JsonPropertyName("restore_settings_on_startup")]
public bool RestoreSettingsOnStartup { get; set; } 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; monitor.ColorTemperature = newValue.Value;
_previousColorTemperatureValues[monitor.HardwareId] = newValue.Value; _previousColorTemperatureValues[monitor.HardwareId] = newValue.Value;
// Trigger custom action to apply color temperature to hardware // Send IPC message to PowerDisplay with monitor ID and new color temperature value
// This is separate from the settings save to avoid unwanted hardware updates // PowerDisplay will apply it directly to the specified monitor only
// when other settings (like RestoreSettingsOnStartup) change ViewModel.ApplyColorTemperatureToMonitor(monitor.InternalName, newValue.Value);
ViewModel.TriggerApplyColorTemperature();
} }
else else
{ {

View File

@@ -355,11 +355,24 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
} }
/// <summary> /// <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 /// Called after user confirms color temperature change in Settings UI
/// </summary> /// </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 var actionMessage = new PowerDisplayActionMessage
{ {
Action = new PowerDisplayActionMessage.ActionData Action = new PowerDisplayActionMessage.ActionData
@@ -368,6 +381,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
{ {
ActionName = "ApplyColorTemperature", ActionName = "ApplyColorTemperature",
Value = string.Empty, Value = string.Empty,
MonitorId = monitorInternalName,
ColorTemperature = colorTemperature,
}, },
}, },
}; };