26
26
27
27
import sun .swing .SwingUtilities2 ;
28
28
29
- import java .awt .*;
30
- import java .awt .event .*;
29
+ import java .awt .AlphaComposite ;
30
+ import java .awt .Color ;
31
+ import java .awt .Composite ;
32
+ import java .awt .Cursor ;
33
+ import java .awt .Dimension ;
34
+ import java .awt .Font ;
35
+ import java .awt .FontMetrics ;
36
+ import java .awt .Frame ;
37
+ import java .awt .Graphics ;
38
+ import java .awt .Graphics2D ;
39
+ import java .awt .Insets ;
40
+ import java .awt .Point ;
41
+ import java .awt .Rectangle ;
42
+ import java .awt .RenderingHints ;
43
+ import java .awt .Toolkit ;
44
+ import java .awt .event .MouseEvent ;
31
45
import java .awt .geom .Ellipse2D ;
46
+ import java .beans .PropertyChangeEvent ;
47
+ import java .beans .PropertyChangeListener ;
32
48
import java .util .function .Supplier ;
33
49
34
- public class WLFrameDecoration {
50
+ public class WLFrameDecoration implements PropertyChangeListener {
35
51
private static final int HEIGHT = 30 ;
36
52
private static final int BUTTON_ICON_SIZE = 4 ;
37
53
private static final int BUTTON_CIRCLE_SIZE = 10 ;
@@ -53,7 +69,11 @@ public class WLFrameDecoration {
53
69
private static final int SIGNIFICANT_DRAG_DISTANCE = 4 ;
54
70
private static final int RESIZE_EDGE_THICKNESS = 5 ;
55
71
56
- private static volatile boolean isDarkTheme = false ;
72
+ private static volatile boolean isDarkTheme ;
73
+ static {
74
+ Object isDarkThemeProp = Toolkit .getDefaultToolkit ().getDesktopProperty ("awt.os.theme.isDark" );
75
+ isDarkTheme = isDarkThemeProp instanceof Boolean ? (Boolean ) isDarkThemeProp : false ;
76
+ }
57
77
58
78
private static final int XDG_TOPLEVEL_RESIZE_EDGE_TOP = 1 ;
59
79
private static final int XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM = 2 ;
@@ -99,6 +119,7 @@ public WLFrameDecoration(WLDecoratedPeer peer, boolean isUndecorated, boolean sh
99
119
closeButton = new ButtonState (this ::getCloseButtonCenter , peer ::postWindowClosing );
100
120
maximizeButton = showMaximize ? new ButtonState (this ::getMaximizeButtonCenter , this ::toggleMaximizedState ) : null ;
101
121
minimizeButton = showMinimize ? new ButtonState (this ::getMinimizeButtonCenter , this ::minimizeWindow ) : null ;
122
+ WLToolkit .getDefaultToolkit ().addPropertyChangeListener ("awt.os.theme.isDark" , this );
102
123
}
103
124
}
104
125
@@ -157,11 +178,6 @@ private static boolean isDarkTheme() {
157
178
return isDarkTheme ;
158
179
}
159
180
160
- private static void updateTheme () {
161
- Boolean isDark = (Boolean ) Toolkit .getDefaultToolkit ().getDesktopProperty ("awt.os.theme.isDark" );
162
- isDarkTheme = isDark != null && isDark ;
163
- }
164
-
165
181
private static Color getBackgroundColor (boolean isActive ) {
166
182
if (isActive ) {
167
183
return isDarkTheme () ? ACTIVE_BACKGROUND_DARK : ACTIVE_BACKGROUND ;
@@ -198,7 +214,6 @@ public void paint(final Graphics g) {
198
214
if (width <= 0 || height <= 0 ) return ;
199
215
Graphics2D g2d = (Graphics2D ) g .create (0 , 0 , width , HEIGHT );
200
216
try {
201
- updateTheme ();
202
217
doPaint (g2d );
203
218
} finally {
204
219
g2d .dispose ();
@@ -448,6 +463,21 @@ Cursor getCursor(int x, int y) {
448
463
return null ;
449
464
}
450
465
466
+ @ Override
467
+ public void propertyChange (PropertyChangeEvent evt ) {
468
+ if ("awt.os.theme.isDark" .equals (evt .getPropertyName ())) {
469
+ Object newValue = evt .getNewValue ();
470
+ if (newValue != null ) {
471
+ isDarkTheme = (Boolean ) newValue ;
472
+ peer .notifyClientDecorationsChanged ();
473
+ }
474
+ }
475
+ }
476
+
477
+ public void dispose () {
478
+ WLToolkit .getDefaultToolkit ().removePropertyChangeListener ("awt.os.theme.isDark" , this );
479
+ }
480
+
451
481
private static class ButtonState {
452
482
private final Supplier <Point > location ;
453
483
private final Runnable action ;
0 commit comments