From 8089e66642ad3a3406768ca153d8f9c176f9c8e1 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 5 Aug 2024 13:56:43 +0200 Subject: [PATCH] SubMenuUsabilityHelper: added system property `flatlaf.useSubMenuSafeTriangle` to allow disabling submenu safe triangle for SWTSwing (issue #870) also check whether EventQueue.push() succeeded; if not, disable submenu safe triangle --- CHANGELOG.md | 3 ++ .../formdev/flatlaf/FlatSystemProperties.java | 9 +++++ .../flatlaf/SubMenuUsabilityHelper.java | 34 ++++++++++++++++--- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ff6cf1a..0375d248 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ FlatLaf Change Log window. (issue #869) - HiDPI: Fixed occasional wrong repaint areas when using `HiDPIUtils.installHiDPIRepaintManager()`. (see PR #864) +- Added system property `flatlaf.useSubMenuSafeTriangle` to allow disabling + submenu safe triangle (PR #490) for + [SWTSwing](https://github.com/Chrriis/SWTSwing). (issue #870) ## 3.5 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatSystemProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatSystemProperties.java index d0ce1907..956c2b9e 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatSystemProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatSystemProperties.java @@ -204,6 +204,15 @@ public interface FlatSystemProperties */ String NATIVE_LIBRARY_PATH = "flatlaf.nativeLibraryPath"; + /** + * Specifies whether safe triangle is used to improve usability of submenus. + *

+ * Allowed Values {@code false} and {@code true}
+ * Default {@code true} + * @since 3.5.1 + */ + String USE_SUB_MENU_SAFE_TRIANGLE = "flatlaf.useSubMenuSafeTriangle"; + /** * Checks whether a system property is set and returns {@code true} if its value * is {@code "true"} (case-insensitive), otherwise it returns {@code false}. diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/SubMenuUsabilityHelper.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/SubMenuUsabilityHelper.java index d4b4515d..f8e1b784 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/SubMenuUsabilityHelper.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/SubMenuUsabilityHelper.java @@ -45,6 +45,7 @@ import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import com.formdev.flatlaf.ui.FlatUIUtils; +import com.formdev.flatlaf.util.LoggingFacade; /** * Improves usability of submenus by using a @@ -64,6 +65,7 @@ class SubMenuUsabilityHelper // https://github.com/apache/netbeans/issues/4231#issuecomment-1179616607 private static SubMenuUsabilityHelper instance; + private boolean eventQueuePushNotSupported; private SubMenuEventQueue subMenuEventQueue; private SafeTrianglePainter safeTrianglePainter; private boolean changePending; @@ -83,6 +85,9 @@ class SubMenuUsabilityHelper if( instance != null ) return false; + if( !FlatSystemProperties.getBoolean( FlatSystemProperties.USE_SUB_MENU_SAFE_TRIANGLE, true ) ) + return false; + instance = new SubMenuUsabilityHelper(); MenuSelectionManager.defaultManager().addChangeListener( instance ); return true; @@ -99,7 +104,7 @@ class SubMenuUsabilityHelper @Override public void stateChanged( ChangeEvent e ) { - if( !FlatUIUtils.getUIBoolean( KEY_USE_SAFE_TRIANGLE, true )) + if( eventQueuePushNotSupported || !FlatUIUtils.getUIBoolean( KEY_USE_SAFE_TRIANGLE, true )) return; // handle menu selection change later, but only once in case of temporary changes @@ -173,8 +178,29 @@ debug*/ targetBottomY = popupLocation.y + popupSize.height; // install own event queue to suppress mouse events when mouse is moved within safe triangle - if( subMenuEventQueue == null ) - subMenuEventQueue = new SubMenuEventQueue(); + if( subMenuEventQueue == null ) { + SubMenuEventQueue queue = new SubMenuEventQueue(); + + try { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + toolkit.getSystemEventQueue().push( queue ); + + // check whether push() worked + // (e.g. SWTSwing uses own event queue that does not support push()) + if( toolkit.getSystemEventQueue() != queue ) { + eventQueuePushNotSupported = true; + LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to push submenu event queue. Disabling submenu safe triangle.", null ); + return; + } + + subMenuEventQueue = queue; + } catch( RuntimeException ex ) { + // catch runtime exception from EventQueue.push() + eventQueuePushNotSupported = true; + LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to push submenu event queue. Disabling submenu safe triangle.", ex ); + return; + } + } // create safe triangle painter if( safeTrianglePainter == null && UIManager.getBoolean( KEY_SHOW_SAFE_TRIANGLE ) ) @@ -247,8 +273,6 @@ debug*/ } } ); timeoutTimer.setRepeats( false ); - - Toolkit.getDefaultToolkit().getSystemEventQueue().push( this ); } void uninstall() {