[macOS] Shown ContextMenu does not close when macOS system menu is clicked

XMLWordPrintable

    • generic
    • os_x

      ADDITIONAL SYSTEM INFORMATION :
      The JDK version where the issue started appearing/occurring
      JDK 26, JDK, 25.0.1
      javafx 26-ea+14


      A DESCRIPTION OF THE PROBLEM :
      Detailed explanation of the problem, including any error messages
      The context menu remains open even after the node that owns the menu is no longer in the scene.
      The bug only occurs when using the macOS system menu item, which hides the node the ContextMenu belongs to, then the ContextMenu is still visible.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      A clear set of steps to reproduce the issue/reproducible test case
      Start the attached ContextMenuApp on macOS. Right click on "View one: right click for context menu" and while the ContextMenu is shown, click on system menu "View / View two".

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The shown ContextMenu should be hidden.
      ACTUAL -
      The ContextMenu is still visible but the node it belongs to is no longer there. If the user now uses the ContextMenuItem it will lead to exceptions as the underling node it belongs to is not present in the scene anymore.

      ---------- BEGIN SOURCE ----------
      package org.openjfx;

      import javafx.application.Application;
      import javafx.scene.Scene;
      import javafx.scene.control.Alert;
      import javafx.scene.control.ContextMenu;
      import javafx.scene.control.Label;
      import javafx.scene.control.Menu;
      import javafx.scene.control.MenuBar;
      import javafx.scene.control.MenuItem;
      import javafx.scene.layout.BorderPane;
      import javafx.stage.Stage;

      public class ContextMenuApp extends Application {

          @Override
          public void start(Stage stage) {
              BorderPane root = new BorderPane();

              // ----- View 1 and View 2
              Label label = new Label("View one: right click for context menu");
              label.setId("labelWithContextMenu");
              Label label2 = new Label("View two");
              root.setCenter(label);

              // ----- ContextMenu
              ContextMenu contextMenu = new ContextMenu();
              contextMenu.setId("contextMenu");
              MenuItem item = new MenuItem("Action of view one");
              item.setOnAction(event -> {
                  if (root.getCenter() != label) {
                      throw new IllegalStateException("The view one that the action belongs to is no longer visible!" +
                              "\n\nJavaFX Bug: it was expected that, when a system menu item was pressed, the context menu would be hidden.");
                  } else {
                      new Alert(Alert.AlertType.INFORMATION, "Action of view one executed successfully").show();
                  }
              });
              contextMenu.getItems().add(item);
              label.setContextMenu(contextMenu);

              // ----- Main Menu
              MenuBar menuBar = new MenuBar();
              Menu menu = new Menu("View");
              menuBar.getMenus().add(menu);
              MenuItem item1 = new MenuItem("View one");
              MenuItem item2 = new MenuItem("View two");
              item1.setOnAction(event -> {
                  root.setCenter(label);
              });
              item2.setOnAction(event -> {
                  root.setCenter(label2);
              });
              menu.getItems().add(item1);
              menu.getItems().add(item2);
              menuBar.setUseSystemMenuBar(true);
              root.setTop(menuBar);

              // ----- Scene
              Scene scene = new Scene(root);
              stage.setScene(scene);
              stage.setWidth(300);
              stage.setHeight(200);
              stage.show();
          }

          private static class ContextMenuAppMain {

              public static void main(String[] args) {
                  launch(ContextMenuApp.class, args);
              }
          }
      }


      package org.openjfx;

      import org.junit.jupiter.api.Test;
      import org.testfx.framework.junit5.ApplicationTest;

      import javafx.scene.input.KeyCode;
      import javafx.stage.Stage;

      /**
       * Navigate to Apple menu > System Preferences > Security & Privacy > Privacy > Accessibility
       * Click the lock and enter your password to change these settings
       * If terminal or IntelliJ IDEA or any other IDE you used to start this Unittest has requested accessibility features before it should show in the list
       * If not, add it by clicking + and selecting Applications > Utilities > Terminal
       */
      public class ContextMenuTest extends ApplicationTest {

          @Override
          public void start(Stage stage) {
              ContextMenuApp contextMenuApp = new ContextMenuApp();
              contextMenuApp.start(stage);
          }

          @Test
          public void contextMenuTest() throws Exception {
              System.out.println("Navigate to Apple menu > System Preferences > Security & Privacy > Privacy > Accessibility" +
                  "\nClick the lock and enter your password to change these settings" +
                  "\nIf terminal or IntelliJ IDEA or any other IDE you used to start this Unittest has requested accessibility features before it should show in the list" +
                  "\nIf not, add it by clicking + and selecting Applications > Utilities > Terminal");
              rightClickOn("#labelWithContextMenu");
              String[] command = { "osascript", "-e", "tell application \"System Events\"\ntell (first process whose frontmost is true)\nclick menu item 2 of menu 3 of menu bar 1\nend tell\nend tell"};
              Process process = new ProcessBuilder(command).start();
              process.waitFor();
              //JavaFX Bug: it was expected that, when a system menu item was pressed, the context menu would be hidden.
              push(KeyCode.ENTER);
          }
      }
      ---------- END SOURCE ----------

            Assignee:
            Andy Goryachev
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: