# HG changeset patch
# Parent 6dcc449dfbf939f5187f7612ec978b38933e4559
# Parent  d0713da6d8126022884a3dd9728093f062ec4ba7

diff -r d0713da6d812 modules/controls/src/main/java/javafx/scene/control/skin/LabeledSkinBase.java
--- a/modules/controls/src/main/java/javafx/scene/control/skin/LabeledSkinBase.java	Mon Feb 29 11:02:12 2016 +1300
+++ b/modules/controls/src/main/java/javafx/scene/control/skin/LabeledSkinBase.java	Mon Mar 14 10:42:27 2016 -0700
@@ -231,7 +231,13 @@
         registerChangeListener(labeled.sceneProperty(), o -> sceneChanged());
     }
 
+    boolean containsMnemonic() {
+        return containsMnemonic;
+    }
 
+    TextBinding textBinding() {
+        return bindings;
+    }
 
     /***************************************************************************
      *                                                                         *
diff -r d0713da6d812 modules/controls/src/main/java/javafx/scene/control/skin/MenuBarSkin.java
--- a/modules/controls/src/main/java/javafx/scene/control/skin/MenuBarSkin.java	Mon Feb 29 11:02:12 2016 +1300
+++ b/modules/controls/src/main/java/javafx/scene/control/skin/MenuBarSkin.java	Mon Mar 14 10:42:27 2016 -0700
@@ -47,6 +47,7 @@
 import javafx.css.StyleableProperty;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
+import javafx.event.EventType;
 import javafx.event.WeakEventHandler;
 import javafx.geometry.NodeOrientation;
 import javafx.geometry.Pos;
@@ -81,6 +82,8 @@
 import com.sun.javafx.menu.MenuBase;
 import com.sun.javafx.scene.SceneHelper;
 import com.sun.javafx.scene.control.GlobalMenuAdapter;
+import com.sun.javafx.scene.control.behavior.TextBinding;
+import com.sun.javafx.scene.control.behavior.TextBinding.MnemonicKeyCombination;
 import com.sun.javafx.stage.StageHelper;
 import com.sun.javafx.tk.Toolkit;
 import javafx.stage.Window;
@@ -163,7 +166,7 @@
             if (container.getChildren().size() > 0) {
                 if (container.getChildren().get(0) instanceof MenuButton) {
 //                        container.getChildren().get(0).requestFocus();
-                    if (focusedMenuIndex != 0) {
+                    if (focusedMenuIndex == -1) {
                         unSelectMenus();
                         menuModeStart(0);
                         openMenuButton = ((MenuBarButton)container.getChildren().get(0));
@@ -205,6 +208,8 @@
         keyEventHandler = event -> {
             // process right left and may be tab key events
             if (openMenu != null) {
+              EventType<KeyEvent> type = event.getEventType();
+              if (type == KeyEvent.KEY_PRESSED) {
                 switch (event.getCode()) {
                     case LEFT: {
                         boolean isRTL = control.getEffectiveNodeOrientation() == NodeOrientation.RIGHT_TO_LEFT;
@@ -272,6 +277,32 @@
                 default:
                     break;
                 }
+              } else if (type == KeyEvent.KEY_TYPED) {
+                    KeyCombination typedKC = new MnemonicKeyCombination(event.getCharacter());
+
+                    // Loop over menus to find a matching mnemonic.
+                    for (Node node : container.getChildren()) {
+                        if (node instanceof MenuButton && !node.isDisable()) {
+                            MenuButton mb = (MenuButton)node;
+                            LabeledSkinBase mbLabelSkin = (LabeledSkinBase)((MenuButtonSkin)mb.getSkin()).label.getSkin();
+                            if (mbLabelSkin.containsMnemonic()) {
+                                KeyCombination mnemonicKC = mbLabelSkin.textBinding().getMnemonicKeyCombination();
+                                if (mnemonicKC.equals(typedKC)) {
+                                    unSelectMenus();
+                                    mb.fire();
+                                    event.consume();
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    if (!event.isConsumed() && openMenu.isShowing()) {
+                        // Loop over menuitems in the open menu to find a matching mnemonic.
+                        findAndFireMnemonic(openMenu, event, typedKC);
+                    }
+              }
+              // Consume all remaining key events here.
+              event.consume();
             }
         };
         menuBarFocusedPropertyListener = (ov, t, t1) -> {
@@ -290,6 +321,7 @@
         weakSceneKeyEventHandler = new WeakEventHandler<KeyEvent>(keyEventHandler);
         Utils.executeOnceWhenPropertyIsNonNull(control.sceneProperty(), (Scene scene) -> {
             scene.addEventFilter(KeyEvent.KEY_PRESSED, weakSceneKeyEventHandler);
+            scene.addEventFilter(KeyEvent.KEY_TYPED, weakSceneKeyEventHandler);
         });
 
         // When we click else where in the scene - menu selection should be cleared.
@@ -352,8 +384,9 @@
 //        });
 
         /*
-        ** add an accelerator for F10 on windows and ctrl+F10 on mac/linux
-        ** pressing f10 will select the first menu button on a menubar
+        ** add an accelerator for F10 on windows/linux and ctrl+F10 on mac.
+        ** Pressing it will select the first menu button on a menubar or
+        ** unselect if there's already a menu button selected.
         */
         final KeyCombination acceleratorKeyCombo;
         if (com.sun.javafx.util.Utils.isMac()) {
@@ -374,7 +407,7 @@
                     unSelectMenus();
                 }
             });
