JDK-8233182 : Browsers inside JavaFX panel do not consume keyboard shortcuts
  • Type: Bug
  • Component: javafx
  • Sub-Component: web
  • Affected Version: openjfx12
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: x86_64
  • Submitted: 2019-10-25
  • Updated: 2021-12-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
Java 12 Open JDK (but can be reproduced also with older Java 1.8), Windows 10

A DESCRIPTION OF THE PROBLEM :
A Swing based application has a top level menu containing a menu item with an accelerator (in this case Ctrl-V).
A JavaFX panel is added inside the Swing application, it contains an opened HTML page with a form control (a text field for example). Focus inside the text field from the JavaFX browser and press Ctrl-V, content is pasted there but the paste action from the top level menu is triggered as well. So the panel has failed to consume the local keyboard shortcut so the shortcut also triggers a menu item inside the main application.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create Swing JFrame containing a top level menu with an action having the accelerator "Ctrl-V".
Inside add a JavaFX frame with a browser which presents a text field.
Click inside the text field, ctrl-v pastes the content there but also triggers the top level paste action.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
ctrl-v inside the inner browser's text field should not trigger an action from the main menu.
ACTUAL -
ctrl-v triggers two events, the paste in the field and the action in the main menu.

---------- BEGIN SOURCE ----------
public class Test {
public static void main(String[] args) {

    JFrame fr = new JFrame();
    JTextArea jta = new JTextArea();
    jta.setPreferredSize(new Dimension(200, 200));
    fr.getContentPane().add(jta, BorderLayout.EAST);

    JFXPanel jfxPanel = new JFXPanel();
    javafx.application.Platform.runLater(new Runnable() {
		@Override
		public void run() {
			StackPane sceneLayout = new javafx.scene.layout.StackPane();
			WebView browser = new javafx.scene.web.WebView();
			browser.setContextMenuEnabled(false);
			WebEngine webengine = browser.getEngine();
			webengine.load("https://www.google.com");
			sceneLayout.getChildren().add(browser);
			Scene scene = new javafx.scene.Scene(sceneLayout);
			jfxPanel.setScene(scene);
		}
	});
    fr.getContentPane().add(new JScrollPane(jfxPanel), BorderLayout.CENTER);
    fr.getContentPane().add(new JLabel("WORKS"), BorderLayout.WEST);
    fr.setSize(800, 800);
    JMenuBar jmb = new JMenuBar();
    JMenu menu = new JMenu("bla");
    jmb.add(menu);
    AbstractAction action = new AbstractAction("PASTE") {

      @Override
      public void actionPerformed(ActionEvent e) {
        System.err.println("THIS SHOULD NOT GET TRIGGERED ...");
        new Exception().printStackTrace();
      }
    };
    action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_DOWN_MASK, false));
    menu.add(action);
    fr.setJMenuBar(jmb);
    fr.setVisible(true);
}
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Overwrite the processKeyEvent in the JavaFX panel and force consume various shortcuts:

    final JFXPanel jfxPanel = new JFXPanel(){
    	@Override
    	protected void processKeyEvent(KeyEvent e) {
    		if(e.getModifiers() == KeyEvent.CTRL_MASK && e.getKeyCode() == KeyEvent.VK_V){
    			//Consume it...
    			e.consume();
    		}
    		super.processKeyEvent(e);
    	}
    };

FREQUENCY : always



Comments
The JavaFX machinery for handling key events in a Scene doesn't currently have any way of signaling whether the event was consumed or not (in part because the event that ultimately gets consumed is a copy of the original event). This is fixable; the core changes are currently part of the PR for JDK-8273743. The real issue is that the EmbeddedScene sends the event to the sceneListener inside a runLater block. Even if the sceneListener knows that JavaFX consumed the event the Swing equivalent has already moved on.
18-12-2021

The Key pressed event creates a new keyEvent for WebView and goes on to process the events in the Swing components. This triggers common keyboard shortcuts for both swing and WebView (like moving left or right in a textfield in JFXPanel). For fixing this bug, we can synchronise the WebView call to check whether it's processed. Otherwise, we may need to check all the keyboard shortcut cases.
12-11-2019

This bug can be reproduced in Mac as well using ctrl+v
06-11-2019

This is more likely a bug in WebView or in JFXPanel rather than in the base event propagation, but it will need to be evaluated to be sure.
30-10-2019