53 } 54 fIsCheckbox = NO; 55 fIsEnabled = YES; 56 } 57 return self; 58 } 59 60 // This is because NSApplication doesn't check the target's window when sending 61 // actions; they only check the target itself. We always return YES, 62 // since we shouldn't even be installed unless our window is active. 63 - (BOOL) worksWhenModal { 64 return YES; 65 } 66 67 // Events 68 - (void)handleAction:(NSMenuItem *)sender { 69 AWT_ASSERT_APPKIT_THREAD; 70 JNIEnv *env = [ThreadUtilities getJNIEnv]; 71 JNF_COCOA_ENTER(env); 72 73 // If we are called as a result of user pressing a shorcut, do nothing, 74 // because AVTView has already sent corresponding key event to the Java 75 // layer from performKeyEquivalent 76 NSEvent *currEvent = [[NSApplication sharedApplication] currentEvent]; 77 if ([currEvent type] == NSKeyDown) { 78 NSString *menuKey = [sender keyEquivalent]; 79 NSString *eventKey = [currEvent charactersIgnoringModifiers]; 80 81 // Apple uses characters from private Unicode range for some of the 82 // keys, so we need to do the same translation here that we do 83 // for the regular key down events 84 if ([eventKey length] == 1) { 85 unichar origChar = [eventKey characterAtIndex:0]; 86 unichar newChar = NsCharToJavaChar(origChar, 0); 87 if (newChar == java_awt_event_KeyEvent_CHAR_UNDEFINED) { 88 newChar = origChar; 89 } 90 91 eventKey = [NSString stringWithCharacters: &newChar length: 1]; 92 } 93 94 if ([menuKey isEqualToString:eventKey]) { 95 return; 96 } 97 } 98 99 if (fIsCheckbox) { 100 static JNF_CLASS_CACHE(jc_CCheckboxMenuItem, "sun/lwawt/macosx/CCheckboxMenuItem"); 101 static JNF_MEMBER_CACHE(jm_ckHandleAction, jc_CCheckboxMenuItem, "handleAction", "(Z)V"); 102 103 // Send the opposite of what's currently checked -- the action 104 // indicates what state we're going to. 105 NSInteger state = [sender state]; 106 jboolean newState = (state == NSOnState ? JNI_FALSE : JNI_TRUE); 107 JNFCallVoidMethod(env, fPeer, jm_ckHandleAction, newState); 108 } else { 109 static JNF_CLASS_CACHE(jc_CMenuItem, "sun/lwawt/macosx/CMenuItem"); 110 static JNF_MEMBER_CACHE(jm_handleAction, jc_CMenuItem, "handleAction", "(JI)V"); // AWT_THREADING Safe (event) 111 112 NSUInteger modifiers = [currEvent modifierFlags]; 113 jint javaModifiers = NsKeyModifiersToJavaModifiers(modifiers, NO); 114 | 53 } 54 fIsCheckbox = NO; 55 fIsEnabled = YES; 56 } 57 return self; 58 } 59 60 // This is because NSApplication doesn't check the target's window when sending 61 // actions; they only check the target itself. We always return YES, 62 // since we shouldn't even be installed unless our window is active. 63 - (BOOL) worksWhenModal { 64 return YES; 65 } 66 67 // Events 68 - (void)handleAction:(NSMenuItem *)sender { 69 AWT_ASSERT_APPKIT_THREAD; 70 JNIEnv *env = [ThreadUtilities getJNIEnv]; 71 JNF_COCOA_ENTER(env); 72 73 // If we are called as a result of user pressing a shortcut, do nothing, 74 // because AVTView has already sent corresponding key event to the Java 75 // layer from performKeyEquivalent. 76 // There is an exception from the rule above, though: if a window with 77 // a menu gets minimized by user and there are no other windows to take 78 // focus, the window's menu won't be removed from the global menu bar. 79 // However, the Java layer won't handle invocation by a shortcut coming 80 // from this "frameless" menu, because there are no active windows. This 81 // means we have to handle it here. 82 NSEvent *currEvent = [[NSApplication sharedApplication] currentEvent]; 83 if ([currEvent type] == NSKeyDown) { 84 NSString *menuKey = [sender keyEquivalent]; 85 NSString *eventKey = [currEvent charactersIgnoringModifiers]; 86 87 // Apple uses characters from private Unicode range for some of the 88 // keys, so we need to do the same translation here that we do 89 // for the regular key down events 90 if ([eventKey length] == 1) { 91 unichar origChar = [eventKey characterAtIndex:0]; 92 unichar newChar = NsCharToJavaChar(origChar, 0); 93 if (newChar == java_awt_event_KeyEvent_CHAR_UNDEFINED) { 94 newChar = origChar; 95 } 96 97 eventKey = [NSString stringWithCharacters: &newChar length: 1]; 98 } 99 100 NSWindow *keyWindow = [NSApp keyWindow]; 101 if ([menuKey isEqualToString:eventKey] && keyWindow != nil) { 102 return; 103 } 104 } 105 106 if (fIsCheckbox) { 107 static JNF_CLASS_CACHE(jc_CCheckboxMenuItem, "sun/lwawt/macosx/CCheckboxMenuItem"); 108 static JNF_MEMBER_CACHE(jm_ckHandleAction, jc_CCheckboxMenuItem, "handleAction", "(Z)V"); 109 110 // Send the opposite of what's currently checked -- the action 111 // indicates what state we're going to. 112 NSInteger state = [sender state]; 113 jboolean newState = (state == NSOnState ? JNI_FALSE : JNI_TRUE); 114 JNFCallVoidMethod(env, fPeer, jm_ckHandleAction, newState); 115 } else { 116 static JNF_CLASS_CACHE(jc_CMenuItem, "sun/lwawt/macosx/CMenuItem"); 117 static JNF_MEMBER_CACHE(jm_handleAction, jc_CMenuItem, "handleAction", "(JI)V"); // AWT_THREADING Safe (event) 118 119 NSUInteger modifiers = [currEvent modifierFlags]; 120 jint javaModifiers = NsKeyModifiersToJavaModifiers(modifiers, NO); 121 |