-            // Put focus on the first menu when ALT is released
+            // Put focus on the first menu when the alt or F10 key is released
             // directly after being pressed by itself
             scene.addEventHandler(KeyEvent.KEY_RELEASED, e -> {
                 if (altKeyPressed && e.getCode() == ALT && !e.isConsumed()) {
@@ -394,8 +427,10 @@
         control.sceneProperty().addListener((ov, t, t1) -> {
             if (weakSceneKeyEventHandler != null) {
                 // remove event filter from the old scene (t)
-                if (t != null)
+                if (t != null) {
                     t.removeEventFilter(KeyEvent.KEY_PRESSED, weakSceneKeyEventHandler);
+                    t.removeEventFilter(KeyEvent.KEY_TYPED, weakSceneKeyEventHandler);
+                }
             }
             if (weakSceneMouseEventHandler != null) {
                 // remove event filter from the old scene (t)
@@ -679,6 +714,38 @@
      *                                                                         *
      **************************************************************************/
 
+    private void findAndFireMnemonic(Menu menu, KeyEvent event, KeyCombination typedKC) {
+        for (MenuItem menuItem : menu.getItems()) {
+            if (!menuItem.isDisable() && menuItem.isMnemonicParsing()) {
+                TextBinding textBinding = new TextBinding(menuItem.getText());
+                if (textBinding.getMnemonicIndex() >= 0) {
+                    KeyCombination mnemonicKC = textBinding.getMnemonicKeyCombination();
+                    if (mnemonicKC.equals(typedKC)) {
+                        if (menuItem instanceof Menu) {
+                            ((Menu)menuItem).show();
+                        } else {
+                            menuItem.fire();
+                            unSelectMenus();
+                        }
+                        event.consume();
+                        break;
+                    }
+                }
+            }
+        }
+        if (!event.isConsumed()) {
+            // Look for submenus
+            for (MenuItem menuItem : menu.getItems()) {
+                if (menuItem instanceof Menu && ((Menu)menuItem).isShowing()) {
+                    findAndFireMnemonic((Menu)menuItem, event, typedKC);
+                    if (event.isConsumed()) {
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
     // For testing purpose only.
     MenuButton getNodeForMenu(int i) {
         if (i < container.getChildren().size()) {
diff -r d0713da6d812 modules/graphics/src/main/java/com/sun/javafx/scene/KeyboardShortcutsHandler.java
--- a/modules/graphics/src/main/java/com/sun/javafx/scene/KeyboardShortcutsHandler.java	Mon Feb 29 11:02:12 2016 +1300
+++ b/modules/graphics/src/main/java/com/sun/javafx/scene/KeyboardShortcutsHandler.java	Mon Mar 14 10:42:27 2016 -0700
@@ -182,19 +182,19 @@
                         setMnemonicsDisplayEnabled(true);
                     }
                     else {
-                        if (PlatformUtil.isWindows()) {
+                        // if (PlatformUtil.isWindows()) {
                             setMnemonicsDisplayEnabled(!isMnemonicsDisplayEnabled());
-                        }
+                        // }
                     }
                 }
             }
-            if (event.getEventType() == KeyEvent.KEY_RELEASED) {
-                if (!((KeyEvent)event).isAltDown()) {
-                    if (!PlatformUtil.isWindows()) {
-                        setMnemonicsDisplayEnabled(false);
-                    }
-                }
-            }
+            // if (event.getEventType() == KeyEvent.KEY_RELEASED) {
+            //     if (!((KeyEvent)event).isAltDown()) {
+            //         if (!PlatformUtil.isWindows()) {
+            //             setMnemonicsDisplayEnabled(false);
+            //         }
+            //     }
+            // }
         }
         return event;
     }
