diff options
3 files changed, 43 insertions, 8 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java index e76973420e..86d777c4e1 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java @@ -155,6 +155,8 @@ public class Display extends Device { Menu menuBar; Menu[] menus, popups; + /* Menu items with ESC key as accelerator need to be handled differently on Cocoa */ + boolean escAsAcceleratorPresent = false; NSApplication application; long /*int*/ applicationClass; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MenuItem.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MenuItem.java index b8fa54ff6f..6f25a9f810 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MenuItem.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/MenuItem.java @@ -595,6 +595,9 @@ public void setAccelerator (int accelerator) { if (this.accelerator == accelerator) return; this.accelerator = accelerator; int key = accelerator & SWT.KEY_MASK; + if (key == SWT.ESC && /* no masks */key == accelerator && !display.escAsAcceleratorPresent) { + display.escAsAcceleratorPresent = true; + } int virtualKey = keyChar (key); String string = virtualKey != 0 ? (char)virtualKey + "" : (char)key + ""; NSString nsstring = (NSString) new NSString().alloc(); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java index 1a854f763a..ea0709df01 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Shell.java @@ -133,6 +133,7 @@ public class Shell extends Decorations { NSRect fullScreenFrame; ToolBar toolBar; Map windowEmbedCounts; + MenuItem escMenuItem; static int DEFAULT_CLIENT_WIDTH = -1; static int DEFAULT_CLIENT_HEIGHT = -1; @@ -2284,14 +2285,17 @@ void windowSendEvent (long /*int*/ id, long /*int*/ sel, long /*int*/ event) { * Feature in Cocoa. For some reason, Cocoa does not perform accelerators * with ESC key code. The fix is to perform the accelerators ourselves. */ - if (nsEvent.keyCode() == 53 /* ESC */) { - if (menuBar != null && !menuBar.isDisposed()) { - if (menuBar.nsMenu.performKeyEquivalent(nsEvent)) { - return; - } - } else if (display.appMenuBar != null && !display.appMenuBar.isDisposed()) { - if (display.appMenuBar.nsMenu.performKeyEquivalent(nsEvent)) { - return; + if (display.escAsAcceleratorPresent && nsEvent.keyCode() == 53 /* ESC */) { + if (escMenuItem == null || escMenuItem.getAccelerator() != SWT.ESC) { + updateEscMenuItem(); + } + if (escMenuItem != null) { + Menu parentMenu = escMenuItem.getParent(); + if (parentMenu != null) { + NSMenu escNSMenu = parentMenu.nsMenu; + if (escNSMenu != null) { + escNSMenu.performKeyEquivalent(nsEvent); + } } } } @@ -2325,6 +2329,32 @@ void windowSendEvent (long /*int*/ id, long /*int*/ sel, long /*int*/ event) { super.windowSendEvent (id, sel, event); } +private void updateEscMenuItem() { + if (menuBar != null && !menuBar.isDisposed()){ + searchForEscMenuItem(menuBar); + } else if (display.appMenuBar != null && !display.appMenuBar.isDisposed()) { + searchForEscMenuItem(display.appMenuBar); + } +} + +private boolean searchForEscMenuItem(Menu menu) { + if (menu == null || menu.isDisposed()) return false; + MenuItem[] items = menu.getItems(); + if (items == null) return false; + for (MenuItem item:items) { + if (item == null || item.isDisposed()) { + continue; + } else if (item.getAccelerator() == SWT.ESC) { + escMenuItem = item; + return true; + } else if ((item.getStyle() & SWT.CASCADE) != 0) { + Menu subMenu = item.getMenu(); + if (searchForEscMenuItem(subMenu)) return true; + } + } + return false; +} + boolean windowShouldClose(long /*int*/ id, long /*int*/ sel, long /*int*/ window) { if (isEnabled()) closeWidget (false); return false; |