mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
Updated NVIDIALibrary and WinLibrary to handle win display reordering
NVIDIALibrary and WinLibrary were too rigid in their equality testing, which meant that there was a problem when Windows reordered the displays in the path. This happens randomly when changing to cloned displays, and after a reboot. This would muck up the equality testing, which would prevent users selecting the display profiles. This has now been corrected (as far as we can tell so far). There is a slight chance that further testing may find other parts of the Windows Display Config that randomly change and need to be updated. Thanks Microsoft.
This commit is contained in:
parent
aee177ecb7
commit
aede23a83d
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.InteropServices;
|
||||
@ -2258,12 +2259,25 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
public override bool Equals(object obj) => obj is NV_DISPLAYCONFIG_PATH_INFO_V2 other && this.Equals(other);
|
||||
|
||||
public bool Equals(NV_DISPLAYCONFIG_PATH_INFO_V2 other)
|
||||
=> Version == other.Version &&
|
||||
SourceId == other.SourceId &&
|
||||
TargetInfoCount == other.TargetInfoCount &&
|
||||
TargetInfo.SequenceEqual(other.TargetInfo) &&
|
||||
SourceModeInfo.Equals(other.SourceModeInfo) &&
|
||||
Flags == other.Flags;
|
||||
{
|
||||
if (!(Version == other.Version &&
|
||||
SourceId == other.SourceId &&
|
||||
TargetInfoCount == other.TargetInfoCount &&
|
||||
SourceModeInfo.Equals(other.SourceModeInfo) &&
|
||||
Flags == other.Flags))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we need to go through the HDR states comparing vaues, as the order changes if there is a cloned display
|
||||
if (!NVImport.EqualButDifferentOrder<NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2>(TargetInfo, other.TargetInfo))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public override Int32 GetHashCode()
|
||||
{
|
||||
@ -7032,5 +7046,52 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
|
||||
// NVAPI_INTERFACE NvAPI_DRS_DeleteProfile(NvDRSSessionHandle hSession, NvDRSProfileHandle hProfile)
|
||||
|
||||
public static bool EqualButDifferentOrder<T>(IList<T> list1, IList<T> list2)
|
||||
{
|
||||
|
||||
if (list1.Count != list2.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we need to go through the list1, checking that all it's items are in list2
|
||||
foreach (T item1 in list1)
|
||||
{
|
||||
bool foundIt = false;
|
||||
foreach (T item2 in list2)
|
||||
{
|
||||
if (item1.Equals(item2))
|
||||
{
|
||||
foundIt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundIt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we need to go through the list2, checking that all it's items are in list1
|
||||
foreach (T item2 in list2)
|
||||
{
|
||||
bool foundIt = false;
|
||||
foreach (T item1 in list1)
|
||||
{
|
||||
if (item1.Equals(item2))
|
||||
{
|
||||
foundIt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundIt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -170,14 +170,25 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
public override bool Equals(object obj) => obj is NVIDIA_DISPLAY_CONFIG other && this.Equals(other);
|
||||
|
||||
public bool Equals(NVIDIA_DISPLAY_CONFIG other)
|
||||
=> IsCloned == other.IsCloned &&
|
||||
{
|
||||
if (!(IsCloned == other.IsCloned &&
|
||||
IsOptimus == other.IsOptimus &&
|
||||
PhysicalAdapters.SequenceEqual(other.PhysicalAdapters) &&
|
||||
MosaicConfig.Equals(other.MosaicConfig) &&
|
||||
DisplayConfigs.SequenceEqual(other.DisplayConfigs) &&
|
||||
DRSSettings.SequenceEqual(other.DRSSettings) &&
|
||||
DisplayIdentifiers.SequenceEqual(other.DisplayIdentifiers);
|
||||
DisplayIdentifiers.SequenceEqual(other.DisplayIdentifiers)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we need to go through the display configscomparing values, as the order changes if there is a cloned display
|
||||
if (!NVIDIALibrary.EqualButDifferentOrder<NV_DISPLAYCONFIG_PATH_INFO_V2>(DisplayConfigs, other.DisplayConfigs))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
@ -4306,6 +4317,53 @@ namespace DisplayMagicianShared.NVIDIA
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool EqualButDifferentOrder<T>(IList<T> list1, IList<T> list2)
|
||||
{
|
||||
|
||||
if (list1.Count != list2.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we need to go through the list1, checking that all it's items are in list2
|
||||
foreach (T item1 in list1)
|
||||
{
|
||||
bool foundIt = false;
|
||||
foreach (T item2 in list2)
|
||||
{
|
||||
if (item1.Equals(item2))
|
||||
{
|
||||
foundIt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundIt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we need to go through the list2, checking that all it's items are in list1
|
||||
foreach (T item2 in list2)
|
||||
{
|
||||
bool foundIt = false;
|
||||
foreach (T item1 in list1)
|
||||
{
|
||||
if (item1.Equals(item2))
|
||||
{
|
||||
foundIt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundIt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,15 +52,15 @@ namespace DisplayMagicianShared.Windows
|
||||
|
||||
public override bool Equals(object obj) => obj is DISPLAY_SOURCE other && this.Equals(other);
|
||||
public bool Equals(DISPLAY_SOURCE other)
|
||||
=> SourceId.Equals(other.SourceId) &&
|
||||
TargetId.Equals(other.TargetId) &&
|
||||
=> //SourceId.Equals(other.SourceId) && // Source ID needs to be ignored in this case, as windows moves the source ids around :(
|
||||
TargetId.Equals(other.TargetId) &&
|
||||
DevicePath.Equals(other.DevicePath) &&
|
||||
SourceDpiScalingRel.Equals(other.SourceDpiScalingRel);
|
||||
//=> true;
|
||||
public override int GetHashCode()
|
||||
{
|
||||
//return 300;
|
||||
return (SourceId, TargetId, DevicePath, SourceDpiScalingRel).GetHashCode();
|
||||
//return (SourceId, TargetId, DevicePath, SourceDpiScalingRel).GetHashCode(); // Source ID needs to be ignored in this case, as windows moves the source ids around :(
|
||||
return (TargetId, DevicePath, SourceDpiScalingRel).GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator ==(DISPLAY_SOURCE lhs, DISPLAY_SOURCE rhs) => lhs.Equals(rhs);
|
||||
@ -91,7 +91,6 @@ namespace DisplayMagicianShared.Windows
|
||||
if (!(IsCloned == other.IsCloned &&
|
||||
DisplayConfigPaths.SequenceEqual(other.DisplayConfigPaths) &&
|
||||
DisplayConfigModes.SequenceEqual(other.DisplayConfigModes) &&
|
||||
DisplayHDRStates.SequenceEqual(other.DisplayHDRStates) &&
|
||||
// The dictionary keys sometimes change after returning from NVIDIA Surround, so we need to only focus on comparing the values of the GDISettings.
|
||||
// Additionally, we had to disable the DEviceKey from the equality testing within the GDI library itself as that waould also change after changing back from NVIDIA surround
|
||||
// This still allows us to detect when refresh rates change, which will allow DisplayMagician to detect profile differences.
|
||||
@ -101,6 +100,12 @@ namespace DisplayMagicianShared.Windows
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we need to go through the HDR states comparing vaues, as the order changes if there is a cloned display
|
||||
if (!WinLibrary.EqualButDifferentOrder<ADVANCED_HDR_INFO_PER_PATH>(DisplayHDRStates, other.DisplayHDRStates))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we need to go through the values to make sure they are the same, but ignore the keys (as they change after each reboot!)
|
||||
for (int i = 0; i < DisplaySources.Count; i++)
|
||||
{
|
||||
@ -2361,6 +2366,53 @@ namespace DisplayMagicianShared.Windows
|
||||
Utils.SendMessage(windowHandle, Utils.WM_MOUSEMOVE, 0, (y << 16) + x);
|
||||
}
|
||||
|
||||
public static bool EqualButDifferentOrder<T>(IList<T> list1, IList<T> list2)
|
||||
{
|
||||
|
||||
if (list1.Count != list2.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we need to go through the list1, checking that all it's items are in list2
|
||||
foreach (T item1 in list1)
|
||||
{
|
||||
bool foundIt = false;
|
||||
foreach (T item2 in list2)
|
||||
{
|
||||
if (item1.Equals(item2))
|
||||
{
|
||||
foundIt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundIt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we need to go through the list2, checking that all it's items are in list1
|
||||
foreach (T item2 in list2)
|
||||
{
|
||||
bool foundIt = false;
|
||||
foreach (T item1 in list1)
|
||||
{
|
||||
if (item1.Equals(item2))
|
||||
{
|
||||
foundIt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundIt)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[global::System.Serializable]
|
||||
|
Loading…
Reference in New Issue
Block a user