Remove "Link all monitor brightness" feature

Eliminates the UI and backend logic for synchronizing all monitor brightness levels. Refactors monitor list update logic to distinguish between initial load and refresh, introducing RestoreMonitorSettings for startup state restoration. Streamlines feature visibility application and settings handling for improved maintainability.
This commit is contained in:
Yu Leng
2025-12-10 11:42:23 +08:00
parent 97560ea6c0
commit 102077a29b
6 changed files with 40 additions and 166 deletions

View File

@@ -182,28 +182,6 @@ namespace PowerDisplay.Helpers
(mon, val) => mon.UpdateStatus(val, true),
cancellationToken);
/// <summary>
/// Set brightness of all monitors
/// </summary>
public async Task<IEnumerable<MonitorOperationResult>> SetAllBrightnessAsync(int brightness, CancellationToken cancellationToken = default)
{
var tasks = _monitors
.Where(m => m.IsAvailable)
.Select(async monitor =>
{
try
{
return await SetBrightnessAsync(monitor.Id, brightness, cancellationToken);
}
catch (Exception ex)
{
return MonitorOperationResult.Failure($"Failed to set brightness for {monitor.Name}: {ex.Message}");
}
});
return await Task.WhenAll(tasks);
}
/// <summary>
/// Set contrast of the specified monitor
/// </summary>

View File

@@ -387,13 +387,6 @@
</Flyout>
</Button.Flyout>
</Button>
<Button
x:Name="LinkButton"
x:Uid="SyncAllMonitorsTooltip"
Click="OnLinkClick"
Content="{ui:FontIcon Glyph=&#xE71B;,
FontSize=16}"
Style="{StaticResource SubtleButtonStyle}" />
<Button
x:Name="RefreshButton"
x:Uid="RefreshTooltip"

View File

@@ -394,24 +394,6 @@ namespace PowerDisplay
}
}
private void OnLinkClick(object sender, RoutedEventArgs e)
{
try
{
// Link all monitor brightness (synchronized adjustment)
if (_viewModel != null && _viewModel.Monitors.Count > 0)
{
// Get first monitor brightness as reference
var baseBrightness = _viewModel.Monitors.First().Brightness;
_ = _viewModel.SetAllBrightnessAsync(baseBrightness);
}
}
catch (Exception ex)
{
Logger.LogError($"OnLinkClick failed: {ex}");
}
}
private void OnSettingsClick(object sender, RoutedEventArgs e)
{
// Open PowerDisplay settings in PowerToys Settings UI

View File

@@ -34,7 +34,7 @@ public partial class MainViewModel
{
try
{
UpdateMonitorList(monitors);
UpdateMonitorList(monitors, isInitialLoad: true);
IsScanning = false;
IsInitialized = true;
@@ -73,7 +73,7 @@ public partial class MainViewModel
_dispatcherQueue.TryEnqueue(() =>
{
UpdateMonitorList(monitors);
UpdateMonitorList(monitors, isInitialLoad: false);
IsScanning = false;
});
}
@@ -87,7 +87,7 @@ public partial class MainViewModel
}
}
private void UpdateMonitorList(IReadOnlyList<Monitor> monitors)
private void UpdateMonitorList(IReadOnlyList<Monitor> monitors, bool isInitialLoad)
{
Monitors.Clear();
@@ -105,26 +105,20 @@ public partial class MainViewModel
}
var vm = new MonitorViewModel(monitor, _monitorManager, this);
ApplyFeatureVisibility(vm, settings);
Monitors.Add(vm);
}
OnPropertyChanged(nameof(HasMonitors));
OnPropertyChanged(nameof(ShowNoMonitorsMessage));
// Save monitor information to settings and reload
// Save monitor information to settings
SaveMonitorsToSettings();
_ = ReloadMonitorSettingsAsync(null);
}
public async Task SetAllBrightnessAsync(int brightness)
// Only restore settings on initial load, not on refresh
if (isInitialLoad && settings.Properties.RestoreSettingsOnStartup)
{
try
{
await _monitorManager.SetAllBrightnessAsync(brightness, _cancellationTokenSource.Token);
}
catch (Exception ex)
{
Logger.LogError($"[SetAllBrightnessAsync] Failed to set brightness: {ex.Message}");
RestoreMonitorSettings();
}
}

View File

