From 78a8035b921a49da22799ae42ac015d1dfc2a5b2 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 27 Jan 2025 15:05:28 +0100 Subject: [PATCH] Linux: rounded borders for popups (issue #949) --- .../formdev/flatlaf/FlatClientProperties.java | 2 + .../formdev/flatlaf/ui/FlatPopupFactory.java | 40 +- .../com/formdev/flatlaf/ui/FlatUIUtils.java | 3 +- .../flatlaf/ui/FlatWindowRoundedBorder.java | 361 ++++++++++++++++++ .../formdev/flatlaf/FlatDarkLaf.properties | 1 - .../com/formdev/flatlaf/FlatLaf.properties | 8 +- .../formdev/flatlaf/FlatLightLaf.properties | 1 + .../uidefaults/FlatDarkLaf_1.8.0-mac.txt | 18 +- .../dumps/uidefaults/FlatDarkLaf_1.8.0.txt | 4 + .../uidefaults/FlatLightLaf_1.8.0-mac.txt | 7 +- .../dumps/uidefaults/FlatLightLaf_1.8.0.txt | 4 + .../dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt | 4 + .../uidefaults/FlatMacLightLaf_1.8.0.txt | 4 + .../dumps/uidefaults/FlatTestLaf_1.8.0.txt | 4 + 14 files changed, 429 insertions(+), 32 deletions(-) create mode 100644 flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowRoundedBorder.java diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index a1953cce1..8b7ba2890 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -384,6 +384,7 @@ public interface FlatClientProperties * If this value is {@code 1 - 4}, then {@code DWMWCP_ROUNDSMALL} is used. * If it is {@code >= 5}, then {@code DWMWCP_ROUND} is used. *
  • macOS (10.14 and later): Any corner radius is supported. + *
  • Linux (since FlatLaf 3.6): Any corner radius is supported. * * Component {@link javax.swing.JComponent}
    * Value type {@link java.lang.Integer}
    @@ -402,6 +403,7 @@ public interface FlatClientProperties * Supported platforms: * * Component {@link javax.swing.JComponent}
    * Value type {@link java.lang.Integer} or {@link java.lang.Float}
    diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java index 553695d8a..a4804ba15 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java @@ -25,6 +25,7 @@ import java.awt.EventQueue; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; +import java.awt.GraphicsDevice.WindowTranslucency; import java.awt.GraphicsEnvironment; import java.awt.Insets; import java.awt.MouseInfo; @@ -117,8 +118,8 @@ public Popup getPopup( Component owner, Component contents, int x, int y ) // macOS and Linux adds drop shadow to heavy weight popups if( SystemInfo.isMacOS || SystemInfo.isLinux ) { NonFlashingPopup popup = new NonFlashingPopup( getPopupForScreenOfOwner( owner, contents, x, y, true ), owner, contents ); - if( popup.popupWindow != null && isMacOSBorderSupported() ) - setupRoundedBorder( popup.popupWindow, owner, contents ); + if( popup.popupWindow != null && (isMacOSBorderSupported() || isLinuxBorderSupported( popup.popupWindow )) ) + setupRoundedBorder( popup, popup.popupWindow, owner, contents ); return popup; } @@ -128,7 +129,7 @@ public Popup getPopup( Component owner, Component contents, int x, int y ) { NonFlashingPopup popup = new NonFlashingPopup( getPopupForScreenOfOwner( owner, contents, x, y, true ), owner, contents ); if( popup.popupWindow != null ) - setupRoundedBorder( popup.popupWindow, owner, contents ); + setupRoundedBorder( popup, popup.popupWindow, owner, contents ); return popup; } @@ -370,7 +371,15 @@ private static boolean isMacOSBorderSupported() { FlatNativeMacLibrary.isLoaded(); } - private static void setupRoundedBorder( Window popupWindow, Component owner, Component contents ) { + private static boolean isLinuxBorderSupported( Window window ) { + return SystemInfo.isLinux && + FlatSystemProperties.getBoolean( FlatSystemProperties.USE_ROUNDED_POPUP_BORDER, true ) && + window.getGraphicsConfiguration().getDevice().isWindowTranslucencySupported( WindowTranslucency.PERPIXEL_TRANSPARENT ); + } + + private static void setupRoundedBorder( NonFlashingPopup popup, + Window popupWindow, Component owner, Component contents ) + { int borderCornerRadius = getBorderCornerRadius( owner, contents ); float borderWidth = getRoundedBorderWidth( owner, contents ); @@ -397,7 +406,7 @@ else if( border instanceof EmptyBorder ) if( popupWindow.isDisplayable() ) { // native window already created - setupRoundedBorderImpl( popupWindow, borderCornerRadius, borderWidth, borderColor ); + setupRoundedBorderImpl( popup, popupWindow, borderCornerRadius, borderWidth, borderColor ); } else { // native window not yet created --> add listener to set native border after window creation AtomicReference l = new AtomicReference<>(); @@ -405,7 +414,7 @@ else if( border instanceof EmptyBorder ) if( e.getID() == HierarchyEvent.HIERARCHY_CHANGED && (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0 ) { - setupRoundedBorderImpl( popupWindow, borderCornerRadius, borderWidth, borderColor ); + setupRoundedBorderImpl( popup, popupWindow, borderCornerRadius, borderWidth, borderColor ); popupWindow.removeHierarchyListener( l.get() ); } } ); @@ -413,7 +422,9 @@ else if( border instanceof EmptyBorder ) } } - private static void setupRoundedBorderImpl( Window popupWindow, int borderCornerRadius, float borderWidth, Color borderColor ) { + private static void setupRoundedBorderImpl( NonFlashingPopup popup, + Window popupWindow, int borderCornerRadius, float borderWidth, Color borderColor ) + { if( SystemInfo.isWindows ) { // get native window handle long hwnd = FlatNativeWindowsLibrary.getHWND( popupWindow ); @@ -433,6 +444,12 @@ private static void setupRoundedBorderImpl( Window popupWindow, int borderCorner // set corner radius, border width and color FlatNativeMacLibrary.setWindowRoundedBorder( popupWindow, borderCornerRadius, borderWidth, (borderColor != null) ? borderColor.getRGB() : 0 ); + } else if( SystemInfo.isLinux ) { + if( popupWindow instanceof RootPaneContainer ) { + popup.windowRoundedBorder = new FlatWindowRoundedBorder( + ((RootPaneContainer)popupWindow).getRootPane(), + borderCornerRadius, borderWidth, borderColor ); + } } } @@ -465,7 +482,7 @@ private static float getRoundedBorderWidth( Component owner, Component contents "Popup.roundedBorderWidth"; Object value = getOption( owner, contents, FlatClientProperties.POPUP_ROUNDED_BORDER_WIDTH, uiKey ); - return (value instanceof Number) ? ((Number)value).floatValue() : 0; + return (value instanceof Number) ? ((Number)value).floatValue() : 1; } //---- fixes -------------------------------------------------------------- @@ -578,6 +595,7 @@ private class NonFlashingPopup // heavy weight Window popupWindow; private Color oldPopupWindowBackground; + private FlatWindowRoundedBorder windowRoundedBorder; private boolean disposed; @@ -603,6 +621,7 @@ private NonFlashingPopup( NonFlashingPopup reusePopup ) { contents = reusePopup.contents; popupWindow = reusePopup.popupWindow; oldPopupWindowBackground = reusePopup.oldPopupWindowBackground; + windowRoundedBorder = reusePopup.windowRoundedBorder; } NonFlashingPopup cloneForReuse() { @@ -674,6 +693,11 @@ void hideImpl() { contents = null; } + if( windowRoundedBorder != null ) { + windowRoundedBorder.uninstall(); + windowRoundedBorder = null; + } + if( popupWindow != null ) { // restore background so that it can not affect other LaFs (when switching) // because popup windows are cached and reused diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java index 706e45460..17c247a13 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java @@ -411,7 +411,8 @@ public static boolean isFullScreen( Component c ) { GraphicsConfiguration gc = c.getGraphicsConfiguration(); GraphicsDevice gd = (gc != null) ? gc.getDevice() : null; Window fullScreenWindow = (gd != null) ? gd.getFullScreenWindow() : null; - return (fullScreenWindow != null && fullScreenWindow == SwingUtilities.windowForComponent( c )); + return (fullScreenWindow != null && + (fullScreenWindow == c || fullScreenWindow == SwingUtilities.windowForComponent( c ))); } public static Boolean isRoundRect( Component c ) { diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowRoundedBorder.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowRoundedBorder.java new file mode 100644 index 000000000..33b6d1971 --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowRoundedBorder.java @@ -0,0 +1,361 @@ +/* + * Copyright 2025 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf.ui; + +import static javax.swing.SwingConstants.*; +import java.awt.Color; +import java.awt.Container; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.IllegalComponentStateException; +import java.awt.Shape; +import java.awt.Window; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.geom.Area; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.RoundRectangle2D; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.JComponent; +import javax.swing.JLayeredPane; +import javax.swing.JRootPane; +import com.formdev.flatlaf.util.UIScale; + +/** + * Rounded border for {@link Window}. + * Used for popups and for FlatLaf window decorations. + *

    + * Border is painted only if window is not maximized (in both directions) and + * not in full screen mode. If maximized in one direction (vertically or horizontally), + * then a square border is painted. + *

    + * Note: The rootpane of the window should have a {@link FlatEmptyBorder} with + * same insets as border width used in this class. + * + * @author Karl Tauber + * @since 3.6 + */ +public class FlatWindowRoundedBorder + implements PropertyChangeListener, ComponentListener +{ + protected final JRootPane rootPane; + protected final int borderCornerRadius; + protected final float borderWidth; + protected final Color borderColor; + + protected final Shape cornerShape; + + // edges + protected final RoundedBorderComponent northComp; + protected final RoundedBorderComponent southComp; + protected final RoundedBorderComponent westComp; + protected final RoundedBorderComponent eastComp; + + // corners + protected final RoundedBorderComponent northWestComp; + protected final RoundedBorderComponent northEastComp; + protected final RoundedBorderComponent southWestComp; + protected final RoundedBorderComponent southEastComp; + + protected Window window; + protected boolean windowIsRounded; + + public FlatWindowRoundedBorder( JRootPane rootPane, int borderCornerRadius, + float borderWidth, Color borderColor ) + { + this.rootPane = rootPane; + this.borderCornerRadius = borderCornerRadius; + this.borderWidth = borderWidth; + this.borderColor = borderColor; + + // create shape used to paint rounded corners + cornerShape = createCornerShape(); + + // create edges + northComp = new RoundedBorderComponent( NORTH ); + southComp = new RoundedBorderComponent( SOUTH ); + westComp = new RoundedBorderComponent( WEST ); + eastComp = new RoundedBorderComponent( EAST ); + + // create corners + northWestComp = new RoundedBorderComponent( NORTH_WEST ); + northEastComp = new RoundedBorderComponent( NORTH_EAST ); + southWestComp = new RoundedBorderComponent( SOUTH_WEST ); + southEastComp = new RoundedBorderComponent( SOUTH_EAST ); + + // insert before layered pane + int insertIndex = rootPane.getComponentCount() - 1; + JLayeredPane layeredPane = rootPane.getLayeredPane(); + for( int i = insertIndex; i >= 0; i-- ) { + if( rootPane.getComponent( insertIndex ) == layeredPane ) + break; + } + + // add edges + rootPane.add( northComp, insertIndex++ ); + rootPane.add( southComp, insertIndex++ ); + rootPane.add( westComp, insertIndex++ ); + rootPane.add( eastComp, insertIndex++ ); + + // add corners + rootPane.add( northWestComp, insertIndex++ ); + rootPane.add( northEastComp, insertIndex++ ); + rootPane.add( southWestComp, insertIndex++ ); + rootPane.add( southEastComp, insertIndex++ ); + + // add listeners + rootPane.addComponentListener( this ); + rootPane.addPropertyChangeListener( "ancestor", this ); + + if( rootPane.isDisplayable() ) + addNotify(); + else + updateVisibility(); + } + + public void uninstall() { + removeNotify(); + + // remove listeners + rootPane.removeComponentListener( this ); + rootPane.removePropertyChangeListener( "ancestor", this ); + + // remove edges + rootPane.remove( northComp ); + rootPane.remove( southComp ); + rootPane.remove( westComp ); + rootPane.remove( eastComp ); + + // remove corners + rootPane.remove( northWestComp ); + rootPane.remove( northEastComp ); + rootPane.remove( southWestComp ); + rootPane.remove( southEastComp ); + } + + public void doLayout() { + if( !northComp.isVisible() ) + return; + + int x = 0; + int y = 0; + int width = rootPane.getWidth(); + int height = rootPane.getHeight(); + if( width <= 0 || height <= 0 ) + return; + + // for layout, round-up scaled border width and radius to ensure that components are large enough + int lineWidth = (int) Math.ceil( UIScale.scale( borderWidth ) ); + int cornerSize = (windowIsRounded && lineWidth > 0) + ? (int) Math.ceil( UIScale.scale( (float) borderCornerRadius ) ) + : 0; + int cornerSize2x = cornerSize * 2; + + // edges + northComp.setBounds( x + cornerSize, y, width - cornerSize2x, lineWidth ); + southComp.setBounds( x + cornerSize, y + height - lineWidth, width - cornerSize2x, lineWidth ); + westComp.setBounds( x, y + cornerSize, lineWidth, height - cornerSize2x ); + eastComp.setBounds( x + width - lineWidth, y + cornerSize, lineWidth, height - cornerSize2x ); + + // corners + northWestComp.setBounds( x, y, cornerSize, cornerSize ); + northEastComp.setBounds( x + width - cornerSize, y, cornerSize, cornerSize ); + southWestComp.setBounds( x, y + height - cornerSize, cornerSize, cornerSize ); + southEastComp.setBounds( x + width - cornerSize, y + height - cornerSize, cornerSize, cornerSize ); + } + + protected void addNotify() { + Container parent = rootPane.getParent(); + window = (parent instanceof Window) ? (Window) parent : null; + + updateVisibility(); + updateWindowShape(); + doLayout(); + } + + protected void removeNotify() { + if( window != null ) { + window.setShape( null ); + window = null; + } + + updateVisibility(); + } + + protected void updateVisibility() { + boolean visible = needsBorder(); + if( visible == northComp.isVisible() ) + return; + + // edges + northComp.setVisible( visible ); + southComp.setVisible( visible ); + westComp.setVisible( visible ); + eastComp.setVisible( visible ); + + // corners + northWestComp.setVisible( visible ); + northEastComp.setVisible( visible ); + southWestComp.setVisible( visible ); + southEastComp.setVisible( visible ); + } + + protected boolean needsBorder() { + if( window == null || FlatUIUtils.isFullScreen( window ) ) + return false; + if( window instanceof Frame ) + return (((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) != Frame.MAXIMIZED_BOTH; + return true; + } + + protected void updateWindowShape() { + windowIsRounded = false; + + if( window == null ) + return; + + if( !northComp.isVisible() || + (window instanceof Frame && (((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0) ) + { + window.setShape( null ); + return; + } + + int arc = UIScale.scale( borderCornerRadius * 2 ); + + // use a slightly smaller arc for the shape so that at least parts of + // the antialiased arc outside are shown + arc -= 2; + + if( arc > 0 ) { + try { + window.setShape( new RoundRectangle2D.Float( 0, 0, + rootPane.getWidth(), rootPane.getHeight(), arc, arc ) ); + windowIsRounded = true; + } catch( IllegalComponentStateException | UnsupportedOperationException ex ) { + window.setShape( null ); + } + } else + window.setShape( null ); + } + + protected Shape createCornerShape() { + float lineWidth = UIScale.scale( borderWidth ); + int arc = UIScale.scale( borderCornerRadius * 2 ); + int wh = arc * 3; + float innerArc = arc - (lineWidth * 2); + float innerWH = wh - (lineWidth * 2); + + Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD ); + path.append( new RoundRectangle2D.Float( 0, 0, wh, wh, arc, arc ), false ); + path.append( new RoundRectangle2D.Float( lineWidth, lineWidth, innerWH, innerWH, innerArc, innerArc ), false ); + + Area area = new Area( path ); + int cornerSize = (int) Math.ceil( UIScale.scale( (float) borderCornerRadius ) ); + area.intersect( new Area( new Rectangle2D.Float( 0, 0, cornerSize, cornerSize ) ) ); + return area; + } + + //---- interface PropertyChangeListener ---- + + @Override + public void propertyChange( PropertyChangeEvent e ) { + switch( e.getPropertyName() ) { + case "ancestor": + if( e.getNewValue() != null ) + addNotify(); + else + removeNotify(); + break; + } + } + + //---- interface ComponentListener ---- + + @Override + public void componentResized( ComponentEvent e ) { + updateVisibility(); + updateWindowShape(); + doLayout(); + } + + @Override public void componentMoved( ComponentEvent e ) {} + @Override public void componentShown( ComponentEvent e ) {} + @Override public void componentHidden( ComponentEvent e ) {} + + //---- class RoundedBorderComponent --------------------------------------- + + protected class RoundedBorderComponent + extends JComponent + { + private final int position; + + protected RoundedBorderComponent( int position ) { + this.position = position; + } + + @Override + public void paint( Graphics g ) { + Graphics2D g2 = (Graphics2D) g; + int width = getWidth(); + int height = getHeight(); + float lineWidth = UIScale.scale( borderWidth ); + +/*debug + g.setColor( java.awt.Color.green ); + g.drawRect( 0, 0, width - 1, height - 1 ); +debug*/ + + Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g ); + + g.setColor( borderColor ); + switch( position ) { + case NORTH: g2.fill( new Rectangle2D.Float( 0, 0, width, lineWidth ) ); break; + case SOUTH: g2.fill( new Rectangle2D.Float( 0, height - lineWidth, width, lineWidth ) ); break; + case WEST: g2.fill( new Rectangle2D.Float( 0, 0, lineWidth, height ) ); break; + case EAST: g2.fill( new Rectangle2D.Float( width - lineWidth, 0, lineWidth, height ) ); break; + + case NORTH_WEST: + g2.fill( cornerShape ); + break; + + case NORTH_EAST: + g2.translate( width, 0 ); + g2.rotate( Math.toRadians( 90 ) ); + g2.fill( cornerShape ); + break; + + case SOUTH_WEST: + g2.translate( 0, height ); + g2.rotate( Math.toRadians( -90 ) ); + g2.fill( cornerShape ); + break; + + case SOUTH_EAST: + g2.translate( width, height ); + g2.rotate( Math.toRadians( 180 ) ); + g2.fill( cornerShape ); + break; + } + + FlatUIUtils.resetRenderingHints( g, oldRenderingHints ); + } + } +} diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties index e6a3413d4..95e6b3cde 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties @@ -246,7 +246,6 @@ PasswordField.revealIconColor = @foreground #---- Popup ---- -[mac]Popup.roundedBorderWidth = 1 Popup.dropShadowColor = #000 Popup.dropShadowOpacity = 0.25 diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index c39995ffd..6e2346b87 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -289,7 +289,7 @@ ComboBox.popupInsets = 0,0,0,0 ComboBox.selectionInsets = 0,0,0,0 ComboBox.selectionArc = 0 ComboBox.borderCornerRadius = $Popup.borderCornerRadius -[mac]ComboBox.roundedBorderWidth = $Popup.roundedBorderWidth +ComboBox.roundedBorderWidth = $Popup.roundedBorderWidth #---- Component ---- @@ -506,7 +506,7 @@ PasswordField.revealIcon = com.formdev.flatlaf.icons.FlatRevealIcon #---- Popup ---- Popup.borderCornerRadius = 4 -[mac]Popup.roundedBorderWidth = 0 +Popup.roundedBorderWidth = 1 Popup.dropShadowPainted = true Popup.dropShadowInsets = -4,-4,4,4 @@ -516,7 +516,7 @@ Popup.dropShadowInsets = -4,-4,4,4 PopupMenu.border = com.formdev.flatlaf.ui.FlatPopupMenuBorder PopupMenu.borderInsets = 4,1,4,1 PopupMenu.borderCornerRadius = $Popup.borderCornerRadius -[mac]PopupMenu.roundedBorderWidth = $Popup.roundedBorderWidth +PopupMenu.roundedBorderWidth = $Popup.roundedBorderWidth PopupMenu.background = @menuBackground PopupMenu.scrollArrowColor = @buttonArrowColor @@ -913,7 +913,7 @@ ToolTipManager.enableToolTipMode = activeApplication #---- ToolTip ---- ToolTip.borderCornerRadius = $Popup.borderCornerRadius -[mac]ToolTip.roundedBorderWidth = $Popup.roundedBorderWidth +ToolTip.roundedBorderWidth = $Popup.roundedBorderWidth #---- Tree ---- diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties index 272c965dc..eedbef10e 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties @@ -253,6 +253,7 @@ PasswordField.revealIconColor = tint(@foreground,40%) #---- Popup ---- +[mac]Popup.roundedBorderWidth = 0 Popup.dropShadowColor = #000 Popup.dropShadowOpacity = 0.15 diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-mac.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-mac.txt index 7f0d7d077..9b49ba2f1 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-mac.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-mac.txt @@ -1,12 +1,11 @@ - Java 1.8.0_202 -+ Java 1.8.0_292 ++ Java 1.8.0_322 - OS Windows 10 + OS Mac OS X #---- ComboBox ---- -+ ComboBox.roundedBorderWidth 1 + ComboBox.showPopupOnNavigation true @@ -47,16 +46,6 @@ + OptionPane.isYesLast true -#---- Popup ---- - -+ Popup.roundedBorderWidth 1 - - -#---- PopupMenu ---- - -+ PopupMenu.roundedBorderWidth 1 - - #---- ProgressBar ---- - ProgressBar.font [active] Segoe UI plain 10 javax.swing.plaf.FontUIResource [UI] @@ -88,11 +77,6 @@ - TitlePane.small.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI] + TitlePane.small.font [active] Helvetica Neue plain 12 javax.swing.plaf.FontUIResource [UI] - - -#---- ToolTip ---- - -+ ToolTip.roundedBorderWidth 1 - defaultFont Segoe UI plain 12 javax.swing.plaf.FontUIResource [UI] + defaultFont Helvetica Neue plain 13 javax.swing.plaf.FontUIResource [UI] diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt index a8cf18904..4933d59fc 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt @@ -222,6 +222,7 @@ ComboBox.minimumWidth 72 ComboBox.noActionOnKeyNavigation false ComboBox.padding 2,6,2,6 javax.swing.plaf.InsetsUIResource [UI] ComboBox.popupInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] +ComboBox.roundedBorderWidth 1 ComboBox.selectionArc 0 ComboBox.selectionBackground #4b6eaf HSL 219 40 49 javax.swing.plaf.ColorUIResource [UI] ComboBox.selectionForeground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI] @@ -744,6 +745,7 @@ Popup.dropShadowColor #000000 HSL 0 0 0 javax.swing.plaf.Colo Popup.dropShadowInsets -4,-4,4,4 javax.swing.plaf.InsetsUIResource [UI] Popup.dropShadowOpacity 0.25 Popup.dropShadowPainted true +Popup.roundedBorderWidth 1 #---- PopupMenu ---- @@ -757,6 +759,7 @@ PopupMenu.consumeEventOnClose false PopupMenu.font [active] $defaultFont [UI] PopupMenu.foreground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI] PopupMenu.hoverScrollArrowBackground #484c4e HSL 200 4 29 javax.swing.plaf.ColorUIResource [UI] +PopupMenu.roundedBorderWidth 1 PopupMenu.scrollArrowColor #9b9b9b HSL 0 0 61 javax.swing.plaf.ColorUIResource [UI] @@ -1375,6 +1378,7 @@ ToolTip.border [lazy] 4,6,4,6 false com.formdev.flatlaf.ui.F ToolTip.borderCornerRadius 4 ToolTip.font [active] $defaultFont [UI] ToolTip.foreground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI] +ToolTip.roundedBorderWidth 1 #---- ToolTipManager ---- diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-mac.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-mac.txt index 46d779b22..3ec1ff3ee 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-mac.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-mac.txt @@ -1,12 +1,14 @@ - Java 1.8.0_202 -+ Java 1.8.0_292 ++ Java 1.8.0_322 - OS Windows 10 + OS Mac OS X #---- ComboBox ---- +- ComboBox.roundedBorderWidth 1 + ComboBox.roundedBorderWidth 0 + + ComboBox.showPopupOnNavigation true @@ -49,11 +51,13 @@ #---- Popup ---- +- Popup.roundedBorderWidth 1 + Popup.roundedBorderWidth 0 #---- PopupMenu ---- +- PopupMenu.roundedBorderWidth 1 + PopupMenu.roundedBorderWidth 0 @@ -92,6 +96,7 @@ #---- ToolTip ---- +- ToolTip.roundedBorderWidth 1 + ToolTip.roundedBorderWidth 0 - defaultFont Segoe UI plain 12 javax.swing.plaf.FontUIResource [UI] + defaultFont Helvetica Neue plain 13 javax.swing.plaf.FontUIResource [UI] diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt index e366fe1d0..d6c76f8d7 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt @@ -226,6 +226,7 @@ ComboBox.minimumWidth 72 ComboBox.noActionOnKeyNavigation false ComboBox.padding 2,6,2,6 javax.swing.plaf.InsetsUIResource [UI] ComboBox.popupInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] +ComboBox.roundedBorderWidth 1 ComboBox.selectionArc 0 ComboBox.selectionBackground #2675bf HSL 209 67 45 javax.swing.plaf.ColorUIResource [UI] ComboBox.selectionForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] @@ -749,6 +750,7 @@ Popup.dropShadowColor #000000 HSL 0 0 0 javax.swing.plaf.Colo Popup.dropShadowInsets -4,-4,4,4 javax.swing.plaf.InsetsUIResource [UI] Popup.dropShadowOpacity 0.15 Popup.dropShadowPainted true +Popup.roundedBorderWidth 1 #---- PopupMenu ---- @@ -762,6 +764,7 @@ PopupMenu.consumeEventOnClose false PopupMenu.font [active] $defaultFont [UI] PopupMenu.foreground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI] PopupMenu.hoverScrollArrowBackground #e5e5e5 HSL 0 0 90 javax.swing.plaf.ColorUIResource [UI] +PopupMenu.roundedBorderWidth 1 PopupMenu.scrollArrowColor #666666 HSL 0 0 40 javax.swing.plaf.ColorUIResource [UI] @@ -1380,6 +1383,7 @@ ToolTip.border [lazy] 4,6,4,6 false com.formdev.flatlaf.ui.F ToolTip.borderCornerRadius 4 ToolTip.font [active] $defaultFont [UI] ToolTip.foreground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI] +ToolTip.roundedBorderWidth 1 #---- ToolTipManager ---- diff --git a/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt index af6ef1bfc..d901d11a2 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt @@ -228,6 +228,7 @@ ComboBox.noActionOnKeyNavigation false ComboBox.padding 2,6,2,6 javax.swing.plaf.InsetsUIResource [UI] ComboBox.popupBackground #323232 HSL 0 0 20 javax.swing.plaf.ColorUIResource [UI] ComboBox.popupInsets 5,0,5,0 javax.swing.plaf.InsetsUIResource [UI] +ComboBox.roundedBorderWidth 1 ComboBox.selectionArc 8 ComboBox.selectionBackground #1458b8 HSL 215 80 40 javax.swing.plaf.ColorUIResource [UI] ComboBox.selectionForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] @@ -752,6 +753,7 @@ Popup.dropShadowColor #000000 HSL 0 0 0 javax.swing.plaf.Colo Popup.dropShadowInsets -4,-4,4,4 javax.swing.plaf.InsetsUIResource [UI] Popup.dropShadowOpacity 0.25 Popup.dropShadowPainted true +Popup.roundedBorderWidth 1 #---- PopupMenu ---- @@ -765,6 +767,7 @@ PopupMenu.consumeEventOnClose false PopupMenu.font [active] $defaultFont [UI] PopupMenu.foreground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI] PopupMenu.hoverScrollArrowBackground #2b2b2b HSL 0 0 17 javax.swing.plaf.ColorUIResource [UI] +PopupMenu.roundedBorderWidth 1 PopupMenu.scrollArrowColor #b7b7b7 HSL 0 0 72 javax.swing.plaf.ColorUIResource [UI] @@ -1385,6 +1388,7 @@ ToolTip.border [lazy] 4,6,4,6 false com.formdev.flatlaf.ui.F ToolTip.borderCornerRadius 4 ToolTip.font [active] $defaultFont [UI] ToolTip.foreground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI] +ToolTip.roundedBorderWidth 1 #---- ToolTipManager ---- diff --git a/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt index 6f03f1113..b02e488b6 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt @@ -232,6 +232,7 @@ ComboBox.noActionOnKeyNavigation false ComboBox.padding 2,6,2,6 javax.swing.plaf.InsetsUIResource [UI] ComboBox.popupBackground #ececec HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI] ComboBox.popupInsets 5,0,5,0 javax.swing.plaf.InsetsUIResource [UI] +ComboBox.roundedBorderWidth 1 ComboBox.selectionArc 8 ComboBox.selectionBackground #3d9aff HSL 211 100 62 javax.swing.plaf.ColorUIResource [UI] ComboBox.selectionForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] @@ -756,6 +757,7 @@ Popup.dropShadowColor #000000 HSL 0 0 0 javax.swing.plaf.Colo Popup.dropShadowInsets -4,-4,4,4 javax.swing.plaf.InsetsUIResource [UI] Popup.dropShadowOpacity 0.15 Popup.dropShadowPainted true +Popup.roundedBorderWidth 1 #---- PopupMenu ---- @@ -769,6 +771,7 @@ PopupMenu.consumeEventOnClose false PopupMenu.font [active] $defaultFont [UI] PopupMenu.foreground #262626 HSL 0 0 15 javax.swing.plaf.ColorUIResource [UI] PopupMenu.hoverScrollArrowBackground #e9e9e9 HSL 0 0 91 javax.swing.plaf.ColorUIResource [UI] +PopupMenu.roundedBorderWidth 1 PopupMenu.scrollArrowColor #7d7d7d HSL 0 0 49 javax.swing.plaf.ColorUIResource [UI] @@ -1389,6 +1392,7 @@ ToolTip.border [lazy] 4,6,4,6 false com.formdev.flatlaf.ui.F ToolTip.borderCornerRadius 4 ToolTip.font [active] $defaultFont [UI] ToolTip.foreground #262626 HSL 0 0 15 javax.swing.plaf.ColorUIResource [UI] +ToolTip.roundedBorderWidth 1 #---- ToolTipManager ---- diff --git a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt index 74a70884f..9dba3ea31 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt @@ -254,6 +254,7 @@ ComboBox.noActionOnKeyNavigation false ComboBox.padding 2,6,2,6 javax.swing.plaf.InsetsUIResource [UI] ComboBox.popupBackground #ffffcc HSL 60 100 90 javax.swing.plaf.ColorUIResource [UI] ComboBox.popupInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] +ComboBox.roundedBorderWidth 1 ComboBox.selectionArc 0 ComboBox.selectionBackground #00aa00 HSL 120 100 33 javax.swing.plaf.ColorUIResource [UI] ComboBox.selectionForeground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI] @@ -782,6 +783,7 @@ Popup.dropShadowColor #00ff00 HSL 120 100 50 javax.swing.plaf.Colo Popup.dropShadowInsets -6,6,6,6 javax.swing.plaf.InsetsUIResource [UI] Popup.dropShadowOpacity 0.5 Popup.dropShadowPainted true +Popup.roundedBorderWidth 1 #---- PopupMenu ---- @@ -795,6 +797,7 @@ PopupMenu.consumeEventOnClose false PopupMenu.font [active] $defaultFont [UI] PopupMenu.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI] PopupMenu.hoverScrollArrowBackground #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI] +PopupMenu.roundedBorderWidth 1 PopupMenu.scrollArrowColor #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI] @@ -1438,6 +1441,7 @@ ToolTip.border [lazy] line: #000000 HSL 0 0 0 java.awt ToolTip.borderCornerRadius 4 ToolTip.font [active] $defaultFont [UI] ToolTip.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI] +ToolTip.roundedBorderWidth 1 #---- ToolTipManager ----