xiruibing / javachromiumembedded

Automatically exported from code.google.com/p/javachromiumembedded
0 stars 0 forks source link

Swing Menu mnemonics not triggered when cef browser has focus #122

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Get the latest JCEF revision (r104)
2. Add the following line below to MenuBar.java
3. Compile and run. Give focus to browser. Click "Alt-F". Menu doesn't open. 
Give focus to Swing address field. Click "Alt-F". Menu opens up.

MenuBar.java
...
    JMenu fileMenu = new JMenu("File");
+   fileMenu.setMnemonic('F');

JCEF has improved greatly in the last few months. Starting to dig into the most 
minute integration issues :-)

Original issue reported on code.google.com by christop...@gmail.com on 25 Sep 2014 at 6:37

GoogleCodeExporter commented 9 years ago
If you're using a windowed browser on Windows this could be related to 
https://code.google.com/p/chromiumembedded/issues/detail?id=1387.

Original comment by magreenb...@gmail.com on 25 Sep 2014 at 6:42

GoogleCodeExporter commented 9 years ago
Yes I'm in window rendering mode.

Wondering if a fix for CEF 1387 would also work for us in JCEF. There's some 
extra stuff AWT/Swing do to manage the JMenuItem's...

Original comment by christop...@gmail.com on 25 Sep 2014 at 7:04

GoogleCodeExporter commented 9 years ago
Here's a temporary workaround until CEF bubbles events up. The idea is to 
leverage the CefKeyboardHandler. Translate specific CefKeyEvent's into AWT 
KeyEvent's, then forward those to the AWT KeyboardFocusManager. We get proper 
alt behavior for menus and can also activate any desired shortcut ctrl-s 
ctrl-f4 ctrl-shift-f4 for example.

Not saying this should go in, but I mention it in case it can help someone else.
Tested on Windows only.

        cefClient.addKeyboardHandler(new CefKeyboardHandler() {

            @Override
            public boolean onPreKeyEvent(final CefBrowser browser, CefKeyEvent event,
                    BoolRef is_keyboard_shortcut) {
                // Forward CEF ctrl-f4 to AWT ctrl-f4 (which is important because it is tied to the close tab command)
                // Note. This is done on onPreKeyEvent because Javascript apps registering hot keys consume the ctrl-down event (jQuery.WhenIType module does that)
                if (event.type == CefKeyEvent.EventType.KEYEVENT_RAWKEYDOWN && event.modifiers == 4 /* ctrl */ && event.windows_key_code == 115 /* f4 */) {
                    JFrame frame = (JFrame) SwingUtilities.getRoot(browser.getUIComponent());
                    KeyEvent e = new KeyEvent(frame, KeyEvent.KEY_PRESSED,
                            System.currentTimeMillis(),
                            KeyEvent.CTRL_DOWN_MASK, KeyEvent.VK_F4,
                            KeyEvent.CHAR_UNDEFINED,
                            KeyEvent.KEY_LOCATION_STANDARD);
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().dispatchKeyEvent(e);
                    return true;
                }
                // Forward CEF ctrl-shift-f4 to AWT ctrl-shift-f4 (which is important because it is tied to the close all tabs command)
                // Note. This is done on onPreKeyEvent because Javascript apps registering hot keys consume the ctrl-down event (jQuery.WhenIType module does that)
                if (event.type == CefKeyEvent.EventType.KEYEVENT_RAWKEYDOWN && event.modifiers == 6 /* ctrl shift */ && event.windows_key_code == 115 /* f4 */) {
                    JFrame frame = (JFrame) SwingUtilities.getRoot(browser.getUIComponent());
                    KeyEvent e = new KeyEvent(frame, KeyEvent.KEY_PRESSED,
                            System.currentTimeMillis(), KeyEvent.CTRL_DOWN_MASK
                                    | KeyEvent.SHIFT_DOWN_MASK, KeyEvent.VK_F4,
                            KeyEvent.CHAR_UNDEFINED,
                            KeyEvent.KEY_LOCATION_STANDARD);
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().dispatchKeyEvent(e);
                    return true;
                }
                // Forward CEF ctrl-s to AWT ctrl-s (which is important because it is tied to the save tab command)
                // Note. This is done on onPreKeyEvent because Javascript apps registering hot keys consume the ctrl-down event (jQuery.WhenIType module does that)
                if (event.type == CefKeyEvent.EventType.KEYEVENT_RAWKEYDOWN && event.modifiers == 4 /* ctrl */ && event.character == 'S') {
                    JFrame frame = (JFrame) SwingUtilities.getRoot(browser.getUIComponent());
                    KeyEvent e = new KeyEvent(frame, KeyEvent.KEY_PRESSED,
                            System.currentTimeMillis(),
                            KeyEvent.CTRL_DOWN_MASK, KeyEvent.VK_S,
                            KeyEvent.CHAR_UNDEFINED,
                            KeyEvent.KEY_LOCATION_STANDARD);
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().dispatchKeyEvent(e);
                    return true;
                }
                return false;
            }

            @Override
            public boolean onKeyEvent(CefBrowser browser, CefKeyEvent event) {
                // Forward CEF alt-down to AWT alt-down (which is important to bring up menu mnemonics on Swing menu bar)
                // Note. This is done on onKeyEvent to allow Java script apps to register hotkeys such as "alt-enter".
                if (event.type == CefKeyEvent.EventType.KEYEVENT_RAWKEYDOWN && event.is_system_key && event.modifiers == 8 /* ALT */) {
                    JFrame frame = (JFrame) SwingUtilities.getRoot(browser.getUIComponent());
                    KeyEvent e = new KeyEvent(frame, KeyEvent.KEY_PRESSED,
                            System.currentTimeMillis(), KeyEvent.ALT_MASK,
                            KeyEvent.VK_ALT, KeyEvent.CHAR_UNDEFINED,
                            KeyEvent.KEY_LOCATION_STANDARD);
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().dispatchKeyEvent(e);
                    return true;
                }
                // Forward CEF alt-up to AWT alt-up (which is important to let user navigate through Swing menu bar or return to previously focused element)
                // Note. This is done on onKeyEvent to allow Javascript apps to register hotkeys such as "alt-enter".
                if (event.type == CefKeyEvent.EventType.KEYEVENT_KEYUP && event.is_system_key && event.windows_key_code == 18 /* ALT */) {
                    JFrame frame = (JFrame) SwingUtilities.getRoot(browser.getUIComponent());
                    KeyEvent e = new KeyEvent(frame, KeyEvent.KEY_RELEASED,
                            System.currentTimeMillis(), 0, KeyEvent.VK_ALT,
                            KeyEvent.CHAR_UNDEFINED,
                            KeyEvent.KEY_LOCATION_STANDARD);
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().dispatchKeyEvent(e);
                    return true;
                }
                return false;
            }
        });

Original comment by christop...@gmail.com on 29 Sep 2014 at 5:41

GoogleCodeExporter commented 9 years ago
JCEF is transitioning from Google Code to Bitbucket project hosting. If you 
would like to continue receiving notifications on this issue please add 
yourself as a Watcher at the new location: 
https://bitbucket.org/chromiumembedded/java-cef/issue/122

Original comment by magreenb...@gmail.com on 18 Mar 2015 at 6:00