mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 03:07:56 +01:00
Refactor logging and VCP naming; simplify capabilities status
Removed excessive debug/info logging and consolidated VCP code/value naming into a single VcpNames utility. Eliminated CapabilitiesStatus property in favor of simpler logic. Cleaned up exception handling and removed non-essential UI and service logs. No changes to core functionality.
This commit is contained in:
@@ -165,7 +165,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
// Check if capabilities are already cached
|
||||
if (!string.IsNullOrEmpty(monitor.CapabilitiesRaw))
|
||||
{
|
||||
Logger.LogDebug($"GetCapabilitiesStringAsync: Using cached capabilities for {monitor.Id} (length: {monitor.CapabilitiesRaw.Length})");
|
||||
return monitor.CapabilitiesRaw;
|
||||
}
|
||||
|
||||
@@ -202,7 +201,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
|
||||
if (!string.IsNullOrEmpty(capsString))
|
||||
{
|
||||
Logger.LogDebug($"Got capabilities string (length: {capsString.Length})");
|
||||
return capsString;
|
||||
}
|
||||
|
||||
@@ -370,7 +368,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
var monitorInfo = matchingInfos[i];
|
||||
|
||||
candidates.Add(new CandidateMonitor(physicalMonitor.HPhysicalMonitor, physicalMonitor, monitorInfo));
|
||||
Logger.LogDebug($"DDC: Candidate {gdiDeviceName} -> DevicePath={monitorInfo.DevicePath}, HardwareId={monitorInfo.HardwareId}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,7 +410,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
{
|
||||
if (!capResult.IsValid)
|
||||
{
|
||||
Logger.LogDebug($"DDC: Handle 0x{candidate.Handle:X} - No DDC/CI brightness support, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -471,7 +467,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
if (GetVCPFeatureAndVCPFeatureReply(handle, VcpCodeInputSource, IntPtr.Zero, out uint current, out uint _))
|
||||
{
|
||||
monitor.CurrentInputSource = (int)current;
|
||||
Logger.LogDebug($"[{monitor.Id}] Input source: {VcpValueNames.GetFormattedName(VcpCodeInputSource, (int)current)}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +478,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
if (GetVCPFeatureAndVCPFeatureReply(handle, VcpCodeSelectColorPreset, IntPtr.Zero, out uint current, out uint _))
|
||||
{
|
||||
monitor.CurrentColorTemperature = (int)current;
|
||||
Logger.LogDebug($"[{monitor.Id}] Color temperature: {VcpValueNames.GetFormattedName(VcpCodeSelectColorPreset, (int)current)}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,7 +490,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
{
|
||||
var brightnessInfo = new VcpFeatureValue((int)current, 0, (int)max);
|
||||
monitor.CurrentBrightness = brightnessInfo.ToPercentage();
|
||||
Logger.LogDebug($"[{monitor.Id}] Brightness: {monitor.CurrentBrightness}%");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,8 +515,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
{
|
||||
monitor.SupportsColorTemperature = true;
|
||||
}
|
||||
|
||||
Logger.LogDebug($"[{monitor.Id}] Capabilities: Contrast={monitor.SupportsContrast}, Volume={monitor.SupportsVolume}, ColorTemp={monitor.SupportsColorTemperature}, InputSource={monitor.SupportsInputSource}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -599,30 +590,14 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
{
|
||||
if (monitor.Handle == IntPtr.Zero)
|
||||
{
|
||||
if (featureName != null)
|
||||
{
|
||||
Logger.LogDebug($"[{monitor.Id}] Invalid handle for {featureName} read");
|
||||
}
|
||||
|
||||
return VcpFeatureValue.Invalid;
|
||||
}
|
||||
|
||||
if (GetVCPFeatureAndVCPFeatureReply(monitor.Handle, vcpCode, IntPtr.Zero, out uint current, out uint max))
|
||||
{
|
||||
if (featureName != null)
|
||||
{
|
||||
var valueName = VcpValueNames.GetFormattedName(vcpCode, (int)current);
|
||||
Logger.LogDebug($"[{monitor.Id}] {featureName} via 0x{vcpCode:X2}: {valueName}");
|
||||
}
|
||||
|
||||
return new VcpFeatureValue((int)current, 0, (int)max);
|
||||
}
|
||||
|
||||
if (featureName != null)
|
||||
{
|
||||
Logger.LogWarning($"[{monitor.Id}] Failed to read {featureName} (0x{vcpCode:X2} not supported)");
|
||||
}
|
||||
|
||||
return VcpFeatureValue.Invalid;
|
||||
},
|
||||
cancellationToken);
|
||||
|
||||
@@ -93,7 +93,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
var capsString = TryGetCapabilitiesString(hPhysicalMonitor);
|
||||
if (string.IsNullOrEmpty(capsString))
|
||||
{
|
||||
Logger.LogDebug($"FetchCapabilities: Failed to get capabilities string for handle 0x{hPhysicalMonitor:X}");
|
||||
return DdcCiValidationResult.Invalid;
|
||||
}
|
||||
|
||||
@@ -102,19 +101,15 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
var capabilities = parseResult.Capabilities;
|
||||
if (capabilities == null || capabilities.SupportedVcpCodes.Count == 0)
|
||||
{
|
||||
Logger.LogDebug($"FetchCapabilities: Failed to parse capabilities string for handle 0x{hPhysicalMonitor:X}");
|
||||
return DdcCiValidationResult.Invalid;
|
||||
}
|
||||
|
||||
// Check if brightness (VCP 0x10) is supported - determines DDC/CI validity
|
||||
bool supportsBrightness = capabilities.SupportsVcpCode(NativeConstants.VcpCodeBrightness);
|
||||
|
||||
Logger.LogDebug($"FetchCapabilities: Handle 0x{hPhysicalMonitor:X} - BrightnessSupport={supportsBrightness}, VcpCodes={capabilities.SupportedVcpCodes.Count}");
|
||||
return new DdcCiValidationResult(supportsBrightness, capsString, capabilities);
|
||||
}
|
||||
catch (Exception ex) when (ex is not OutOfMemoryException)
|
||||
{
|
||||
Logger.LogDebug($"FetchCapabilities: Exception for handle 0x{hPhysicalMonitor:X}: {ex.Message}");
|
||||
return DdcCiValidationResult.Invalid;
|
||||
}
|
||||
}
|
||||
@@ -157,7 +152,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
}
|
||||
catch (Exception ex) when (ex is not OutOfMemoryException)
|
||||
{
|
||||
Logger.LogDebug($"TryGetCapabilitiesString failed: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -191,7 +185,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
}
|
||||
catch (Exception ex) when (ex is not OutOfMemoryException)
|
||||
{
|
||||
Logger.LogDebug($"GetSourceGdiDeviceName failed: {ex.Message}");
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -238,7 +231,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
}
|
||||
catch (Exception ex) when (ex is not OutOfMemoryException)
|
||||
{
|
||||
Logger.LogDebug($"GetTargetDeviceInfo failed: {ex.Message}");
|
||||
}
|
||||
|
||||
return (null, null, null);
|
||||
@@ -308,7 +300,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
var gdiDeviceName = GetSourceGdiDeviceName(path.SourceInfo.AdapterId, path.SourceInfo.Id);
|
||||
if (string.IsNullOrEmpty(gdiDeviceName))
|
||||
{
|
||||
Logger.LogDebug($"QueryDisplayConfig path[{i}]: Failed to get GDI device name");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -318,7 +309,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
// Use device path as key - unique per target, supports mirror mode
|
||||
if (string.IsNullOrEmpty(devicePath))
|
||||
{
|
||||
Logger.LogDebug($"QueryDisplayConfig path[{i}]: Failed to get device path");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -332,13 +322,10 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
TargetId = path.TargetInfo.Id,
|
||||
MonitorNumber = i + 1, // 1-based, matches Windows Display Settings
|
||||
};
|
||||
|
||||
Logger.LogDebug($"QueryDisplayConfig path[{i}]: DevicePath={devicePath}, GdiName={gdiDeviceName}, HardwareId={hardwareId}, FriendlyName={friendlyName}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex) when (ex is not OutOfMemoryException)
|
||||
{
|
||||
Logger.LogDebug($"GetAllMonitorDisplayInfo failed: {ex.Message}");
|
||||
}
|
||||
|
||||
return monitorInfo;
|
||||
|
||||
@@ -34,15 +34,12 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
|
||||
try
|
||||
{
|
||||
Logger.LogDebug($"GetPhysicalMonitors: hMonitor=0x{hMonitor:X}");
|
||||
|
||||
if (!GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, out uint numMonitors))
|
||||
{
|
||||
Logger.LogWarning($"GetPhysicalMonitors: GetNumberOfPhysicalMonitorsFromHMONITOR failed for 0x{hMonitor:X}");
|
||||
return null;
|
||||
}
|
||||
|
||||
Logger.LogDebug($"GetPhysicalMonitors: numMonitors={numMonitors}");
|
||||
if (numMonitors == 0)
|
||||
{
|
||||
Logger.LogWarning($"GetPhysicalMonitors: numMonitors is 0");
|
||||
@@ -59,8 +56,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
}
|
||||
}
|
||||
|
||||
Logger.LogDebug($"GetPhysicalMonitors: GetPhysicalMonitorsFromHMONITOR returned {apiResult}");
|
||||
|
||||
if (!apiResult)
|
||||
{
|
||||
Logger.LogWarning($"GetPhysicalMonitors: GetPhysicalMonitorsFromHMONITOR failed");
|
||||
@@ -71,7 +66,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
var validMonitors = new List<PHYSICAL_MONITOR>();
|
||||
for (int i = 0; i < numMonitors; i++)
|
||||
{
|
||||
string desc = physicalMonitors[i].GetDescription() ?? string.Empty;
|
||||
IntPtr handle = physicalMonitors[i].HPhysicalMonitor;
|
||||
|
||||
if (handle == IntPtr.Zero)
|
||||
@@ -81,7 +75,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.LogDebug($"GetPhysicalMonitors: [{i}] Handle=0x{handle:X}, Desc='{desc}'");
|
||||
validMonitors.Add(physicalMonitors[i]);
|
||||
}
|
||||
|
||||
@@ -141,7 +134,6 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
Handle = physicalMonitor.HPhysicalMonitor,
|
||||
Capabilities = MonitorCapabilities.DdcCi,
|
||||
CommunicationMethod = "DDC/CI",
|
||||
CapabilitiesStatus = "unknown",
|
||||
MonitorNumber = monitorInfo.MonitorNumber,
|
||||
GdiDeviceName = monitorInfo.GdiDeviceName ?? string.Empty,
|
||||
Orientation = DmdoDefault, // Orientation will be set separately if needed
|
||||
|
||||
@@ -66,11 +66,10 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
try
|
||||
{
|
||||
DestroyPhysicalMonitor(handle);
|
||||
Logger.LogDebug($"DDC: Cleaned up unused handle 0x{handle:X}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch
|
||||
{
|
||||
Logger.LogWarning($"DDC: Failed to destroy handle 0x{handle:X}: {ex.Message}");
|
||||
// Silently ignore cleanup failures
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,11 +90,10 @@ namespace PowerDisplay.Common.Drivers.DDC
|
||||
try
|
||||
{
|
||||
DestroyPhysicalMonitor(handle);
|
||||
Logger.LogDebug($"Released physical monitor handle 0x{handle:X}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch
|
||||
{
|
||||
Logger.LogWarning($"Failed to destroy physical monitor handle 0x{handle:X}: {ex.Message}");
|
||||
// Silently ignore cleanup failures
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,6 @@ namespace PowerDisplay.Common.Drivers.WMI
|
||||
// Check if match was found (struct default has null/empty HardwareId)
|
||||
if (!string.IsNullOrEmpty(match.HardwareId))
|
||||
{
|
||||
Logger.LogDebug($"WMI: Matched HardwareId '{hardwareId}' to MonitorNumber {match.MonitorNumber}, GdiDeviceName={match.GdiDeviceName}");
|
||||
return match;
|
||||
}
|
||||
|
||||
@@ -162,7 +161,6 @@ namespace PowerDisplay.Common.Drivers.WMI
|
||||
}
|
||||
|
||||
// No match found - monitor may have been disconnected
|
||||
Logger.LogDebug($"WMI GetBrightness: No monitor found with InstanceName '{monitor.InstanceName}'");
|
||||
}
|
||||
catch (WmiException ex)
|
||||
{
|
||||
@@ -296,7 +294,6 @@ namespace PowerDisplay.Common.Drivers.WMI
|
||||
|
||||
// Get display name from PnP manufacturer ID (e.g., "Lenovo Built-in Display")
|
||||
var displayName = PnpIdHelper.GetBuiltInDisplayName(hardwareId);
|
||||
Logger.LogDebug($"WMI: Found internal display '{hardwareId}' -> '{displayName}'");
|
||||
|
||||
var monitor = new Monitor
|
||||
{
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace PowerDisplay.Common.Models
|
||||
/// Gets human-readable color temperature preset name (e.g., "6500K (0x05)", "sRGB (0x01)")
|
||||
/// </summary>
|
||||
public string ColorTemperaturePresetName =>
|
||||
VcpValueNames.GetFormattedName(0x14, CurrentColorTemperature);
|
||||
VcpNames.GetFormattedValueName(0x14, CurrentColorTemperature);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the monitor supports color temperature adjustment via VCP 0x14
|
||||
@@ -122,7 +122,7 @@ namespace PowerDisplay.Common.Models
|
||||
/// Returns just the name without hex value for cleaner UI display.
|
||||
/// </summary>
|
||||
public string InputSourceName =>
|
||||
VcpValueNames.GetName(0x60, CurrentInputSource) ?? $"Source 0x{CurrentInputSource:X2}";
|
||||
VcpNames.GetValueName(0x60, CurrentInputSource) ?? $"Source 0x{CurrentInputSource:X2}";
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the monitor supports input source switching via VCP 0x60
|
||||
@@ -135,11 +135,6 @@ namespace PowerDisplay.Common.Models
|
||||
public System.Collections.Generic.IReadOnlyList<int>? SupportedInputSources =>
|
||||
VcpCapabilitiesInfo?.GetSupportedValues(0x60);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets capabilities detection status: "available", "unavailable", or "unknown"
|
||||
/// </summary>
|
||||
public string CapabilitiesStatus { get; set; } = "unknown";
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the monitor supports contrast adjustment
|
||||
/// </summary>
|
||||
|
||||
@@ -71,12 +71,10 @@ namespace PowerDisplay.Common.Services
|
||||
}
|
||||
|
||||
int currentOrientation = devMode.DmDisplayOrientation;
|
||||
Logger.LogDebug($"SetRotation: Current orientation={currentOrientation}, target={newOrientation}");
|
||||
|
||||
// If already at target orientation, return success
|
||||
if (currentOrientation == newOrientation)
|
||||
{
|
||||
Logger.LogDebug($"SetRotation: Already at target orientation {newOrientation}");
|
||||
return MonitorOperationResult.Success();
|
||||
}
|
||||
|
||||
@@ -91,7 +89,6 @@ namespace PowerDisplay.Common.Services
|
||||
int temp = devMode.DmPelsWidth;
|
||||
devMode.DmPelsWidth = devMode.DmPelsHeight;
|
||||
devMode.DmPelsHeight = temp;
|
||||
Logger.LogDebug($"SetRotation: Swapped dimensions to {devMode.DmPelsWidth}x{devMode.DmPelsHeight}");
|
||||
}
|
||||
|
||||
// 3. Set new orientation
|
||||
@@ -107,8 +104,6 @@ namespace PowerDisplay.Common.Services
|
||||
return MonitorOperationResult.Failure($"Display settings test failed: {errorMsg}", testResult);
|
||||
}
|
||||
|
||||
Logger.LogDebug($"SetRotation: Test passed, applying settings...");
|
||||
|
||||
// 5. Apply the settings (without CDS_UPDATEREGISTRY to make it temporary)
|
||||
int result = ChangeDisplaySettingsEx(gdiDeviceName, &devMode, IntPtr.Zero, 0, IntPtr.Zero);
|
||||
if (result != DispChangeSuccessful)
|
||||
@@ -147,15 +142,13 @@ namespace PowerDisplay.Common.Services
|
||||
|
||||
if (!EnumDisplaySettings(gdiDeviceName, EnumCurrentSettings, &devMode))
|
||||
{
|
||||
Logger.LogDebug($"GetCurrentOrientation: EnumDisplaySettings failed for {gdiDeviceName}");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return devMode.DmDisplayOrientation;
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch
|
||||
{
|
||||
Logger.LogDebug($"GetCurrentOrientation: Exception for {gdiDeviceName}: {ex.Message}");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,8 +210,6 @@ namespace PowerDisplay.Common.Services
|
||||
|
||||
// Clear dirty flag after successful save
|
||||
_isDirty = false;
|
||||
|
||||
Logger.LogDebug($"[State] Saved state for {monitorCount} monitors");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -231,8 +229,6 @@ namespace PowerDisplay.Common.Services
|
||||
|
||||
// Write to disk synchronously - safe for Dispose
|
||||
File.WriteAllText(_stateFilePath, json);
|
||||
|
||||
Logger.LogDebug($"[State] Saved state for {monitorCount} monitors (sync)");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -46,12 +46,7 @@ namespace PowerDisplay.Common.Services
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
var (profiles, message) = LoadProfilesInternal();
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
Logger.LogInfo($"{LogPrefix} {message}");
|
||||
}
|
||||
|
||||
var (profiles, _) = LoadProfilesInternal();
|
||||
return profiles;
|
||||
}
|
||||
}
|
||||
@@ -72,12 +67,7 @@ namespace PowerDisplay.Common.Services
|
||||
return false;
|
||||
}
|
||||
|
||||
var (success, message) = SaveProfilesInternal(profiles);
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
Logger.LogInfo($"{LogPrefix} {message}");
|
||||
}
|
||||
|
||||
var (success, _) = SaveProfilesInternal(profiles);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace PowerDisplay.Common.Utils
|
||||
|
||||
/// <summary>
|
||||
/// Formats a color temperature display name.
|
||||
/// Uses VcpValueNames for standard VCP value mappings if no custom name is provided.
|
||||
/// Uses VcpNames for standard VCP value mappings if no custom name is provided.
|
||||
/// </summary>
|
||||
/// <param name="vcpValue">The VCP value.</param>
|
||||
/// <param name="customName">Optional custom name from capabilities string.</param>
|
||||
@@ -60,7 +60,7 @@ namespace PowerDisplay.Common.Utils
|
||||
}
|
||||
|
||||
// Fall back to standard VCP value name from shared library
|
||||
var standardName = VcpValueNames.GetName(NativeConstants.VcpCodeSelectColorPreset, vcpValue);
|
||||
var standardName = VcpNames.GetValueName(NativeConstants.VcpCodeSelectColorPreset, vcpValue);
|
||||
if (standardName != null)
|
||||
{
|
||||
return $"{standardName} ({hexValue})";
|
||||
@@ -78,7 +78,7 @@ namespace PowerDisplay.Common.Utils
|
||||
/// <returns>Formatted display name with "Custom" indicator.</returns>
|
||||
public static string FormatCustomColorTemperatureDisplayName(int vcpValue)
|
||||
{
|
||||
var standardName = VcpValueNames.GetName(NativeConstants.VcpCodeSelectColorPreset, vcpValue);
|
||||
var standardName = VcpNames.GetValueName(NativeConstants.VcpCodeSelectColorPreset, vcpValue);
|
||||
return string.IsNullOrEmpty(standardName)
|
||||
? $"Custom (0x{vcpValue:X2})"
|
||||
: $"{standardName} (0x{vcpValue:X2}) - Custom";
|
||||
|
||||
@@ -34,7 +34,6 @@ namespace PowerDisplay.Common.Utils
|
||||
EventResetMode.AutoReset,
|
||||
eventName);
|
||||
eventHandle.Set();
|
||||
Logger.LogDebug($"[EventHelper] Signaled event: {eventName}");
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -254,8 +254,7 @@ namespace PowerDisplay.Common.Utils
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store unknown segments for potential future use
|
||||
Logger.LogDebug($"Unknown capabilities segment: {segment.Name}({segment.Content})");
|
||||
// Unknown segments are silently ignored
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -273,7 +272,7 @@ namespace PowerDisplay.Common.Utils
|
||||
|
||||
while (parser.TryParseEntry(out var entry))
|
||||
{
|
||||
var name = VcpCodeNames.GetName(entry.Code);
|
||||
var name = VcpNames.GetCodeName(entry.Code);
|
||||
vcpCodes[entry.Code] = new VcpCodeInfo(entry.Code, name, entry.Values);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@ namespace PowerDisplay.Common.Utils
|
||||
|
||||
public bool SupportsInputSource { get; init; }
|
||||
|
||||
public string CapabilitiesStatus { get; init; }
|
||||
|
||||
public static FeatureSupportResult Unavailable => new()
|
||||
{
|
||||
SupportsBrightness = false,
|
||||
@@ -39,7 +37,6 @@ namespace PowerDisplay.Common.Utils
|
||||
SupportsColorTemperature = false,
|
||||
SupportsVolume = false,
|
||||
SupportsInputSource = false,
|
||||
CapabilitiesStatus = "unavailable",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -69,7 +66,6 @@ namespace PowerDisplay.Common.Utils
|
||||
SupportsColorTemperature = vcpCodeInts.Contains(NativeConstants.VcpCodeSelectColorPreset),
|
||||
SupportsVolume = vcpCodeInts.Contains(NativeConstants.VcpCodeVolume),
|
||||
SupportsInputSource = vcpCodeInts.Contains(NativeConstants.VcpCodeInputSource),
|
||||
CapabilitiesStatus = "available",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,10 @@ using System.Collections.Generic;
|
||||
namespace PowerDisplay.Common.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// VCP code to friendly name mapping based on MCCS v2.2a specification
|
||||
/// Provides human-readable names for VCP codes and their values based on MCCS v2.2a specification.
|
||||
/// Combines VCP code names (e.g., 0x10 = "Brightness") and VCP value names (e.g., 0x14:0x05 = "6500K").
|
||||
/// </summary>
|
||||
public static class VcpCodeNames
|
||||
public static class VcpNames
|
||||
{
|
||||
/// <summary>
|
||||
/// VCP code to name mapping
|
||||
@@ -240,9 +241,187 @@ namespace PowerDisplay.Common.Utils
|
||||
/// </summary>
|
||||
/// <param name="code">VCP code (e.g., 0x10)</param>
|
||||
/// <returns>Friendly name, or hex representation if unknown</returns>
|
||||
public static string GetName(byte code)
|
||||
public static string GetCodeName(byte code)
|
||||
{
|
||||
return CodeNames.TryGetValue(code, out var name) ? name : $"Unknown (0x{code:X2})";
|
||||
}
|
||||
|
||||
// Dictionary<VcpCode, Dictionary<Value, Name>>
|
||||
private static readonly Dictionary<byte, Dictionary<int, string>> ValueNames = new()
|
||||
{
|
||||
// 0x14: Select Color Preset
|
||||
[0x14] = new Dictionary<int, string>
|
||||
{
|
||||
[0x01] = "sRGB",
|
||||
[0x02] = "Display Native",
|
||||
[0x03] = "4000K",
|
||||
[0x04] = "5000K",
|
||||
[0x05] = "6500K",
|
||||
[0x06] = "7500K",
|
||||
[0x08] = "9300K",
|
||||
[0x09] = "10000K",
|
||||
[0x0A] = "11500K",
|
||||
[0x0B] = "User 1",
|
||||
[0x0C] = "User 2",
|
||||
[0x0D] = "User 3",
|
||||
},
|
||||
|
||||
// 0x60: Input Source
|
||||
[0x60] = new Dictionary<int, string>
|
||||
{
|
||||
[0x01] = "VGA-1",
|
||||
[0x02] = "VGA-2",
|
||||
[0x03] = "DVI-1",
|
||||
[0x04] = "DVI-2",
|
||||
[0x05] = "Composite Video 1",
|
||||
[0x06] = "Composite Video 2",
|
||||
[0x07] = "S-Video-1",
|
||||
[0x08] = "S-Video-2",
|
||||
[0x09] = "Tuner-1",
|
||||
[0x0A] = "Tuner-2",
|
||||
[0x0B] = "Tuner-3",
|
||||
[0x0C] = "Component Video 1",
|
||||
[0x0D] = "Component Video 2",
|
||||
[0x0E] = "Component Video 3",
|
||||
[0x0F] = "DisplayPort-1",
|
||||
[0x10] = "DisplayPort-2",
|
||||
[0x11] = "HDMI-1",
|
||||
[0x12] = "HDMI-2",
|
||||
[0x1B] = "USB-C",
|
||||
},
|
||||
|
||||
// 0xD6: Power Mode
|
||||
[0xD6] = new Dictionary<int, string>
|
||||
{
|
||||
[0x01] = "On",
|
||||
[0x02] = "Standby",
|
||||
[0x03] = "Suspend",
|
||||
[0x04] = "Off (DPM)",
|
||||
[0x05] = "Off (Hard)",
|
||||
},
|
||||
|
||||
// 0x8D: Audio Mute
|
||||
[0x8D] = new Dictionary<int, string>
|
||||
{
|
||||
[0x01] = "Muted",
|
||||
[0x02] = "Unmuted",
|
||||
},
|
||||
|
||||
// 0xDC: Display Application
|
||||
[0xDC] = new Dictionary<int, string>
|
||||
{
|
||||
[0x00] = "Standard/Default",
|
||||
[0x01] = "Productivity",
|
||||
[0x02] = "Mixed",
|
||||
[0x03] = "Movie",
|
||||
[0x04] = "User Defined",
|
||||
[0x05] = "Games",
|
||||
[0x06] = "Sports",
|
||||
[0x07] = "Professional (calibration)",
|
||||
[0x08] = "Standard/Default with intermediate power consumption",
|
||||
[0x09] = "Standard/Default with low power consumption",
|
||||
[0x0A] = "Demonstration",
|
||||
[0xF0] = "Dynamic Contrast",
|
||||
},
|
||||
|
||||
// 0xCC: OSD Language
|
||||
[0xCC] = new Dictionary<int, string>
|
||||
{
|
||||
[0x01] = "Chinese (traditional, Hantai)",
|
||||
[0x02] = "English",
|
||||
[0x03] = "French",
|
||||
[0x04] = "German",
|
||||
[0x05] = "Italian",
|
||||
[0x06] = "Japanese",
|
||||
[0x07] = "Korean",
|
||||
[0x08] = "Portuguese (Portugal)",
|
||||
[0x09] = "Russian",
|
||||
[0x0A] = "Spanish",
|
||||
[0x0B] = "Swedish",
|
||||
[0x0C] = "Turkish",
|
||||
[0x0D] = "Chinese (simplified, Kantai)",
|
||||
[0x0E] = "Portuguese (Brazil)",
|
||||
[0x0F] = "Arabic",
|
||||
[0x10] = "Bulgarian",
|
||||
[0x11] = "Croatian",
|
||||
[0x12] = "Czech",
|
||||
[0x13] = "Danish",
|
||||
[0x14] = "Dutch",
|
||||
[0x15] = "Estonian",
|
||||
[0x16] = "Finnish",
|
||||
[0x17] = "Greek",
|
||||
[0x18] = "Hebrew",
|
||||
[0x19] = "Hindi",
|
||||
[0x1A] = "Hungarian",
|
||||
[0x1B] = "Latvian",
|
||||
[0x1C] = "Lithuanian",
|
||||
[0x1D] = "Norwegian",
|
||||
[0x1E] = "Polish",
|
||||
[0x1F] = "Romanian",
|
||||
[0x20] = "Serbian",
|
||||
[0x21] = "Slovak",
|
||||
[0x22] = "Slovenian",
|
||||
[0x23] = "Thai",
|
||||
[0x24] = "Ukrainian",
|
||||
[0x25] = "Vietnamese",
|
||||
},
|
||||
|
||||
// 0x62: Audio Speaker Volume
|
||||
[0x62] = new Dictionary<int, string>
|
||||
{
|
||||
[0x00] = "Mute",
|
||||
|
||||
// Other values are continuous
|
||||
},
|
||||
|
||||
// 0xDB: Image Mode (Dell monitors)
|
||||
[0xDB] = new Dictionary<int, string>
|
||||
{
|
||||
[0x00] = "Standard",
|
||||
[0x01] = "Multimedia",
|
||||
[0x02] = "Movie",
|
||||
[0x03] = "Game",
|
||||
[0x04] = "Sports",
|
||||
[0x05] = "Color Temperature",
|
||||
[0x06] = "Custom Color",
|
||||
[0x07] = "ComfortView",
|
||||
},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Get human-readable name for a VCP value
|
||||
/// </summary>
|
||||
/// <param name="vcpCode">VCP code (e.g., 0x14)</param>
|
||||
/// <param name="value">Value to translate</param>
|
||||
/// <returns>Name string like "sRGB" or null if unknown</returns>
|
||||
public static string? GetValueName(byte vcpCode, int value)
|
||||
{
|
||||
if (ValueNames.TryGetValue(vcpCode, out var codeValues))
|
||||
{
|
||||
if (codeValues.TryGetValue(value, out var name))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get formatted display name for a VCP value (with hex value in parentheses)
|
||||
/// </summary>
|
||||
/// <param name="vcpCode">VCP code (e.g., 0x14)</param>
|
||||
/// <param name="value">Value to translate</param>
|
||||
/// <returns>Formatted string like "sRGB (0x01)" or "0x01" if unknown</returns>
|
||||
public static string GetFormattedValueName(byte vcpCode, int value)
|
||||
{
|
||||
var name = GetValueName(vcpCode, value);
|
||||
if (name != null)
|
||||
{
|
||||
return $"{name} (0x{value:X2})";
|
||||
}
|
||||
|
||||
return $"0x{value:X2}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
// 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.Collections.Generic;
|
||||
|
||||
namespace PowerDisplay.Common.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides human-readable names for VCP code values based on MCCS standard
|
||||
/// </summary>
|
||||
public static class VcpValueNames
|
||||
{
|
||||
// Dictionary<VcpCode, Dictionary<Value, Name>>
|
||||
private static readonly Dictionary<byte, Dictionary<int, string>> ValueNames = new()
|
||||
{
|
||||
// 0x14: Select Color Preset
|
||||
[0x14] = new Dictionary<int, string>
|
||||
{
|
||||
[0x01] = "sRGB",
|
||||
[0x02] = "Display Native",
|
||||
[0x03] = "4000K",
|
||||
[0x04] = "5000K",
|
||||
[0x05] = "6500K",
|
||||
[0x06] = "7500K",
|
||||
[0x08] = "9300K",
|
||||
[0x09] = "10000K",
|
||||
[0x0A] = "11500K",
|
||||
[0x0B] = "User 1",
|
||||
[0x0C] = "User 2",
|
||||
[0x0D] = "User 3",
|
||||
},
|
||||
|
||||
// 0x60: Input Source
|
||||
[0x60] = new Dictionary<int, string>
|
||||
{
|
||||
[0x01] = "VGA-1",
|
||||
[0x02] = "VGA-2",
|
||||
[0x03] = "DVI-1",
|
||||
[0x04] = "DVI-2",
|
||||
[0x05] = "Composite Video 1",
|
||||
[0x06] = "Composite Video 2",
|
||||
[0x07] = "S-Video-1",
|
||||
[0x08] = "S-Video-2",
|
||||
[0x09] = "Tuner-1",
|
||||
[0x0A] = "Tuner-2",
|
||||
[0x0B] = "Tuner-3",
|
||||
[0x0C] = "Component Video 1",
|
||||
[0x0D] = "Component Video 2",
|
||||
[0x0E] = "Component Video 3",
|
||||
[0x0F] = "DisplayPort-1",
|
||||
[0x10] = "DisplayPort-2",
|
||||
[0x11] = "HDMI-1",
|
||||
[0x12] = "HDMI-2",
|
||||
[0x1B] = "USB-C",
|
||||
},
|
||||
|
||||
// 0xD6: Power Mode
|
||||
[0xD6] = new Dictionary<int, string>
|
||||
{
|
||||
[0x01] = "On",
|
||||
[0x02] = "Standby",
|
||||
[0x03] = "Suspend",
|
||||
[0x04] = "Off (DPM)",
|
||||
[0x05] = "Off (Hard)",
|
||||
},
|
||||
|
||||
// 0x8D: Audio Mute
|
||||
[0x8D] = new Dictionary<int, string>
|
||||
{
|
||||
[0x01] = "Muted",
|
||||
[0x02] = "Unmuted",
|
||||
},
|
||||
|
||||
// 0xDC: Display Application
|
||||
[0xDC] = new Dictionary<int, string>
|
||||
{
|
||||
[0x00] = "Standard/Default",
|
||||
[0x01] = "Productivity",
|
||||
[0x02] = "Mixed",
|
||||
[0x03] = "Movie",
|
||||
[0x04] = "User Defined",
|
||||
[0x05] = "Games",
|
||||
[0x06] = "Sports",
|
||||
[0x07] = "Professional (calibration)",
|
||||
[0x08] = "Standard/Default with intermediate power consumption",
|
||||
[0x09] = "Standard/Default with low power consumption",
|
||||
[0x0A] = "Demonstration",
|
||||
[0xF0] = "Dynamic Contrast",
|
||||
},
|
||||
|
||||
// 0xCC: OSD Language
|
||||
[0xCC] = new Dictionary<int, string>
|
||||
{
|
||||
[0x01] = "Chinese (traditional, Hantai)",
|
||||
[0x02] = "English",
|
||||
[0x03] = "French",
|
||||
[0x04] = "German",
|
||||
[0x05] = "Italian",
|
||||
[0x06] = "Japanese",
|
||||
[0x07] = "Korean",
|
||||
[0x08] = "Portuguese (Portugal)",
|
||||
[0x09] = "Russian",
|
||||
[0x0A] = "Spanish",
|
||||
[0x0B] = "Swedish",
|
||||
[0x0C] = "Turkish",
|
||||
[0x0D] = "Chinese (simplified, Kantai)",
|
||||
[0x0E] = "Portuguese (Brazil)",
|
||||
[0x0F] = "Arabic",
|
||||
[0x10] = "Bulgarian",
|
||||
[0x11] = "Croatian",
|
||||
[0x12] = "Czech",
|
||||
[0x13] = "Danish",
|
||||
[0x14] = "Dutch",
|
||||
[0x15] = "Estonian",
|
||||
[0x16] = "Finnish",
|
||||
[0x17] = "Greek",
|
||||
[0x18] = "Hebrew",
|
||||
[0x19] = "Hindi",
|
||||
[0x1A] = "Hungarian",
|
||||
[0x1B] = "Latvian",
|
||||
[0x1C] = "Lithuanian",
|
||||
[0x1D] = "Norwegian",
|
||||
[0x1E] = "Polish",
|
||||
[0x1F] = "Romanian",
|
||||
[0x20] = "Serbian",
|
||||
[0x21] = "Slovak",
|
||||
[0x22] = "Slovenian",
|
||||
[0x23] = "Thai",
|
||||
[0x24] = "Ukrainian",
|
||||
[0x25] = "Vietnamese",
|
||||
},
|
||||
|
||||
// 0x62: Audio Speaker Volume
|
||||
[0x62] = new Dictionary<int, string>
|
||||
{
|
||||
[0x00] = "Mute",
|
||||
|
||||
// Other values are continuous
|
||||
},
|
||||
|
||||
// 0xDB: Image Mode (Dell monitors)
|
||||
[0xDB] = new Dictionary<int, string>
|
||||
{
|
||||
[0x00] = "Standard",
|
||||
[0x01] = "Multimedia",
|
||||
[0x02] = "Movie",
|
||||
[0x03] = "Game",
|
||||
[0x04] = "Sports",
|
||||
[0x05] = "Color Temperature",
|
||||
[0x06] = "Custom Color",
|
||||
[0x07] = "ComfortView",
|
||||
},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Get human-readable name for a VCP value
|
||||
/// </summary>
|
||||
/// <param name="vcpCode">VCP code (e.g., 0x14)</param>
|
||||
/// <param name="value">Value to translate</param>
|
||||
/// <returns>Name string like "sRGB" or null if unknown</returns>
|
||||
public static string? GetName(byte vcpCode, int value)
|
||||
{
|
||||
if (ValueNames.TryGetValue(vcpCode, out var codeValues))
|
||||
{
|
||||
if (codeValues.TryGetValue(value, out var name))
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get formatted display name for a VCP value (with hex value in parentheses)
|
||||
/// </summary>
|
||||
/// <param name="vcpCode">VCP code (e.g., 0x14)</param>
|
||||
/// <param name="value">Value to translate</param>
|
||||
/// <returns>Formatted string like "sRGB (0x01)" or "0x01" if unknown</returns>
|
||||
public static string GetFormattedName(byte vcpCode, int value)
|
||||
{
|
||||
var name = GetName(vcpCode, value);
|
||||
if (name != null)
|
||||
{
|
||||
return $"{name} (0x{value:X2})";
|
||||
}
|
||||
|
||||
return $"0x{value:X2}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,6 @@ public sealed partial class DisplayChangeWatcher : IDisposable
|
||||
|
||||
if (_isRunning)
|
||||
{
|
||||
Logger.LogDebug("[DisplayChangeWatcher] Already running, ignoring Start()");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -125,11 +124,10 @@ public sealed partial class DisplayChangeWatcher : IDisposable
|
||||
// Ignore events during initial enumeration or after disposal
|
||||
if (_disposed || !_initialEnumerationComplete)
|
||||
{
|
||||
Logger.LogDebug($"[DisplayChangeWatcher] Ignoring add: {args.Name} (disposed={_disposed}, enumComplete={_initialEnumerationComplete})");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.LogInfo($"[DisplayChangeWatcher] Display added: {args.Name} ({args.Id})");
|
||||
Logger.LogInfo($"[DisplayChangeWatcher] Display added: {args.Name}");
|
||||
ScheduleDisplayChanged();
|
||||
});
|
||||
}
|
||||
@@ -142,19 +140,16 @@ public sealed partial class DisplayChangeWatcher : IDisposable
|
||||
// Ignore events during initial enumeration or after disposal
|
||||
if (_disposed || !_initialEnumerationComplete)
|
||||
{
|
||||
Logger.LogDebug($"[DisplayChangeWatcher] Ignoring remove: {args.Id} (disposed={_disposed}, enumComplete={_initialEnumerationComplete})");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.LogInfo($"[DisplayChangeWatcher] Display removed: {args.Id}");
|
||||
Logger.LogInfo("[DisplayChangeWatcher] Display removed");
|
||||
ScheduleDisplayChanged();
|
||||
});
|
||||
}
|
||||
|
||||
private void OnDeviceUpdated(DeviceWatcher sender, DeviceInformationUpdate args)
|
||||
{
|
||||
Logger.LogDebug($"[DisplayChangeWatcher] Display updated: {args.Id}");
|
||||
|
||||
// Only trigger refresh for significant updates, not every property change.
|
||||
// For now, we'll skip updates to avoid excessive refreshes.
|
||||
// The Added and Removed events are the primary triggers for monitor changes.
|
||||
|
||||
@@ -238,7 +238,6 @@ namespace PowerDisplay.Helpers
|
||||
}
|
||||
catch (Exception ex) when (ex is not OutOfMemoryException)
|
||||
{
|
||||
Logger.LogDebug($"GetColorTemperatureAsync failed: {ex.Message}");
|
||||
return VcpFeatureValue.Invalid;
|
||||
}
|
||||
}
|
||||
@@ -277,7 +276,6 @@ namespace PowerDisplay.Helpers
|
||||
}
|
||||
catch (Exception ex) when (ex is not OutOfMemoryException)
|
||||
{
|
||||
Logger.LogDebug($"GetInputSourceAsync failed: {ex.Message}");
|
||||
return VcpFeatureValue.Invalid;
|
||||
}
|
||||
}
|
||||
@@ -348,7 +346,6 @@ namespace PowerDisplay.Helpers
|
||||
var currentOrientation = _rotationService.GetCurrentOrientation(monitor.GdiDeviceName);
|
||||
if (currentOrientation >= 0 && currentOrientation != monitor.Orientation)
|
||||
{
|
||||
Logger.LogDebug($"[MonitorManager] RefreshAllOrientations: {monitor.Id} orientation updated from {monitor.Orientation} to {currentOrientation}");
|
||||
monitor.Orientation = currentOrientation;
|
||||
monitor.LastUpdate = DateTime.Now;
|
||||
}
|
||||
|
||||
@@ -24,26 +24,21 @@ namespace PowerDisplay.Helpers
|
||||
public static void WaitForEventLoop(string eventName, Action callback, CancellationToken cancellationToken)
|
||||
{
|
||||
var dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||
Logger.LogInfo($"[NativeEventWaiter] Setting up listener for event: {eventName}");
|
||||
|
||||
var t = new Thread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, eventName);
|
||||
Logger.LogInfo($"[NativeEventWaiter] Thread started, waiting on event: {eventName}");
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
// Use infinite wait like Peek.UI for more reliable event reception
|
||||
if (eventHandle.WaitOne(500))
|
||||
{
|
||||
Logger.LogInfo($"[NativeEventWaiter] Event signaled: {eventName}");
|
||||
dispatcherQueue.TryEnqueue(() => callback());
|
||||
}
|
||||
}
|
||||
|
||||
Logger.LogInfo($"[NativeEventWaiter] Cancellation requested, exiting loop for: {eventName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -265,21 +265,14 @@ namespace PowerDisplay
|
||||
{
|
||||
try
|
||||
{
|
||||
bool isVisible = IsWindowVisible();
|
||||
Logger.LogInfo($"[ToggleWindow] IsWindowVisible returned: {isVisible}");
|
||||
|
||||
if (isVisible)
|
||||
if (IsWindowVisible())
|
||||
{
|
||||
Logger.LogInfo("[ToggleWindow] Window is visible, calling HideWindow");
|
||||
HideWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogInfo("[ToggleWindow] Window is hidden, calling ShowWindow");
|
||||
ShowWindow();
|
||||
}
|
||||
|
||||
Logger.LogInfo("[ToggleWindow] Toggle completed");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -493,8 +486,6 @@ namespace PowerDisplay
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.LogDebug($"[AdjustSize] Starting adjustment, current window size: {_appWindow.Size.Width}x{_appWindow.Size.Height}");
|
||||
|
||||
// Force layout update to ensure proper measurement
|
||||
RootGrid.UpdateLayout();
|
||||
|
||||
@@ -502,21 +493,13 @@ namespace PowerDisplay
|
||||
var availableWidth = (double)AppConstants.UI.WindowWidth;
|
||||
var contentHeight = GetContentHeight(availableWidth);
|
||||
|
||||
Logger.LogDebug($"[AdjustSize] Content height from measurement: {contentHeight} DIU");
|
||||
|
||||
// Use unified DPI scaling method (consistent with FlyoutWindow pattern)
|
||||
double dpiScale = WindowHelper.GetDpiScale(this);
|
||||
Logger.LogDebug($"[AdjustSize] DPI scale: {dpiScale} ({dpiScale * 100}%)");
|
||||
|
||||
int scaledHeight = WindowHelper.ScaleToPhysicalPixels((int)Math.Ceiling(contentHeight), dpiScale);
|
||||
Logger.LogDebug($"[AdjustSize] Scaled height (physical pixels): {scaledHeight}");
|
||||
|
||||
// Apply maximum height limit (also needs DPI scaling)
|
||||
int maxHeight = WindowHelper.ScaleToPhysicalPixels(AppConstants.UI.MaxWindowHeight, dpiScale);
|
||||
Logger.LogDebug($"[AdjustSize] Max height limit (physical pixels): {maxHeight}");
|
||||
|
||||
scaledHeight = Math.Min(scaledHeight, maxHeight);
|
||||
Logger.LogDebug($"[AdjustSize] Final scaled height after limit: {scaledHeight}");
|
||||
|
||||
// Check if resize is needed
|
||||
// Check if resize is needed
|
||||
@@ -563,10 +546,9 @@ namespace PowerDisplay
|
||||
windowSize.Height,
|
||||
AppConstants.UI.WindowRightMargin);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception)
|
||||
{
|
||||
// Window positioning failures are non-critical, just log for diagnostics
|
||||
Logger.LogDebug($"[PositionWindow] Failed to position window: {ex.Message}");
|
||||
// Window positioning failures are non-critical, silently ignore
|
||||
}
|
||||
}
|
||||
|
||||
@@ -576,31 +558,23 @@ namespace PowerDisplay
|
||||
/// </summary>
|
||||
private void Slider_PointerCaptureLost(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
|
||||
{
|
||||
Logger.LogDebug("[UI] Slider_PointerCaptureLost event triggered");
|
||||
|
||||
var slider = sender as Slider;
|
||||
if (slider == null)
|
||||
{
|
||||
Logger.LogWarning("[UI] Slider is null in PointerCaptureLost");
|
||||
return;
|
||||
}
|
||||
|
||||
var propertyName = slider.Tag as string;
|
||||
var monitorVm = slider.DataContext as MonitorViewModel;
|
||||
|
||||
Logger.LogDebug($"[UI] Property: {propertyName}, MonitorVM: {(monitorVm != null ? monitorVm.Name : "NULL")}, Value: {slider.Value}");
|
||||
|
||||
if (monitorVm == null || propertyName == null)
|
||||
{
|
||||
Logger.LogWarning($"[UI] Null check failed - MonitorVM: {monitorVm == null}, PropertyName: {propertyName == null}");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get final value after drag completes
|
||||
int finalValue = (int)slider.Value;
|
||||
|
||||
Logger.LogInfo($"[UI] Updating {propertyName} to {finalValue} for monitor {monitorVm.Name}");
|
||||
|
||||
// Now update the ViewModel, which will trigger hardware operation
|
||||
switch (propertyName)
|
||||
{
|
||||
@@ -616,8 +590,6 @@ namespace PowerDisplay
|
||||
monitorVm.Volume = finalValue;
|
||||
break;
|
||||
}
|
||||
|
||||
Logger.LogDebug($"[UI] ViewModel property {propertyName} updated successfully");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -66,7 +66,6 @@ public partial class MainViewModel
|
||||
{
|
||||
if (!skipScanningCheck && IsScanning)
|
||||
{
|
||||
Logger.LogDebug("[RefreshMonitorsAsync] Skipping refresh - already scanning");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -536,7 +536,7 @@ public partial class MainViewModel
|
||||
else if (info.HasDiscreteValues)
|
||||
{
|
||||
var formattedValues = info.SupportedValues
|
||||
.Select(v => Common.Utils.VcpValueNames.GetFormattedName(code, v))
|
||||
.Select(v => Common.Utils.VcpNames.GetFormattedValueName(code, v))
|
||||
.ToList();
|
||||
result.Values = $"Values: {string.Join(", ", formattedValues)}";
|
||||
result.HasValues = true;
|
||||
@@ -547,7 +547,7 @@ public partial class MainViewModel
|
||||
.Select(v => new Microsoft.PowerToys.Settings.UI.Library.VcpValueInfo
|
||||
{
|
||||
Value = $"0x{v:X2}",
|
||||
Name = Common.Utils.VcpValueNames.GetName(code, v),
|
||||
Name = Common.Utils.VcpNames.GetValueName(code, v),
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@@ -168,11 +168,9 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
{
|
||||
// Get all display areas (virtual desktop regions)
|
||||
var displayAreas = DisplayArea.FindAll();
|
||||
Logger.LogDebug($"Found {displayAreas.Count} display areas");
|
||||
|
||||
// Get all monitor info from QueryDisplayConfig
|
||||
var allDisplayInfo = DdcCiNative.GetAllMonitorDisplayInfo().Values.ToList();
|
||||
Logger.LogDebug($"Found {allDisplayInfo.Count} monitors from QueryDisplayConfig");
|
||||
|
||||
// Build GDI name to MonitorNumber(s) mapping
|
||||
// Note: In mirror mode, multiple monitors may share the same GdiDeviceName
|
||||
@@ -194,7 +192,6 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
var hMonitor = Win32Interop.GetMonitorFromDisplayId(displayArea.DisplayId);
|
||||
if (hMonitor == IntPtr.Zero)
|
||||
{
|
||||
Logger.LogDebug($"DisplayArea[{i}]: Failed to get HMONITOR");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -202,7 +199,6 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
var monitorInfo = new MonitorInfoEx { CbSize = (uint)sizeof(MonitorInfoEx) };
|
||||
if (!GetMonitorInfo(hMonitor, ref monitorInfo))
|
||||
{
|
||||
Logger.LogDebug($"DisplayArea[{i}]: GetMonitorInfo failed");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -211,13 +207,11 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
// Look up MonitorNumber(s) by GDI device name
|
||||
if (!gdiToMonitorNumbers.TryGetValue(gdiDeviceName, out var monitorNumbers) || monitorNumbers.Count == 0)
|
||||
{
|
||||
Logger.LogDebug($"DisplayArea[{i}]: No MonitorNumber found for GDI device '{gdiDeviceName}'");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Format display text: single number for normal mode, "1|2" for mirror mode
|
||||
var displayText = string.Join("|", monitorNumbers);
|
||||
Logger.LogDebug($"DisplayArea[{i}]: GDI='{gdiDeviceName}' -> MonitorNumbers=[{displayText}]");
|
||||
|
||||
// Create and position identify window
|
||||
var identifyWindow = new IdentifyWindow(displayText);
|
||||
@@ -283,9 +277,9 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
{
|
||||
disposable?.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch
|
||||
{
|
||||
Logger.LogDebug($"Error disposing {name}: {ex.Message}");
|
||||
// Silently ignore dispose errors
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,9 +292,9 @@ public partial class MainViewModel : INotifyPropertyChanged, IDisposable
|
||||
{
|
||||
action();
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch
|
||||
{
|
||||
Logger.LogDebug($"Error executing {name}: {ex.Message}");
|
||||
// Silently ignore execution errors
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -202,8 +202,6 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.LogDebug($"[{Id}] Applying {propertyName.ToLowerInvariant()}: {value}%");
|
||||
|
||||
var result = await setAsyncFunc(Id, value, default);
|
||||
|
||||
if (result.IsSuccess)
|
||||
@@ -518,7 +516,7 @@ public partial class MonitorViewModel : INotifyPropertyChanged, IDisposable
|
||||
_availableInputSources = supportedSources.Select(value => new InputSourceItem
|
||||
{
|
||||
Value = value,
|
||||
Name = Common.Utils.VcpValueNames.GetName(0x60, value) ?? $"Source 0x{value:X2}",
|
||||
Name = Common.Utils.VcpNames.GetValueName(0x60, value) ?? $"Source 0x{value:X2}",
|
||||
SelectionVisibility = value == _monitor.CurrentInputSource ? Visibility.Visible : Visibility.Collapsed,
|
||||
MonitorId = _monitor.Id,
|
||||
}).ToList();
|
||||
|
||||
@@ -43,7 +43,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
private bool _supportsColorTemperature;
|
||||
private bool _supportsVolume;
|
||||
private bool _supportsInputSource;
|
||||
private string _capabilitiesStatus = "unknown"; // "available", "unavailable", or "unknown"
|
||||
|
||||
// Cached color temperature presets (computed from VcpCodesFormatted)
|
||||
private ObservableCollection<ColorPresetItem> _availableColorPresetsCache;
|
||||
@@ -609,21 +608,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("capabilitiesStatus")]
|
||||
public string CapabilitiesStatus
|
||||
{
|
||||
get => _capabilitiesStatus;
|
||||
set
|
||||
{
|
||||
if (_capabilitiesStatus != value)
|
||||
{
|
||||
_capabilitiesStatus = value;
|
||||
OnPropertyChanged();
|
||||
OnPropertyChanged(nameof(ShowCapabilitiesWarning));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Available color temperature presets computed from VcpCodesFormatted (VCP code 0x14).
|
||||
/// This is a computed property that parses the VCP capabilities data on-demand.
|
||||
@@ -740,7 +724,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public bool HasCapabilities => !string.IsNullOrEmpty(_capabilitiesRaw);
|
||||
|
||||
[JsonIgnore]
|
||||
public bool ShowCapabilitiesWarning => _capabilitiesStatus == "unavailable";
|
||||
public bool ShowCapabilitiesWarning => _communicationMethod.Contains("WMI", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
[JsonIgnore]
|
||||
public string BrightnessTooltip => _supportsBrightness ? string.Empty : "Brightness control not supported by this monitor";
|
||||
@@ -816,7 +800,6 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
SupportsColorTemperature = other.SupportsColorTemperature;
|
||||
SupportsVolume = other.SupportsVolume;
|
||||
SupportsInputSource = other.SupportsInputSource;
|
||||
CapabilitiesStatus = other.CapabilitiesStatus;
|
||||
MonitorNumber = other.MonitorNumber;
|
||||
}
|
||||
|
||||
|
||||
@@ -306,7 +306,6 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
monitor.VcpCodes,
|
||||
monitor.CapabilitiesRaw);
|
||||
|
||||
monitor.CapabilitiesStatus = result.CapabilitiesStatus;
|
||||
monitor.SupportsBrightness = result.SupportsBrightness;
|
||||
monitor.SupportsContrast = result.SupportsContrast;
|
||||
monitor.SupportsColorTemperature = result.SupportsColorTemperature;
|
||||
|
||||
Reference in New Issue
Block a user