@@ -40,7 +40,7 @@ public partial class MainViewModel
// Rebuild monitor list with updated hidden monitor settings
// UpdateMonitorList already handles filtering hidden monitors
UpdateMonitorList(_monitorManager.Monitors);
UpdateMonitorList(_monitorManager.Monitors, isInitialLoad: false);
// Apply UI configuration changes only (feature visibility toggles, etc.)
// Hardware parameters (brightness, color temperature) are applied via custom actions
@@ -322,57 +322,33 @@ public partial class MainViewModel
}
/// <summary>
/// Reload monitor settings from configuration - ONLY called at startup
/// Restore monitor settings from state file - ONLY called at startup when RestoreSettingsOnStartup is enabled
/// </summary>
/// <param name="colorTempInitTasks">Optional tasks for color temperature initialization to wait for</param>
public async Task ReloadMonitorSettingsAsync(List<Task>? colorTempInitTasks = null)
public void RestoreMonitorSettings()
{
Logger.LogInfo($"[ReloadMonitorSettingsAsync] Method called with {colorTempInitTasks?.Count ?? 0} color temp tasks");
// Prevent duplicate calls
if (IsLoading)
{
Logger.LogInfo("[Startup] ReloadMonitorSettingsAsync already in progress, skipping");
return;
}
try
{
// Set loading state to block UI interactions
IsLoading = true;
// Read current settings
var settings = _settingsUtils.GetSettingsOrDefault<PowerDisplaySettings>("PowerDisplay");
// Note: Profiles are now quick-apply templates, not startup states
// We only restore from monitor_state.json, not from profiles
if (settings.Properties.RestoreSettingsOnStartup)
{
// Restore saved settings from configuration file
foreach (var monitorVm in Monitors)
{
var hardwareId = monitorVm.HardwareId;
// Find and apply corresponding saved settings from state file using stable HardwareId
var savedState = _stateManager.GetMonitorParameters(hardwareId);
if (savedState.HasValue)
var savedState = _stateManager.GetMonitorParameters(monitorVm.HardwareId);
if (!savedState.HasValue)
{
continue;
}
// Validate and apply saved values (skip invalid values)
// Use UpdatePropertySilently to avoid triggering hardware updates during initialization
if (IsValueInRange(savedState.Value.Brightness, monitorVm.MinBrightness, monitorVm.MaxBrightness))
{
monitorVm.UpdatePropertySilently(nameof(monitorVm.Brightness), savedState.Value.Brightness);
}
else
{
Logger.LogWarning($"[Startup] Invalid brightness value {savedState.Value.Brightness} for HardwareId '{hardwareId}'");
}
// Color temperature: VCP 0x14 preset value (discrete values, no range check needed)
// Note: ColorTemperature is now read-only in flyout UI, controlled via Settings UI
if (savedState.Value.ColorTemperatureVcp > 0)
{
// Validation will happen in Settings UI when applying preset values
monitorVm.UpdatePropertySilently(nameof(monitorVm.ColorTemperature), savedState.Value.ColorTemperatureVcp);
}
@@ -390,54 +366,14 @@ public partial class MainViewModel
monitorVm.UpdatePropertySilently(nameof(monitorVm.Volume), savedState.Value.Volume);
}
}
// Apply feature visibility settings using HardwareId
ApplyFeatureVisibility(monitorVm, settings);
}
}
else
{
// Save current hardware values to configuration file
// Wait for color temperature initialization to complete (if any)
if (colorTempInitTasks != null && colorTempInitTasks.Count > 0)
{
try
{
await Task.WhenAll(colorTempInitTasks);
}
catch (Exception ex)
{
Logger.LogWarning($"[Startup] Some color temperature initializations failed: {ex.Message}");
}
}
foreach (var monitorVm in Monitors)
{
// Save current hardware values to settings
SaveMonitorSettingDirect(monitorVm.HardwareId, "Brightness", monitorVm.Brightness);
SaveMonitorSettingDirect(monitorVm.HardwareId, "ColorTemperature", monitorVm.ColorTemperature);
SaveMonitorSettingDirect(monitorVm.HardwareId, "Contrast", monitorVm.Contrast);
SaveMonitorSettingDirect(monitorVm.HardwareId, "Volume", monitorVm.Volume);
// Apply feature visibility settings
ApplyFeatureVisibility(monitorVm, settings);
}
// No need to flush - MonitorStateManager now saves directly!
}
}
catch (Exception ex)
{
Logger.LogError($"[ReloadMonitorSettingsAsync] Failed to reload settings: {ex.Message}");
Logger.LogError($"[ReloadMonitorSettingsAsync] Stack trace: {ex.StackTrace}");
Logger.LogError($"[RestoreMonitorSettings] Failed: {ex.Message}");
}
finally
{
Logger.LogInfo("[ReloadMonitorSettingsAsync] In finally block, setting IsLoading = false");
// Clear loading state to enable UI interactions
IsLoading = false;
Logger.LogInfo("[ReloadMonitorSettingsAsync] IsLoading set to false, method exiting");
}
}

View File

@@ -156,15 +156,6 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
[RelayCommand]
private async Task RefreshAsync() => await RefreshMonitorsAsync();
[RelayCommand]
private async Task SetAllBrightness(int? brightness)
{
if (brightness.HasValue)
{
await SetAllBrightnessAsync(brightness.Value);
}
}
[RelayCommand]
private void IdentifyMonitors()
{