diff --git a/editor.lib/src/org/netbeans/editor/MultiKeymap.java b/editor.lib/src/org/netbeans/editor/MultiKeymap.java --- a/editor.lib/src/org/netbeans/editor/MultiKeymap.java +++ b/editor.lib/src/org/netbeans/editor/MultiKeymap.java @@ -61,6 +61,7 @@ import javax.swing.Action; import javax.swing.AbstractAction; import org.openide.awt.StatusDisplayer; +import org.openide.util.BaseUtilities; import org.openide.util.Lookup; /** @@ -373,6 +374,13 @@ if (context != null) { // Already in a non-empty context ignoreNextTyped = true; + } else if (BaseUtilities.isMac()) { + if (ret != null + && key.getKeyEventType() == KeyEvent.KEY_PRESSED + && (key.getModifiers() & InputEvent.ALT_MASK) != 0 + && (key.getModifiers() & InputEvent.CTRL_MASK) == 0) { + ignoreNextTyped = true; + } } else if (compatibleIgnoreNextTyped) { // #44307 = disabled extra ignoreNextTyped patches for past JDKs if ( // Explicit patch for the keyTyped sent after Alt+key diff --git a/openide.text/src/org/openide/text/QuietEditorPane.java b/openide.text/src/org/openide/text/QuietEditorPane.java --- a/openide.text/src/org/openide/text/QuietEditorPane.java +++ b/openide.text/src/org/openide/text/QuietEditorPane.java @@ -60,6 +60,7 @@ import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; import java.awt.im.InputContext; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -84,6 +85,7 @@ import javax.swing.text.JTextComponent; import org.openide.util.Lookup; import org.openide.util.NbBundle; +import org.openide.util.Utilities; import org.openide.windows.ExternalDropHandler; import org.openide.windows.TopComponent; @@ -121,6 +123,14 @@ private int fontHeight; private int charWidth; + private static enum AltStatus { + DEFAULT, + MAY_CONSUME_ALT_PRESSED, + IGNORE_NEXT_TYPED, + } + + private AltStatus altStatus = AltStatus.DEFAULT; + /** * consturctor sets the initial values for horizontal * and vertical scroll units. @@ -129,6 +139,44 @@ public QuietEditorPane() { setFontHeightWidth(getFont()); } + + @Override + protected void processKeyEvent(KeyEvent e) { + if (Utilities.isMac()) { + if (e.getID() == KeyEvent.KEY_PRESSED + && (e.getModifiers() & KeyEvent.ALT_MASK) != 0 + && (e.getModifiers() & KeyEvent.CTRL_MASK) == 0) { + altStatus = AltStatus.MAY_CONSUME_ALT_PRESSED; + } + super.processKeyEvent(e); + if (altStatus == AltStatus.MAY_CONSUME_ALT_PRESSED) { + altStatus = AltStatus.IGNORE_NEXT_TYPED; + LOG.fine("Ignore next typed."); + } + } else { + super.processKeyEvent(e); + } + } + + @Override + protected void processComponentKeyEvent(KeyEvent e) { + // JComponent#processKeyEvent call this method if key event is not consumed at listeners. + switch (altStatus) { + case MAY_CONSUME_ALT_PRESSED: + altStatus = AltStatus.DEFAULT; + break; + case IGNORE_NEXT_TYPED: + if (e.getID() == KeyEvent.KEY_TYPED) { + e.consume(); + LOG.fine("Ignored: [" + e.getKeyChar() + "]"); + } + altStatus = AltStatus.DEFAULT; + break; + default: + break; + } + } + public AccessibleContext getAccessibleContext() { AccessibleContext ctx = super.getAccessibleContext(); diff --git a/openide.util.ui/src/org/openide/util/Utilities.java b/openide.util.ui/src/org/openide/util/Utilities.java --- a/openide.util.ui/src/org/openide/util/Utilities.java +++ b/openide.util.ui/src/org/openide/util/Utilities.java @@ -211,6 +211,9 @@ /** A height of the Mac OS X's menu */ private static final int TYPICAL_MACOSX_MENU_HEIGHT = 24; + // Ignore extended key code if it is greater or equal then the following value on Mac. + private static final int MIN_IGNORE_EXTENDED_KEY_CODE = 0x1000000; + private static Timer clearIntrospector; private static ActionListener doClear; private static final int CTRL_WILDCARD_MASK = 32768; @@ -1167,6 +1170,16 @@ } /** + * Test whether extended key code is available. + * + * @param keyCode extended key code + * @return true if it is available. + */ + public static boolean isAvailableExtendedKeyCode(int keyCode) { + return keyCode != KeyEvent.VK_UNDEFINED && (!Utilities.isMac() || keyCode < MIN_IGNORE_EXTENDED_KEY_CODE); + } + + /** * Finds out the monitor where the user currently has the input focus. * This method is usually used to help the client code to figure out on * which monitor it should place newly created windows/frames/dialogs. diff --git a/options.keymap/src/org/netbeans/modules/options/keymap/ShortcutListener.java b/options.keymap/src/org/netbeans/modules/options/keymap/ShortcutListener.java --- a/options.keymap/src/org/netbeans/modules/options/keymap/ShortcutListener.java +++ b/options.keymap/src/org/netbeans/modules/options/keymap/ShortcutListener.java @@ -107,7 +107,7 @@ if (keyEvent_getExtendedKeyCode != null) { try { int ecode = (int)(Integer)keyEvent_getExtendedKeyCode.invoke(e); - if (ecode != KeyEvent.VK_UNDEFINED) { + if (Utilities.isAvailableExtendedKeyCode(ecode)) { code = ecode; } } catch (IllegalAccessException ex) {