Skip to content

Commit

Permalink
Popup: popups that request focus were not shown on Linux with Wayland…
Browse files Browse the repository at this point in the history
… and Java 21 (issue #752)
  • Loading branch information
DevCharly committed Oct 21, 2023
1 parent 0d2f37e commit 5c56dbf
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
FlatLaf Change Log
==================

## 3.2.3

#### Fixed bugs

- Popup: Popups that request focus were not shown on Linux with Wayland and Java 21.
(issue #752)


## 3.2.2

#### Fixed bugs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.WindowFocusListener;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
Expand Down Expand Up @@ -83,6 +84,8 @@ public Popup getPopup( Component owner, Component contents, int x, int y )
y = pt.y;
}

fixLinuxWaylandJava21focusIssue( owner );

boolean forceHeavyWeight = isOptionEnabled( owner, contents, FlatClientProperties.POPUP_FORCE_HEAVY_WEIGHT, "Popup.forceHeavyWeight" );

if( !isOptionEnabled( owner, contents, FlatClientProperties.POPUP_DROP_SHADOW_PAINTED, "Popup.dropShadowPainted" ) || SystemInfo.isProjector || SystemInfo.isWebswing )
Expand Down Expand Up @@ -420,6 +423,38 @@ private static boolean overlapsHeavyWeightComponent( Component parent, Rectangle
return false;
}

/**
* On Linux with Wayland, since Java 21, Swing adds a window focus listener to popup owner/invoker window,
* which hides the popup as soon as the owner/invoker window looses focus.
* This works fine for light-weight popups.
* It also works for heavy-weight popups if the do not request focus.
* Because FlatLaf always uses heavy-weight popups, all popups that request focus
* are broken since Java 21.
*
* This method removes the problematic window focus listener.
*
* https://bugs.openjdk.org/browse/JDK-8280993
* https://github.com/openjdk/jdk/pull/13830
*/
private static void fixLinuxWaylandJava21focusIssue( Component owner ) {
// only necessary on Linux when running in Java 21+
if( !SystemInfo.isLinux || SystemInfo.javaVersion < SystemInfo.toVersion( 21, 0, 0, 0 ) )
return;

// get window
Window window = SwingUtilities.getWindowAncestor( owner );
if( window == null )
return;

// remove window focus listener, which was added from class sun.awt.UNIXToolkit since Java 21
for( WindowFocusListener l : window.getWindowFocusListeners() ) {
if( "sun.awt.UNIXToolkit$1".equals( l.getClass().getName() ) ) {
window.removeWindowFocusListener( l );
break;
}
}
}

//---- class NonFlashingPopup ---------------------------------------------

private static class NonFlashingPopup
Expand Down

0 comments on commit 5c56dbf

Please sign in to comment.