diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/rootpane/DarkRootPaneUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/rootpane/DarkRootPaneUI.java index 8f51894c..46dbd555 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/rootpane/DarkRootPaneUI.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/rootpane/DarkRootPaneUI.java @@ -41,6 +41,7 @@ import com.github.weisj.darklaf.util.PropertyUtil; public class DarkRootPaneUI extends BasicRootPaneUI implements HierarchyListener { protected static final String KEY_PREFIX = "JRootPane."; + public static final String HIDE_TITLEBAR = KEY_PREFIX + "hideTitleBar"; public static final String KEY_NO_DECORATIONS_UPDATE = KEY_PREFIX + "noDecorationsUpdate"; public static final String KEY_NO_DECORATIONS = KEY_PREFIX + "noDecorations"; public static final String KEY_UNIFIED_MENUBAR = KEY_PREFIX + "unifiedMenuBar"; diff --git a/macos/src/main/java/com/github/weisj/darklaf/platform/macos/ui/MacOSTitlePane.java b/macos/src/main/java/com/github/weisj/darklaf/platform/macos/ui/MacOSTitlePane.java index f32bf8af..5840e754 100644 --- a/macos/src/main/java/com/github/weisj/darklaf/platform/macos/ui/MacOSTitlePane.java +++ b/macos/src/main/java/com/github/weisj/darklaf/platform/macos/ui/MacOSTitlePane.java @@ -33,6 +33,7 @@ import javax.swing.*; import com.github.weisj.darklaf.platform.decorations.CustomTitlePane; import com.github.weisj.darklaf.platform.macos.JNIDecorationsMacOS; import com.github.weisj.darklaf.util.PropertyKey; +import com.github.weisj.darklaf.util.PropertyUtil; public class MacOSTitlePane extends CustomTitlePane { @@ -47,12 +48,15 @@ public class MacOSTitlePane extends CustomTitlePane { private DecorationInformation decorationInformation; private JLabel titleLabel; private PropertyChangeHandler propertyChangeListener; + private PropertyChangeListener rootPanePropertyChangeListener; + private boolean titleBarHidden; private boolean hideTitleBar = false; public MacOSTitlePane(final JRootPane rootPane, final Window window) { this.rootPane = rootPane; this.window = window; determineColors(); + updateTitleBarVisibility(); } protected void determineColors() { @@ -151,6 +155,8 @@ public class MacOSTitlePane extends CustomTitlePane { window.addWindowListener(windowListener); propertyChangeListener = new PropertyChangeHandler(); window.addPropertyChangeListener(propertyChangeListener); + rootPanePropertyChangeListener = createRootPanePropertyChangeListener(); + rootPane.addPropertyChangeListener(rootPanePropertyChangeListener); } } @@ -161,6 +167,24 @@ public class MacOSTitlePane extends CustomTitlePane { window.removePropertyChangeListener(propertyChangeListener); propertyChangeListener = null; } + if (rootPane != null) { + rootPane.removePropertyChangeListener(rootPanePropertyChangeListener); + rootPanePropertyChangeListener = null; + } + } + + private PropertyChangeListener createRootPanePropertyChangeListener() { + return new RootPanePropertyChangeListener(); + } + + protected class RootPanePropertyChangeListener implements PropertyChangeListener { + + @Override + public void propertyChange(final PropertyChangeEvent evt) { + if ("JRootPane.hideTitleBar".equals(evt.getPropertyName())) { + updateTitleBarVisibility(); + } + } } @Override @@ -186,11 +210,19 @@ public class MacOSTitlePane extends CustomTitlePane { } private boolean hideTitleBar() { + if (titleBarHidden) return true; return (decorationInformation.windowHandle == 0) || JNIDecorationsMacOS.isFullscreen(decorationInformation.windowHandle) || getDecorationStyle() == JRootPane.NONE; } + + private void updateTitleBarVisibility() { + titleBarHidden = PropertyUtil.getBooleanProperty(rootPane, "JRootPane.hideTitleBar"); + rootPane.doLayout(); + rootPane.repaint(); + } + private boolean useCustomTitle() { return titleLabel != null && decorationInformation != null && !decorationInformation.titleVisible; } diff --git a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java index 20db72ec..b38b42cf 100644 --- a/windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java +++ b/windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java @@ -56,6 +56,7 @@ public class WindowsTitlePane extends CustomTitlePane { private final JRootPane rootPane; private boolean unifiedMenuBar; + private boolean titleBarHidden; private ContainerListener rootPaneContainerListener; private ContainerListener layeredPaneContainerListener; @@ -105,6 +106,7 @@ public class WindowsTitlePane extends CustomTitlePane { oldResizable = true; installSubcomponents(); updateMenuBar(true); + updateTitleBarVisibility(); installDefaults(); setLayout(createLayout()); } @@ -133,6 +135,12 @@ public class WindowsTitlePane extends CustomTitlePane { rootPane.revalidate(); } + private void updateTitleBarVisibility() { + titleBarHidden = PropertyUtil.getBooleanProperty(rootPane, "JRootPane.hideTitleBar"); + rootPane.doLayout(); + rootPane.repaint(); + } + private ContainerListener createRootPaneContainerListener() { return new ContainerListener() { @Override @@ -247,6 +255,9 @@ public class WindowsTitlePane extends CustomTitlePane { determineColors(); setActive(window.isActive()); installListeners(); + if (getComponentCount() == 0) { + addComponents(); + } updateSystemIcon(getGraphicsConfiguration()); } } @@ -305,16 +316,20 @@ public class WindowsTitlePane extends CustomTitlePane { private void installSubcomponents() { titleLabel = new JLabel(); titleLabel.setHorizontalAlignment(JLabel.LEFT); - add(titleLabel); createIcons(); createActions(); createButtons(); + addComponents(); + } + + private void addComponents() { add(windowIconButton); add(minimizeButton); add(maximizeToggleButton); add(closeButton); + add(titleLabel); setComponentZOrder(closeButton, 0); setComponentZOrder(maximizeToggleButton, 1); setComponentZOrder(minimizeButton, 2); @@ -697,14 +712,14 @@ public class WindowsTitlePane extends CustomTitlePane { } private boolean hideTitleBar() { + if (titleBarHidden) return true; String title = titleLabel.getText(); if (title == null) title = ""; - return windowHandle == 0 || (getDecorationStyle() == JRootPane.NONE && (menuBar == null || !menuBar.isVisible()) - && title.length() == 0) // e.g. VCLJ achieves fullscreen by hiding the titlebar through jni and setting visibility - // of - // the menubar. - || (menuBar != null && !menuBar.isVisible()); + // of the menubar. + boolean emptyMenuBar = !unifiedMenuBar || menuBar == null || !menuBar.isVisible(); + boolean emptyContent = getDecorationStyle() == JRootPane.NONE && emptyMenuBar && title.length() == 0; + return windowHandle == 0 || emptyContent || (menuBar != null && !menuBar.isVisible()); } @Override @@ -905,6 +920,8 @@ public class WindowsTitlePane extends CustomTitlePane { public void propertyChange(final PropertyChangeEvent evt) { if ("JRootPane.unifiedMenuBar".equals(evt.getPropertyName())) { updateMenuBar(true); + } else if ("JRootPane.hideTitleBar".equals(evt.getPropertyName())) { + updateTitleBarVisibility(); } } }