diff --git a/src/modules/powerdisplay/PowerDisplay/Serialization/JsonSourceGenerationContext.cs b/src/modules/powerdisplay/PowerDisplay/Serialization/JsonSourceGenerationContext.cs index 4ee496d2dd..31b67b1e44 100644 --- a/src/modules/powerdisplay/PowerDisplay/Serialization/JsonSourceGenerationContext.cs +++ b/src/modules/powerdisplay/PowerDisplay/Serialization/JsonSourceGenerationContext.cs @@ -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))] diff --git a/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.cs b/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.cs index 7b5894ce28..a1f0ef619d 100644 --- a/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.cs +++ b/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.cs @@ -481,49 +481,47 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable } /// - /// 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. /// public async void ApplyColorTemperatureFromSettings() { try { - Logger.LogInfo("[Settings] Processing color temperature update from Settings UI"); - var settings = _settingsUtils.GetSettingsOrDefault("PowerDisplay"); - var updateTasks = new List(); - 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 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 - 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"); + // 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 color temperature changes detected"); + Logger.LogInfo("[Settings] No pending color temperature operation"); } } catch (Exception ex) diff --git a/src/settings-ui/Settings.UI.Library/ColorTemperatureOperation.cs b/src/settings-ui/Settings.UI.Library/ColorTemperatureOperation.cs new file mode 100644 index 0000000000..4e2e45a712 --- /dev/null +++ b/src/settings-ui/Settings.UI.Library/ColorTemperatureOperation.cs @@ -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 +{ + /// + /// Represents a pending color temperature change operation + /// + public class ColorTemperatureOperation + { + [JsonPropertyName("monitor_id")] + public string MonitorId { get; set; } + + [JsonPropertyName("color_temperature")] + public int ColorTemperature { get; set; } + } +} diff --git a/src/settings-ui/Settings.UI.Library/PowerDisplayActionMessage.cs b/src/settings-ui/Settings.UI.Library/PowerDisplayActionMessage.cs index 06ca2bf68f..febd885bff 100644 --- a/src/settings-ui/Settings.UI.Library/PowerDisplayActionMessage.cs +++ b/src/settings-ui/Settings.UI.Library/PowerDisplayActionMessage.cs @@ -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; } } } } diff --git a/src/settings-ui/Settings.UI.Library/PowerDisplayProperties.cs b/src/settings-ui/Settings.UI.Library/PowerDisplayProperties.cs index 64bc7473af..f8b353ed6e 100644 --- a/src/settings-ui/Settings.UI.Library/PowerDisplayProperties.cs +++ b/src/settings-ui/Settings.UI.Library/PowerDisplayProperties.cs @@ -35,5 +35,12 @@ namespace Microsoft.PowerToys.Settings.UI.Library [JsonPropertyName("restore_settings_on_startup")] public bool RestoreSettingsOnStartup { get; set; } + + /// + /// Pending color temperature operation from Settings UI. + /// This is cleared after PowerDisplay processes it. + /// + [JsonPropertyName("pending_color_temperature_operation")] + public ColorTemperatureOperation PendingColorTemperatureOperation { get; set; } } } diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml.cs index f84bd85711..3cd3e921bc 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerDisplayPage.xaml.cs @@ -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 { diff --git a/src/settings-ui/Settings.UI/ViewModels/PowerDisplayViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/PowerDisplayViewModel.cs index aac842c09b..0cb98155a8 100644 --- a/src/settings-ui/Settings.UI/ViewModels/PowerDisplayViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/PowerDisplayViewModel.cs @@ -355,11 +355,24 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } /// - /// 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 /// - public void TriggerApplyColorTemperature() + /// Internal name (ID) of the monitor + /// Color temperature value to apply + 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, }, }, };