Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* <li><strong>macOS</strong> (10.14 and later): Any corner radius is supported.
* <li><strong>Linux</strong> (since FlatLaf 3.6): Any corner radius is supported.
* </ul>
* <strong>Component</strong> {@link javax.swing.JComponent}<br>
* <strong>Value type</strong> {@link java.lang.Integer}<br>
Expand All @@ -402,6 +403,7 @@ public interface FlatClientProperties
* Supported platforms:
* <ul>
* <li><strong>macOS</strong> (10.14 and later)
* <li><strong>Linux</strong> (since FlatLaf 3.6)
* </ul>
* <strong>Component</strong> {@link javax.swing.JComponent}<br>
* <strong>Value type</strong> {@link java.lang.Integer} or {@link java.lang.Float}<br>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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 );

Expand All @@ -397,23 +406,25 @@ 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<HierarchyListener> l = new AtomicReference<>();
l.set( e -> {
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() );
}
} );
popupWindow.addHierarchyListener( l.get() );
}
}

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 );
Expand All @@ -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 );
}
}
}

Expand Down Expand Up @@ -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 --------------------------------------------------------------
Expand Down Expand Up @@ -578,6 +595,7 @@ private class NonFlashingPopup
// heavy weight
Window popupWindow;
private Color oldPopupWindowBackground;
private FlatWindowRoundedBorder windowRoundedBorder;

private boolean disposed;

Expand All @@ -603,6 +621,7 @@ private NonFlashingPopup( NonFlashingPopup reusePopup ) {
contents = reusePopup.contents;
popupWindow = reusePopup.popupWindow;
oldPopupWindowBackground = reusePopup.oldPopupWindowBackground;
windowRoundedBorder = reusePopup.windowRoundedBorder;
}

NonFlashingPopup cloneForReuse() {
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand Down
Loading
Loading