JBR-8618 Wayland: GTK LaF does not change appearance when system theme changes

This commit is contained in:
Maxim Kartashev
2025-04-15 17:33:28 +04:00
parent d26358d57c
commit ea2a91b83e
4 changed files with 60 additions and 24 deletions

View File

@@ -280,12 +280,19 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
private void installPropertyChangeListeners() {
if(!pclInstalled) {
Toolkit kit = Toolkit.getDefaultToolkit();
WeakPCL pcl = new WeakPCL(this, kit, "gnome.Net/ThemeName");
kit.addPropertyChangeListener(pcl.getKey(), pcl);
pcl = new WeakPCL(this, kit, "gnome.Gtk/FontName");
kit.addPropertyChangeListener(pcl.getKey(), pcl);
pcl = new WeakPCL(this, kit, "gnome.Xft/DPI");
kit.addPropertyChangeListener(pcl.getKey(), pcl);
WeakPCL pcl;
if (isWayland) {
pcl = new WeakPCL(this, kit, "awt.os.theme.isDark");
kit.addPropertyChangeListener(pcl.getKey(), pcl);
} else {
// These properties are only available from the X server
pcl = new WeakPCL(this, kit, "gnome.Net/ThemeName");
kit.addPropertyChangeListener(pcl.getKey(), pcl);
pcl = new WeakPCL(this, kit, "gnome.Gtk/FontName");
kit.addPropertyChangeListener(pcl.getKey(), pcl);
pcl = new WeakPCL(this, kit, "gnome.Xft/DPI");
kit.addPropertyChangeListener(pcl.getKey(), pcl);
}
flushUnreferenced();
pclInstalled = true;
@@ -1513,7 +1520,7 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
* the UIDefaults reads them and this event causes
* those to be reinitialised.
*/
if ("gnome.Net/ThemeName".equals(name)) {
if ("gnome.Net/ThemeName".equals(name) || "awt.os.theme.isDark".equals(name)) {
GTKEngine.INSTANCE.themeChanged();
GTKIconFactory.resetIcons();
}

View File

@@ -154,4 +154,10 @@ public abstract class WLDecoratedPeer extends WLWindowPeer {
return super.cursorAt(x, y);
}
}
@Override
public void dispose() {
decoration.dispose();
super.dispose();
}
}

View File

@@ -26,12 +26,28 @@ package sun.awt.wl;
import sun.swing.SwingUtilities2;
import java.awt.*;
import java.awt.event.*;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.function.Supplier;
public class WLFrameDecoration {
public class WLFrameDecoration implements PropertyChangeListener {
private static final int HEIGHT = 30;
private static final int BUTTON_ICON_SIZE = 4;
private static final int BUTTON_CIRCLE_SIZE = 10;
@@ -53,7 +69,11 @@ public class WLFrameDecoration {
private static final int SIGNIFICANT_DRAG_DISTANCE = 4;
private static final int RESIZE_EDGE_THICKNESS = 5;
private static volatile boolean isDarkTheme = false;
private static volatile boolean isDarkTheme;
static {
Object isDarkThemeProp = Toolkit.getDefaultToolkit().getDesktopProperty("awt.os.theme.isDark");
isDarkTheme = isDarkThemeProp instanceof Boolean ? (Boolean) isDarkThemeProp : false;
}
private static final int XDG_TOPLEVEL_RESIZE_EDGE_TOP = 1;
private static final int XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM = 2;
@@ -99,6 +119,7 @@ public class WLFrameDecoration {
closeButton = new ButtonState(this::getCloseButtonCenter, peer::postWindowClosing);
maximizeButton = showMaximize ? new ButtonState(this::getMaximizeButtonCenter, this::toggleMaximizedState) : null;
minimizeButton = showMinimize ? new ButtonState(this::getMinimizeButtonCenter, this::minimizeWindow) : null;
WLToolkit.getDefaultToolkit().addPropertyChangeListener("awt.os.theme.isDark", this);
}
}
@@ -157,11 +178,6 @@ public class WLFrameDecoration {
return isDarkTheme;
}
private static void updateTheme() {
Boolean isDark = (Boolean) Toolkit.getDefaultToolkit().getDesktopProperty("awt.os.theme.isDark");
isDarkTheme = isDark != null && isDark;
}
private static Color getBackgroundColor(boolean isActive) {
if (isActive) {
return isDarkTheme() ? ACTIVE_BACKGROUND_DARK : ACTIVE_BACKGROUND;
@@ -198,7 +214,6 @@ public class WLFrameDecoration {
if (width <= 0 || height <= 0) return;
Graphics2D g2d = (Graphics2D) g.create(0, 0, width, HEIGHT);
try {
updateTheme();
doPaint(g2d);
} finally {
g2d.dispose();
@@ -448,6 +463,21 @@ public class WLFrameDecoration {
return null;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("awt.os.theme.isDark".equals(evt.getPropertyName())) {
Object newValue = evt.getNewValue();
if (newValue != null) {
isDarkTheme = (Boolean) newValue;
peer.notifyClientDecorationsChanged();
}
}
}
public void dispose() {
WLToolkit.getDefaultToolkit().removePropertyChangeListener("awt.os.theme.isDark", this);
}
private static class ButtonState {
private final Supplier<Point> location;
private final Runnable action;

View File

@@ -923,13 +923,6 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
return null;
}
@Override
public synchronized void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Not implemented: WLToolkit.addPropertyChangeListener()");
}
}
/**
* @see SunToolkit#needsXEmbedImpl
*/