Skip to content

Commit c58668e

Browse files
committed
Optimize Windows impl
1 parent 7ad0de7 commit c58668e

1 file changed

Lines changed: 18 additions & 14 deletions

File tree

src/main/java/org/redlance/platformtools/impl/windows/WindowsAccent.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.redlance.platformtools.impl.windows;
22

3-
import com.sun.jna.Native;
43
import com.sun.jna.Pointer;
54
import com.sun.jna.ptr.IntByReference;
65
import com.sun.jna.win32.StdCallLibrary;
@@ -9,7 +8,7 @@
98
import org.redlance.platformtools.impl.windows.jna.ExtendedUser32;
109
import org.redlance.platformtools.impl.windows.jna.WPARAM;
1110

12-
import java.awt.*;
11+
import java.awt.Color;
1312
import java.util.List;
1413
import java.util.concurrent.CopyOnWriteArrayList;
1514
import 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

Comments
 (0)