Popup:
Some checks failed
CI / build (11) (push) Has been cancelled
CI / build-on (17, ) (push) Has been cancelled
CI / build-on (21, ) (push) Has been cancelled
CI / build-on (23, ) (push) Has been cancelled
CI / build-on (8, ) (push) Has been cancelled
CI / snapshot (push) Has been cancelled
CI / release (push) Has been cancelled

- macOS: Fixed popup flickering after theme change. (issue #1009)
- macOS with JetBrains Runtime: Fixed sometimes empty popups. (issue #1019)
This commit is contained in:
Karl Tauber
2025-07-07 18:33:49 +02:00
parent 34b19f00e4
commit ff722c0b34
2 changed files with 41 additions and 1 deletions

View File

@@ -15,6 +15,8 @@ FlatLaf Change Log
- Linux: Popups appeared in wrong position on multi-screen setup if primary
display is located below or right to secondary display. (see
[NetBeans issue #8532](https://github.com/apache/netbeans/issues/8532))
- macOS: Fixed popup flickering after theme change. (issue #1009)
- macOS with JetBrains Runtime: Fixed sometimes empty popups. (issue #1019)
## 3.6

View File

@@ -618,6 +618,29 @@ public class FlatPopupFactory
void showImpl() {
if( delegate != null ) {
// On macOS and Linux, the empty popup window is shown in popup.show()
// (in peer.setVisible(true) invoked from Component.show()),
// but the popup content is painted later via repaint manager.
// This may cause some flicker, especially during JVM warm-up or
// when running JVM in interpreter mode (option -Xint).
// To reduce flicker, immediately paint popup content as soon as popup window becomes visible.
// This also fixes a problem with JetBrainsRuntime JVM, where sometimes the popups were empty.
if( (SystemInfo.isMacOS || SystemInfo.isLinux) && popupWindow instanceof JWindow ) {
HierarchyListener l = e -> {
if( e.getID() == HierarchyEvent.HIERARCHY_CHANGED &&
(e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 )
{
((JWindow)popupWindow).getRootPane().paintImmediately(
0, 0, popupWindow.getWidth(), popupWindow.getHeight() );
}
};
popupWindow.addHierarchyListener( l );
try {
showPopupAndFixLocation( delegate, popupWindow );
} finally {
popupWindow.removeHierarchyListener( l );
}
} else
showPopupAndFixLocation( delegate, popupWindow );
// increase tooltip size if necessary because it may be too small on HiDPI screens
@@ -677,6 +700,21 @@ public class FlatPopupFactory
// restore background so that it can not affect other LaFs (when switching)
// because popup windows are cached and reused
popupWindow.setBackground( oldPopupWindowBackground );
// On macOS, popupWindow.setBackground(...) invoked from constructor,
// has no affect if the popup window peer (a NSWindow) is already created,
// which is the case when reusing a cached popup window
// (see class PopupFactory.HeavyWeightPopup).
// This may result in flicker when e.g. showing a popup in a light theme,
// then switching to a dark theme and again showing a popup,
// because the underling NSWindow still has a light background,
// which may be shown shortly before the actual dark popup content is shown.
// To fix this, dispose the popup window, which disposes the NSWindow.
// The AWT popup window stays in the popup cache, but when reusing it later,
// a new peer and a new NSWindow is created and gets the correct background.
if( SystemInfo.isMacOS )
popupWindow.dispose();
popupWindow = null;
}
}