11package org .redlance .platformtools .impl .windows ;
22
3- import com .sun .jna .Native ;
43import com .sun .jna .Pointer ;
54import com .sun .jna .ptr .IntByReference ;
65import com .sun .jna .win32 .StdCallLibrary ;
98import org .redlance .platformtools .impl .windows .jna .ExtendedUser32 ;
109import org .redlance .platformtools .impl .windows .jna .WPARAM ;
1110
12- import java .awt .* ;
11+ import java .awt .Color ;
1312import java .util .List ;
1413import java .util .concurrent .CopyOnWriteArrayList ;
1514import java .util .function .Consumer ;
@@ -31,14 +30,16 @@ public Color getAccent(Supplier<Color> fallback) {
3130 IntByReference opaque = new IntByReference ();
3231
3332 var result = DwmApi .INSTANCE .DwmGetColorizationColor (colorization , opaque );
34- if (result .intValue () == 0 ) {
35- return new Color (colorization .getValue ());
33+ if (result .intValue () == 0 ) { // S_OK
34+ return new Color (colorization .getValue (), true );
3635 }
3736 return fallback .get ();
3837 }
3938
4039 @ SuppressWarnings ("unused" )
4140 public Pointer callback (Pointer hWnd , int uMsg , WPARAM wParam , WPARAM lParam ) {
41+ Pointer nextProc = this .originalWndProc ;
42+
4243 if (this .hwnd != null && this .hwnd .equals (hWnd )) {
4344 if (uMsg == WM_DWMCOLORIZATIONCOLORCHANGED ) {
4445 Color color = new Color (wParam .intValue (), true );
@@ -49,13 +50,14 @@ public Pointer callback(Pointer hWnd, int uMsg, WPARAM wParam, WPARAM lParam) {
4950 }
5051
5152 if (uMsg == WM_NCDESTROY ) {
52- ExtendedUser32 .INSTANCE .SetWindowLongPtr (hwnd , GWLP_WNDPROC , this . originalWndProc );
53+ ExtendedUser32 .INSTANCE .SetWindowLongPtr (hwnd , GWLP_WNDPROC , nextProc );
5354 this .originalWndProc = this .hwnd = null ;
5455 resubscribe ();
5556 }
5657 }
5758
58- return ExtendedUser32 .INSTANCE .CallWindowProc (this .originalWndProc , hWnd , uMsg , wParam , lParam );
59+ if (nextProc == null ) return Pointer .NULL ;
60+ return ExtendedUser32 .INSTANCE .CallWindowProc (nextProc , hWnd , uMsg , wParam , lParam );
5961 }
6062
6163 @ Override
@@ -70,20 +72,22 @@ public boolean unsubscribeFromChanges(Consumer<Color> consumer) {
7072 }
7173
7274 @ Override
73- public void resubscribe () {
75+ public synchronized void resubscribe () {
7476 if (this .originalWndProc != null && this .hwnd != null ) return ;
77+ if (this .consumers .isEmpty ()) return ;
7578
79+ int currentPid = (int ) ProcessHandle .current ().pid ();
7680 ExtendedUser32 .INSTANCE .EnumWindows ((hWnd , data ) -> {
7781 IntByReference pidRef = new IntByReference ();
7882 ExtendedUser32 .INSTANCE .GetWindowThreadProcessId (hWnd , pidRef );
7983
80- if (pidRef .getValue () == ProcessHandle . current (). pid () && ExtendedUser32 .INSTANCE .IsWindowVisible (hWnd )) {
81- this . hwnd = hWnd ;
82-
83- Pointer prev = ExtendedUser32 . INSTANCE . SetWindowLongPtr ( this .hwnd , GWLP_WNDPROC , this ) ;
84- if ( prev == null ) throw new IllegalStateException ( "SetWindowLongPtr failed, error=" + Native . getLastError ()) ;
85- this . originalWndProc = prev ;
86- return false ;
84+ if (pidRef .getValue () == currentPid && ExtendedUser32 .INSTANCE .IsWindowVisible (hWnd )) {
85+ Pointer prev = ExtendedUser32 . INSTANCE . SetWindowLongPtr ( hWnd , GWLP_WNDPROC , this ) ;
86+ if ( prev != null ) {
87+ this .hwnd = hWnd ;
88+ this . originalWndProc = prev ;
89+ return false ;
90+ }
8791 }
8892 return true ;
8993 }, Pointer .NULL );
0 commit comments