openjdk-jfx
openjdk-jfx copied to clipboard
Accelerator + System MenuBar
Background
If the accelerator set on a MenuItem, placed on a MenuBar, is similar to the key events pre-defined on a control, the accelerator shouldn't fire the action of the MenuItem. This can be observed in edit actions of a TextInputControl
. When an edit action (like copy, paste etc.) are defined as actions on a MenuItem using KeyEvent(s), these are only fired when the focus is not on a TextInputControl
.
Bug
The above mentioned contract is invalid when useSystemMenuBar
property of the MenuBar
is set to true
on a mac. In case of a system menu bar, actions like paste ( CMD+V ) triggers the event for both TextInputControl
and MenuItem
.
The following example can be used to reproduce the issue on a mac:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class MenuBarAcceleratorBug extends Application {
@Override
public void start(Stage stage) {
TextField textField = new TextField();
MenuItem paste = new MenuItem("Paste");
paste.setOnAction(e -> textField.paste());
paste.setAccelerator(new KeyCodeCombination(KeyCode.V, KeyCombination.META_DOWN));
Menu menu = new Menu("Edit");
menu.getItems().add(paste);
MenuBar menuBar = new MenuBar(menu);
menuBar.setUseSystemMenuBar(true);
BorderPane pane = new BorderPane(textField);
pane.setTop(menuBar);
stage.setScene(new Scene(pane, 300, 200));
stage.show();
}
}
Here is the original issue found https://github.com/gluonhq/scenebuilder/issues/221
So, yes, the bug can be easily reproduced
The problem is in - (BOOL)performKeyEquivalent:(NSEvent *)theEvent
in native-glass/mac/GlassView3D.m
That method always return NO
, allowing the regular key processing to do its work. In case the action is processed by the application, we should return YES
here.
The bug is still present in javafx15, the only option is to use a workaround and filter out the first event. https://bugs.openjdk.java.net/browse/JDK-8205915