2626
2727import sun .swing .SwingUtilities2 ;
2828
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 ;
3145import java .awt .geom .Ellipse2D ;
46+ import java .beans .PropertyChangeEvent ;
47+ import java .beans .PropertyChangeListener ;
3248import java .util .function .Supplier ;
3349
34- public class WLFrameDecoration {
50+ public class WLFrameDecoration implements PropertyChangeListener {
3551 private static final int HEIGHT = 30 ;
3652 private static final int BUTTON_ICON_SIZE = 4 ;
3753 private static final int BUTTON_CIRCLE_SIZE = 10 ;
@@ -53,7 +69,11 @@ public class WLFrameDecoration {
5369 private static final int SIGNIFICANT_DRAG_DISTANCE = 4 ;
5470 private static final int RESIZE_EDGE_THICKNESS = 5 ;
5571
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+ }
5777
5878 private static final int XDG_TOPLEVEL_RESIZE_EDGE_TOP = 1 ;
5979 private static final int XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM = 2 ;
@@ -99,6 +119,7 @@ public WLFrameDecoration(WLDecoratedPeer peer, boolean isUndecorated, boolean sh
99119 closeButton = new ButtonState (this ::getCloseButtonCenter , peer ::postWindowClosing );
100120 maximizeButton = showMaximize ? new ButtonState (this ::getMaximizeButtonCenter , this ::toggleMaximizedState ) : null ;
101121 minimizeButton = showMinimize ? new ButtonState (this ::getMinimizeButtonCenter , this ::minimizeWindow ) : null ;
122+ WLToolkit .getDefaultToolkit ().addPropertyChangeListener ("awt.os.theme.isDark" , this );
102123 }
103124 }
104125
@@ -157,11 +178,6 @@ private static boolean isDarkTheme() {
157178 return isDarkTheme ;
158179 }
159180
160- private static void updateTheme () {
161- Boolean isDark = (Boolean ) Toolkit .getDefaultToolkit ().getDesktopProperty ("awt.os.theme.isDark" );
162- isDarkTheme = isDark != null && isDark ;
163- }
164-
165181 private static Color getBackgroundColor (boolean isActive ) {
166182 if (isActive ) {
167183 return isDarkTheme () ? ACTIVE_BACKGROUND_DARK : ACTIVE_BACKGROUND ;
@@ -198,7 +214,6 @@ public void paint(final Graphics g) {
198214 if (width <= 0 || height <= 0 ) return ;
199215 Graphics2D g2d = (Graphics2D ) g .create (0 , 0 , width , HEIGHT );
200216 try {
201- updateTheme ();
202217 doPaint (g2d );
203218 } finally {
204219 g2d .dispose ();
@@ -448,6 +463,21 @@ Cursor getCursor(int x, int y) {
448463 return null ;
449464 }
450465
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+
451481 private static class ButtonState {
452482 private final Supplier <Point > location ;
453483 private final Runnable action ;
0 commit comments