diff --git a/src/modules/powerdisplay/PowerDisplay.Lib/Drivers/DDC/DdcCiController.cs b/src/modules/powerdisplay/PowerDisplay.Lib/Drivers/DDC/DdcCiController.cs index 0cd9fb468d..87b454d750 100644 --- a/src/modules/powerdisplay/PowerDisplay.Lib/Drivers/DDC/DdcCiController.cs +++ b/src/modules/powerdisplay/PowerDisplay.Lib/Drivers/DDC/DdcCiController.cs @@ -576,6 +576,12 @@ namespace PowerDisplay.Common.Drivers.DDC { InitializeInputSource(monitor, candidate.Handle); } + + // Initialize color temperature if supported + if (monitor.SupportsColorTemperature) + { + InitializeColorTemperature(monitor, candidate.Handle); + } } monitors.Add(monitor); @@ -600,6 +606,18 @@ namespace PowerDisplay.Common.Drivers.DDC } } + /// + /// Initialize color temperature value for a monitor using VCP 0x14. + /// + private static void InitializeColorTemperature(Monitor monitor, IntPtr handle) + { + if (DdcCiNative.TryGetVCPFeature(handle, VcpCodeSelectColorPreset, out uint current, out uint _)) + { + monitor.CurrentColorTemperature = (int)current; + Logger.LogDebug($"[{monitor.Id}] Color temperature: {VcpValueNames.GetFormattedName(VcpCodeSelectColorPreset, (int)current)}"); + } + } + /// /// Update monitor capability flags based on parsed VCP capabilities. /// diff --git a/src/modules/powerdisplay/PowerDisplay/Helpers/MonitorManager.cs b/src/modules/powerdisplay/PowerDisplay/Helpers/MonitorManager.cs index a221d41b2a..8133fddc3c 100644 --- a/src/modules/powerdisplay/PowerDisplay/Helpers/MonitorManager.cs +++ b/src/modules/powerdisplay/PowerDisplay/Helpers/MonitorManager.cs @@ -344,56 +344,6 @@ namespace PowerDisplay.Helpers return Task.FromResult(result); } - /// - /// Initialize input source for a monitor (async operation) - /// - public async Task InitializeInputSourceAsync(string monitorId, CancellationToken cancellationToken = default) - { - try - { - var sourceInfo = await GetInputSourceAsync(monitorId, cancellationToken); - if (sourceInfo.IsValid) - { - var monitor = GetMonitor(monitorId); - if (monitor != null) - { - // Store raw VCP 0x60 value (e.g., 0x11 for HDMI-1) - monitor.CurrentInputSource = sourceInfo.Current; - Logger.LogInfo($"[{monitorId}] Input source initialized: {monitor.InputSourceName}"); - } - } - } - catch (Exception ex) - { - Logger.LogWarning($"Failed to initialize input source for {monitorId}: {ex.Message}"); - } - } - - /// - /// Initialize color temperature for a monitor (async operation) - /// - public async Task InitializeColorTemperatureAsync(string monitorId, CancellationToken cancellationToken = default) - { - try - { - var tempInfo = await GetColorTemperatureAsync(monitorId, cancellationToken); - if (tempInfo.IsValid) - { - var monitor = GetMonitor(monitorId); - if (monitor != null) - { - // Store raw VCP 0x14 preset value (e.g., 0x05 for 6500K) - // No Kelvin conversion - we use discrete presets - monitor.CurrentColorTemperature = tempInfo.Current; - } - } - } - catch (Exception ex) - { - Logger.LogWarning($"Failed to initialize color temperature for {monitorId}: {ex.Message}"); - } - } - /// /// Get monitor by ID. Uses dictionary lookup for O(1) performance. /// diff --git a/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.Monitors.cs b/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.Monitors.cs index d795a6be8c..d108744957 100644 --- a/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.Monitors.cs +++ b/src/modules/powerdisplay/PowerDisplay/ViewModels/MainViewModel.Monitors.cs @@ -95,7 +95,6 @@ public partial class MainViewModel var settings = _settingsUtils.GetSettingsOrDefault(PowerDisplaySettings.ModuleName); var hiddenMonitorIds = GetHiddenMonitorIds(settings); - var colorTempTasks = new List(); foreach (var monitor in monitors) { // Skip monitors that are marked as hidden in settings @@ -107,69 +106,14 @@ public partial class MainViewModel var vm = new MonitorViewModel(monitor, _monitorManager, this); Monitors.Add(vm); - - // Asynchronously initialize color temperature for DDC/CI monitors - if (monitor.SupportsColorTemperature && monitor.CommunicationMethod == "DDC/CI") - { - var task = InitializeColorTemperatureSafeAsync(monitor.Id, vm); - colorTempTasks.Add(task); - } } OnPropertyChanged(nameof(HasMonitors)); OnPropertyChanged(nameof(ShowNoMonitorsMessage)); - // Wait for color temperature initialization to complete before saving - // This ensures we save the actual scanned values instead of defaults - if (colorTempTasks.Count > 0) - { - // Use fire-and-forget async method to avoid blocking UI thread - _ = WaitForColorTempAndSaveAsync(colorTempTasks); - } - else - { - // No color temperature tasks, save immediately - SaveMonitorsToSettings(); - - // Restore saved settings if enabled (async, don't block) - _ = ReloadMonitorSettingsAsync(null); - } - } - - private async Task WaitForColorTempAndSaveAsync(IReadOnlyList colorTempTasks) - { - try - { - // Wait for all color temperature initialization tasks to complete - await Task.WhenAll(colorTempTasks); - - // Save monitor information to settings.json and reload settings - // Must be done on UI thread since these methods access UI properties and observable collections - _dispatcherQueue.TryEnqueue(async () => - { - try - { - SaveMonitorsToSettings(); - - // Restore saved settings if enabled (async) - await ReloadMonitorSettingsAsync(null); // Tasks already completed, pass null - } - catch (Exception innerEx) - { - Logger.LogError($"[WaitForColorTempAndSaveAsync] Error in UI thread operation: {innerEx.Message}"); - } - }); - } - catch (Exception ex) - { - Logger.LogWarning($"[WaitForColorTempAndSaveAsync] Color temperature initialization failed: {ex.Message}"); - - // Save anyway with whatever values we have - _dispatcherQueue.TryEnqueue(() => - { - SaveMonitorsToSettings(); - }); - } + // Save monitor information to settings and reload + SaveMonitorsToSettings(); + _ = ReloadMonitorSettingsAsync(null); } public async Task SetAllBrightnessAsync(int brightness) @@ -192,35 +136,4 @@ public partial class MainViewModel settings.Properties.Monitors .Where(m => m.IsHidden) .Select(m => m.InternalName)); - - /// - /// Safe wrapper for initializing color temperature asynchronously - /// - private async Task InitializeColorTemperatureSafeAsync(string monitorId, MonitorViewModel vm) - { - try - { - // Read current color temperature from hardware - await _monitorManager.InitializeColorTemperatureAsync(monitorId); - - // Get the monitor and use the hardware value as-is - var monitor = _monitorManager.GetMonitor(monitorId); - if (monitor != null) - { - Logger.LogInfo($"[{monitorId}] Read color temperature from hardware: {monitor.CurrentColorTemperature}"); - - _dispatcherQueue.TryEnqueue(() => - { - // Update color temperature without triggering hardware write - // Use the hardware value directly, even if not in the preset list - // This will also update monitor_state.json via MonitorStateManager - vm.UpdatePropertySilently(nameof(vm.ColorTemperature), monitor.CurrentColorTemperature); - }); - } - } - catch (Exception ex) - { - Logger.LogWarning($"Failed to initialize color temperature for {monitorId}: {ex.Message}"); - } - } }