@@ -73,11 +73,16 @@ private class Holder
7373 public readonly string DeviceInstanceId ;
7474 public Windows . Graphics . Display . DisplayInformation DisplayInfo { get ; private set ; }
7575 public int Count = 1 ;
76+ public bool IsActive { get ; private set ; } = true ; // default
77+
78+ private Windows . Graphics . Display . AdvancedColorInfo _currentColorInfo ;
79+ private readonly object _closeLock = new ( ) ;
7680
7781 public Holder ( string deviceInstanceId , Windows . Graphics . Display . DisplayInformation displayInfo )
7882 {
7983 this . DeviceInstanceId = deviceInstanceId ;
8084 this . DisplayInfo = displayInfo ;
85+ _currentColorInfo = displayInfo . GetAdvancedColorInfo ( ) ;
8186
8287 // An event handler to DisplayInformation's events must be registered within
8388 // a callback of DispatcherQueueController.DispatcherQueue.TryEnqueue method.
@@ -86,10 +91,40 @@ public Holder(string deviceInstanceId, Windows.Graphics.Display.DisplayInformati
8691
8792 private void OnAdvancedColorInfoChanged ( Windows . Graphics . Display . DisplayInformation sender , object args )
8893 {
94+ lock ( _closeLock )
95+ {
96+ var oldColorInfo = _currentColorInfo ;
97+ _currentColorInfo = sender . GetAdvancedColorInfo ( ) ;
98+
99+ if ( _currentColorInfo . CurrentAdvancedColorKind != oldColorInfo . CurrentAdvancedColorKind )
100+ {
101+ // It is observed that in the case of non-primary monitor, after AdvancedColorKind changes,
102+ // this event will no longer be fired by existing DisplayInformation. Thus it is necessary
103+ // to replace it with new one which is obtained after that change.
104+ // In addition, if an event handler is unregistered within a callback of
105+ // DispatcherQueueController.DispatcherQueue.TryEnqueue method, ArgumentException will be
106+ // thrown saying Delegate to an instance method cannot have null 'this'
107+ sender . AdvancedColorInfoChanged -= OnAdvancedColorInfoChanged ;
108+ IsActive = false ;
109+ }
110+ }
111+
89112 DisplayInformationProvider . AdvancedColorInfoChanged ? . Invoke ( sender , DeviceInstanceId ) ;
90113 }
91114
92- private readonly object _closeLock = new ( ) ;
115+ public void Replace ( Windows . Graphics . Display . DisplayInformation displayInfo )
116+ {
117+ lock ( _closeLock )
118+ {
119+ _currentColorInfo = displayInfo . GetAdvancedColorInfo ( ) ;
120+
121+ this . DisplayInfo = displayInfo ;
122+ this . DisplayInfo . AdvancedColorInfoChanged += OnAdvancedColorInfoChanged ;
123+ IsActive = true ;
124+ }
125+
126+ DisplayInformationProvider . AdvancedColorInfoChanged ? . Invoke ( displayInfo , DeviceInstanceId ) ;
127+ }
93128
94129 public void Close ( )
95130 {
@@ -117,14 +152,22 @@ public static Action RegisterMonitor(string deviceInstanceId, IntPtr monitorHand
117152 lock ( _registerLock )
118153 {
119154 var holder = _holders . FirstOrDefault ( x => x . DeviceInstanceId == deviceInstanceId ) ;
120- if ( holder is null )
155+ if ( holder is not { IsActive : true } )
121156 {
122157 _dispatcherQueueController . DispatcherQueue . TryEnqueue ( ( ) =>
123158 {
124159 var displayInfo = GetForMonitor ( monitorHandle ) ;
125160 if ( displayInfo is not null )
126161 {
127- _holders . Add ( new Holder ( deviceInstanceId , displayInfo ) ) ;
162+ if ( holder is null )
163+ {
164+ _holders . Add ( new Holder ( deviceInstanceId , displayInfo ) ) ;
165+ }
166+ else
167+ {
168+ holder . Replace ( displayInfo ) ;
169+ holder . Count ++ ;
170+ }
128171 }
129172 } ) ;
130173 }
0 commit comments