annotate src/macosx/native/sun/awt/ApplicationDelegate.m @ 7871:d502cc7bcc3d

8006634: Unify LWCToolkit.invokeAndWait() and sun.awt.datatransfer.ToolkitThreadBlockedHandler Summary: Changed the logic for the nested event loops and deleted deadlock detection Reviewed-by: art, denis
author pchelko
date Mon, 25 Feb 2013 10:17:25 +0000
parents 5309fed435b5
children
rev   line source
michaelm@5177 1 /*
michaelm@5177 2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
michaelm@5177 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
michaelm@5177 4 *
michaelm@5177 5 * This code is free software; you can redistribute it and/or modify it
michaelm@5177 6 * under the terms of the GNU General Public License version 2 only, as
michaelm@5177 7 * published by the Free Software Foundation. Oracle designates this
michaelm@5177 8 * particular file as subject to the "Classpath" exception as provided
michaelm@5177 9 * by Oracle in the LICENSE file that accompanied this code.
michaelm@5177 10 *
michaelm@5177 11 * This code is distributed in the hope that it will be useful, but WITHOUT
michaelm@5177 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
michaelm@5177 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
michaelm@5177 14 * version 2 for more details (a copy is included in the LICENSE file that
michaelm@5177 15 * accompanied this code).
michaelm@5177 16 *
michaelm@5177 17 * You should have received a copy of the GNU General Public License version
michaelm@5177 18 * 2 along with this work; if not, write to the Free Software Foundation,
michaelm@5177 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
michaelm@5177 20 *
michaelm@5177 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
michaelm@5177 22 * or visit www.oracle.com if you need additional information or have any
michaelm@5177 23 * questions.
michaelm@5177 24 */
michaelm@5177 25
michaelm@5177 26 #import "ApplicationDelegate.h"
michaelm@5177 27
michaelm@5177 28 #import "com_apple_eawt_Application.h"
michaelm@5177 29 #import "com_apple_eawt__AppDockIconHandler.h"
michaelm@5177 30 #import "com_apple_eawt__AppEventHandler.h"
michaelm@5177 31 #import "com_apple_eawt__AppMenuBarHandler.h"
michaelm@5177 32 #import "com_apple_eawt__AppMenuBarHandler.h"
michaelm@5177 33 #import "com_apple_eawt__AppMiscHandlers.h"
michaelm@5177 34
michaelm@5177 35 #import <JavaNativeFoundation/JavaNativeFoundation.h>
michaelm@5177 36
michaelm@5177 37 #import "CPopupMenu.h"
michaelm@5177 38 #import "ThreadUtilities.h"
michaelm@5177 39 #import "NSApplicationAWT.h"
michaelm@5177 40
michaelm@5177 41
michaelm@5177 42 #pragma mark App Menu helpers
michaelm@5177 43
michaelm@5177 44 // The following is a AWT convention?
michaelm@5177 45 #define PREFERENCES_TAG 42
michaelm@5177 46
michaelm@5177 47 static void addMenuItem(NSMenuItem* menuItem, NSInteger index) {
michaelm@5177 48 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 49
michaelm@5177 50 NSMenu *menuBar = [[NSApplication sharedApplication] mainMenu];
michaelm@5177 51 NSMenu *appMenu = [[menuBar itemAtIndex:0] submenu];
michaelm@5177 52
michaelm@5177 53 [appMenu insertItem:menuItem atIndex:index];
michaelm@5177 54 [appMenu insertItem:[NSMenuItem separatorItem] atIndex:index + 1]; // Add the following separator
michaelm@5177 55 }
michaelm@5177 56
michaelm@5177 57 static void removeMenuItem(NSMenuItem* menuItem) {
michaelm@5177 58 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 59
michaelm@5177 60 NSMenu *menuBar = [[NSApplication sharedApplication] mainMenu];
michaelm@5177 61 NSMenu *appMenu = [[menuBar itemAtIndex:0] submenu];
michaelm@5177 62
michaelm@5177 63 NSInteger index = [appMenu indexOfItem:menuItem];
michaelm@5177 64 if (index < 0) return; // something went wrong
michaelm@5177 65
michaelm@5177 66 [appMenu removeItemAtIndex:index + 1]; // Get the following separator
michaelm@5177 67 [appMenu removeItem:menuItem];
michaelm@5177 68 }
michaelm@5177 69
michaelm@5177 70 @interface NSBundle (EAWTOverrides)
michaelm@5177 71 - (BOOL)_hasEAWTOverride:(NSString *)key;
michaelm@5177 72 @end
michaelm@5177 73
michaelm@5177 74
michaelm@5177 75 @implementation NSBundle (EAWTOverrides)
michaelm@5177 76
michaelm@5177 77 - (BOOL)_hasEAWTOverride:(NSString *)key {
michaelm@5177 78 return [[[[self objectForInfoDictionaryKey:@"Java"] objectForKey:@"EAWTOverride"] objectForKey:key] boolValue];
michaelm@5177 79 }
michaelm@5177 80
michaelm@5177 81 @end
michaelm@5177 82
michaelm@5177 83
michaelm@5177 84 // used by JavaRuntimeSupport.framework's [JRSAppKitAWT awtAppDelegate]
michaelm@5177 85 // to expose our app delegate to the SWT or other apps that have knoledge
michaelm@5177 86 // of Java's AWT and want to install their own app delegate that will delegate
michaelm@5177 87 // to the AWT for some operations
michaelm@5177 88
michaelm@5177 89 @interface JavaAWTAppDelegateLoader : NSObject { }
michaelm@5177 90 @end
michaelm@5177 91
michaelm@5177 92 @implementation JavaAWTAppDelegateLoader
michaelm@5177 93 + (ApplicationDelegate *) awtAppDelegate {
michaelm@5177 94 return [ApplicationDelegate sharedDelegate];
michaelm@5177 95 }
michaelm@5177 96 @end
michaelm@5177 97
michaelm@5177 98
michaelm@5177 99 @implementation ApplicationDelegate
michaelm@5177 100
michaelm@5177 101 @synthesize fPreferencesMenu;
michaelm@5177 102 @synthesize fAboutMenu;
michaelm@5177 103
michaelm@5177 104 @synthesize fDockMenu;
michaelm@5177 105 @synthesize fDefaultMenuBar;
michaelm@5177 106
michaelm@5177 107
michaelm@5177 108 + (ApplicationDelegate *)sharedDelegate {
michaelm@5177 109 static ApplicationDelegate *sApplicationDelegate = nil;
michaelm@5177 110 static BOOL checked = NO;
michaelm@5177 111
michaelm@5177 112 if (sApplicationDelegate != nil) return sApplicationDelegate;
michaelm@5177 113 if (checked) return nil;
michaelm@5177 114
michaelm@5177 115 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 116
michaelm@5177 117 // don't install the EAWT delegate if another kind of NSApplication is installed, like say, Safari
michaelm@5177 118 BOOL shouldInstall = NO;
michaelm@5177 119 if (NSApp != nil) {
michaelm@5177 120 if ([NSApp isMemberOfClass:[NSApplication class]]) shouldInstall = YES;
michaelm@5177 121 if ([NSApp isKindOfClass:[NSApplicationAWT class]]) shouldInstall = YES;
michaelm@5177 122 }
michaelm@5177 123 checked = YES;
michaelm@5177 124 if (!shouldInstall) return nil;
michaelm@5177 125
michaelm@5177 126 sApplicationDelegate = [[ApplicationDelegate alloc] init];
michaelm@5177 127 return sApplicationDelegate;
michaelm@5177 128 }
michaelm@5177 129
michaelm@5177 130 - (void)_updatePreferencesMenu:(BOOL)prefsAvailable enabled:(BOOL)prefsEnabled {
michaelm@5177 131 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 132
michaelm@5177 133 if (prefsAvailable) {
michaelm@5177 134 // Make sure Prefs is around
michaelm@5177 135 if ([self.fPreferencesMenu menu] == nil) {
michaelm@5177 136 // Position of Prefs depends upon About availability.
michaelm@5177 137 NSInteger index = ([self.fAboutMenu menu] != nil) ? 2 : 0;
michaelm@5177 138
michaelm@5177 139 addMenuItem(self.fPreferencesMenu, index);
michaelm@5177 140 }
michaelm@5177 141
michaelm@5177 142 if (prefsEnabled) {
michaelm@5177 143 [self.fPreferencesMenu setEnabled:YES];
michaelm@5177 144 [self.fPreferencesMenu setTarget:self];
michaelm@5177 145 [self.fPreferencesMenu setAction:@selector(_preferencesMenuHandler)];
michaelm@5177 146 } else {
michaelm@5177 147 [self.fPreferencesMenu setEnabled:NO];
michaelm@5177 148 [self.fPreferencesMenu setTarget:nil];
michaelm@5177 149 [self.fPreferencesMenu setAction:nil];
michaelm@5177 150 }
michaelm@5177 151 } else {
michaelm@5177 152 if ([self.fPreferencesMenu menu] == nil) return;
michaelm@5177 153
michaelm@5177 154 // Remove the preferences item
michaelm@5177 155 removeMenuItem(self.fPreferencesMenu);
michaelm@5177 156 }
michaelm@5177 157 }
michaelm@5177 158
michaelm@5177 159 - (void)_updateAboutMenu:(BOOL)aboutAvailable enabled:(BOOL)aboutEnabled {
michaelm@5177 160 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 161
michaelm@5177 162 if (aboutAvailable) {
michaelm@5177 163 // Make sure About is around
michaelm@5177 164 if ([self.fAboutMenu menu] == nil) {
michaelm@5177 165 addMenuItem(self.fAboutMenu, 0);
michaelm@5177 166 }
michaelm@5177 167
michaelm@5177 168 if (aboutEnabled) {
michaelm@5177 169 [self.fAboutMenu setEnabled:YES];
michaelm@5177 170 [self.fAboutMenu setTarget:self];
michaelm@5177 171 [self.fAboutMenu setAction:@selector(_aboutMenuHandler)];
michaelm@5177 172 } else {
michaelm@5177 173 [self.fAboutMenu setEnabled:NO];
michaelm@5177 174 [self.fAboutMenu setTarget:nil];
michaelm@5177 175 [self.fAboutMenu setAction:nil];
michaelm@5177 176 }
michaelm@5177 177 } else {
michaelm@5177 178 if ([self.fAboutMenu menu] == nil) return;
michaelm@5177 179
michaelm@5177 180 // Remove About item.
michaelm@5177 181 removeMenuItem(self.fAboutMenu);
michaelm@5177 182 }
michaelm@5177 183 }
michaelm@5177 184
michaelm@5177 185 - (id) init {
michaelm@5177 186 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 187
michaelm@5177 188 self = [super init];
michaelm@5177 189 if (!self) return self;
michaelm@5177 190
michaelm@5177 191 // Prep for about and preferences menu
michaelm@5177 192 BOOL usingDefaultNib = YES;
michaelm@5177 193 if ([NSApp isKindOfClass:[NSApplicationAWT class]]) {
michaelm@5177 194 usingDefaultNib = [NSApp usingDefaultNib];
michaelm@5177 195 }
michaelm@5177 196 if (!usingDefaultNib) return self;
michaelm@5177 197
michaelm@5177 198 NSMenu *menuBar = [[NSApplication sharedApplication] mainMenu];
michaelm@5177 199 NSMenu *appMenu = [[menuBar itemAtIndex:0] submenu];
michaelm@5177 200
michaelm@5177 201 self.fPreferencesMenu = (NSMenuItem*)[appMenu itemWithTag:PREFERENCES_TAG];
michaelm@5177 202 self.fAboutMenu = (NSMenuItem*)[appMenu itemAtIndex:0];
michaelm@5177 203
michaelm@5177 204 // If the java application has a bundle with an Info.plist file with
michaelm@5177 205 // a CFBundleDocumentTypes entry, then it is set up to handle Open Doc
michaelm@5177 206 // and Print Doc commands for these files. Therefore java AWT will
michaelm@5177 207 // cache Open Doc and Print Doc events that are sent prior to a
michaelm@5177 208 // listener being installed by the client java application.
michaelm@5177 209 NSBundle *bundle = [NSBundle mainBundle];
michaelm@5177 210 fHandlesDocumentTypes = [bundle objectForInfoDictionaryKey:@"CFBundleDocumentTypes"] != nil || [bundle _hasEAWTOverride:@"DocumentHandler"];
michaelm@5177 211 fHandlesURLTypes = [bundle objectForInfoDictionaryKey:@"CFBundleURLTypes"] != nil || [bundle _hasEAWTOverride:@"URLHandler"];
michaelm@5177 212 if (fHandlesURLTypes) {
michaelm@5177 213 [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
michaelm@5177 214 andSelector:@selector(_handleOpenURLEvent:withReplyEvent:)
michaelm@5177 215 forEventClass:kInternetEventClass
michaelm@5177 216 andEventID:kAEGetURL];
michaelm@5177 217 }
michaelm@5177 218
michaelm@5177 219 // By HIG, Preferences are not available unless there is a handler. By default in Mac OS X,
michaelm@5177 220 // there is not a handler, but it is in the nib file for convenience.
michaelm@5177 221 removeMenuItem(self.fPreferencesMenu);
michaelm@5177 222
michaelm@5177 223 [self _updateAboutMenu:YES enabled:YES];
michaelm@5177 224
michaelm@5177 225 // Now that the AppKit objects are known and set up, initialize the model data
michaelm@5177 226 BOOL aboutAvailable = ([self.fAboutMenu menu] != nil);
michaelm@5177 227 BOOL aboutEnabled = (aboutAvailable && [self.fAboutMenu isEnabled] && ([self.fAboutMenu target] != nil));
michaelm@5177 228
michaelm@5177 229 BOOL prefsAvailable = ([self.fPreferencesMenu menu] != nil);
michaelm@5177 230 BOOL prefsEnabled = (prefsAvailable && [self.fPreferencesMenu isEnabled] && ([self.fPreferencesMenu target] != nil));
michaelm@5177 231
michaelm@5177 232 JNIEnv *env = [ThreadUtilities getJNIEnv];
michaelm@5177 233 static JNF_CLASS_CACHE(sjc_AppMenuBarHandler, "com/apple/eawt/_AppMenuBarHandler");
michaelm@5177 234 static JNF_STATIC_MEMBER_CACHE(sjm_initMenuStates, sjc_AppMenuBarHandler, "initMenuStates", "(ZZZZ)V");
michaelm@5177 235 JNFCallStaticVoidMethod(env, sjm_initMenuStates, aboutAvailable, aboutEnabled, prefsAvailable, prefsEnabled);
michaelm@5177 236
michaelm@5177 237 // register for the finish launching and system power off notifications by default
michaelm@5177 238 NSNotificationCenter *ctr = [NSNotificationCenter defaultCenter];
michaelm@5177 239 Class clz = [ApplicationDelegate class];
michaelm@5177 240 [ctr addObserver:clz selector:@selector(_willFinishLaunching) name:NSApplicationWillFinishLaunchingNotification object:nil];
michaelm@5177 241 [ctr addObserver:clz selector:@selector(_systemWillPowerOff) name:NSWorkspaceWillPowerOffNotification object:nil];
michaelm@5177 242 [ctr addObserver:clz selector:@selector(_appDidActivate) name:NSApplicationDidBecomeActiveNotification object:nil];
michaelm@5177 243 [ctr addObserver:clz selector:@selector(_appDidDeactivate) name:NSApplicationDidResignActiveNotification object:nil];
michaelm@5177 244 [ctr addObserver:clz selector:@selector(_appDidHide) name:NSApplicationDidHideNotification object:nil];
michaelm@5177 245 [ctr addObserver:clz selector:@selector(_appDidUnhide) name:NSApplicationDidUnhideNotification object:nil];
michaelm@5177 246
michaelm@5177 247 return self;
michaelm@5177 248 }
michaelm@5177 249
michaelm@5177 250 - (void)dealloc {
michaelm@5177 251 self.fPreferencesMenu = nil;
michaelm@5177 252 self.fAboutMenu = nil;
michaelm@5177 253 self.fDockMenu = nil;
michaelm@5177 254 self.fDefaultMenuBar = nil;
michaelm@5177 255
michaelm@5177 256 [super dealloc];
michaelm@5177 257 }
michaelm@5177 258 //- (void)finalize { [super finalize]; } // GC
michaelm@5177 259
michaelm@5177 260
michaelm@5177 261 #pragma mark Callbacks from AppKit
michaelm@5177 262
michaelm@5177 263 static JNF_CLASS_CACHE(sjc_AppEventHandler, "com/apple/eawt/_AppEventHandler");
michaelm@5177 264
michaelm@5177 265 - (void)_handleOpenURLEvent:(NSAppleEventDescriptor *)openURLEvent withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
michaelm@5177 266 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 267 if (!fHandlesURLTypes) return;
michaelm@5177 268
michaelm@5177 269 NSString *url = [[openURLEvent paramDescriptorForKeyword:keyDirectObject] stringValue];
michaelm@5177 270
michaelm@5177 271 //fprintf(stderr,"jm_handleOpenURL\n");
michaelm@5177 272 JNIEnv *env = [ThreadUtilities getJNIEnv];
michaelm@5177 273 jstring jURL = JNFNSToJavaString(env, url);
michaelm@5177 274 static JNF_STATIC_MEMBER_CACHE(jm_handleOpenURI, sjc_AppEventHandler, "handleOpenURI", "(Ljava/lang/String;)V");
michaelm@5177 275 JNFCallStaticVoidMethod(env, jm_handleOpenURI, jURL); // AWT_THREADING Safe (event)
michaelm@5177 276 (*env)->DeleteLocalRef(env, jURL);
michaelm@5177 277
michaelm@5177 278 [replyEvent insertDescriptor:[NSAppleEventDescriptor nullDescriptor] atIndex:0];
michaelm@5177 279 }
michaelm@5177 280
michaelm@5177 281 // Helper for both open file and print file methods
michaelm@5177 282 // Creates a Java list of files from a native list of files
michaelm@5177 283 - (jobject)_createFilePathArrayFrom:(NSArray *)filenames withEnv:(JNIEnv *)env {
michaelm@5177 284 static JNF_CLASS_CACHE(sjc_ArrayList, "java/util/ArrayList");
michaelm@5177 285 static JNF_CTOR_CACHE(jm_ArrayList_ctor, sjc_ArrayList, "(I)V");
michaelm@5177 286 static JNF_MEMBER_CACHE(jm_ArrayList_add, sjc_ArrayList, "add", "(Ljava/lang/Object;)Z");
michaelm@5177 287
michaelm@5177 288 jobject jFileNamesArray = JNFNewObject(env, jm_ArrayList_ctor, (jint)[filenames count]); // AWT_THREADING Safe (known object)
michaelm@5177 289 for (NSString *filename in filenames) {
michaelm@5177 290 jstring jFileName = JNFNormalizedJavaStringForPath(env, filename);
michaelm@5177 291 JNFCallVoidMethod(env, jFileNamesArray, jm_ArrayList_add, jFileName);
michaelm@5177 292 }
michaelm@5177 293
michaelm@5177 294 return jFileNamesArray;
michaelm@5177 295 }
michaelm@5177 296
michaelm@5177 297 // Open file handler
michaelm@5177 298 - (void)application:(NSApplication *)theApplication openFiles:(NSArray *)fileNames {
michaelm@5177 299 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 300 if (!fHandlesDocumentTypes) {
michaelm@5177 301 [theApplication replyToOpenOrPrint:NSApplicationDelegateReplyCancel];
michaelm@5177 302 return;
michaelm@5177 303 }
michaelm@5177 304
michaelm@5177 305 //fprintf(stderr,"jm_handleOpenFile\n");
michaelm@5177 306 JNIEnv *env = [ThreadUtilities getJNIEnv];
michaelm@5177 307
michaelm@5177 308 // if these files were opened from a Spotlight query, try to get the search text from the current AppleEvent
michaelm@5177 309 NSAppleEventDescriptor *currentEvent = [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent];
michaelm@5177 310 NSString *searchString = [[currentEvent paramDescriptorForKeyword:keyAESearchText] stringValue];
michaelm@5177 311 jstring jSearchString = JNFNSToJavaString(env, searchString);
michaelm@5177 312
michaelm@5177 313 // convert the file names array
michaelm@5177 314 jobject jFileNamesArray = [self _createFilePathArrayFrom:fileNames withEnv:env];
michaelm@5177 315
michaelm@5177 316 static JNF_STATIC_MEMBER_CACHE(jm_handleOpenFiles, sjc_AppEventHandler, "handleOpenFiles", "(Ljava/util/List;Ljava/lang/String;)V");
michaelm@5177 317 JNFCallStaticVoidMethod(env, jm_handleOpenFiles, jFileNamesArray, jSearchString);
michaelm@5177 318 (*env)->DeleteLocalRef(env, jFileNamesArray);
michaelm@5177 319 (*env)->DeleteLocalRef(env, jSearchString);
michaelm@5177 320
michaelm@5177 321 [theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
michaelm@5177 322 }
michaelm@5177 323
michaelm@5177 324 // Print handler
michaelm@5177 325 - (NSApplicationPrintReply)application:(NSApplication *)application printFiles:(NSArray *)fileNames withSettings:(NSDictionary *)printSettings showPrintPanels:(BOOL)showPrintPanels {
michaelm@5177 326 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 327 if (!fHandlesDocumentTypes) return NSPrintingCancelled;
michaelm@5177 328
michaelm@5177 329 //fprintf(stderr,"jm_handlePrintFile\n");
michaelm@5177 330 JNIEnv *env = [ThreadUtilities getJNIEnv];
michaelm@5177 331 jobject jFileNamesArray = [self _createFilePathArrayFrom:fileNames withEnv:env];
michaelm@5177 332 static JNF_STATIC_MEMBER_CACHE(jm_handlePrintFile, sjc_AppEventHandler, "handlePrintFiles", "(Ljava/util/List;)V");
michaelm@5177 333 JNFCallStaticVoidMethod(env, jm_handlePrintFile, jFileNamesArray); // AWT_THREADING Safe (event)
michaelm@5177 334 (*env)->DeleteLocalRef(env, jFileNamesArray);
michaelm@5177 335
michaelm@5177 336 return NSPrintingSuccess;
michaelm@5177 337 }
michaelm@5177 338
michaelm@5177 339 // Open app handler, registered in -init
michaelm@5177 340 + (void)_notifyJava:(jint)notificationType {
michaelm@5177 341 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 342
michaelm@5177 343 //fprintf(stderr,"jm_handleOpenApplication\n");
michaelm@5177 344 JNIEnv *env = [ThreadUtilities getJNIEnv];
michaelm@5177 345 static JNF_STATIC_MEMBER_CACHE(jm_handleNativeNotification, sjc_AppEventHandler, "handleNativeNotification", "(I)V");
michaelm@5177 346 JNFCallStaticVoidMethod(env, jm_handleNativeNotification, notificationType); // AWT_THREADING Safe (event)
michaelm@5177 347 }
michaelm@5177 348
michaelm@5177 349 // About menu handler
michaelm@5177 350 - (void)_aboutMenuHandler {
michaelm@5177 351 [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_ABOUT];
michaelm@5177 352 }
michaelm@5177 353
michaelm@5177 354 // Preferences handler
michaelm@5177 355 - (void)_preferencesMenuHandler {
michaelm@5177 356 [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_PREFS];
michaelm@5177 357 }
michaelm@5177 358
michaelm@5177 359 // Open app handler, registered in -init
michaelm@5177 360 + (void)_willFinishLaunching {
michaelm@5177 361 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_OPEN_APP];
michaelm@5177 362 }
michaelm@5177 363
michaelm@5177 364 // ReOpen app handler
michaelm@5177 365 - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag {
michaelm@5177 366 [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_REOPEN_APP];
michaelm@5177 367 return YES;
michaelm@5177 368 }
michaelm@5177 369
michaelm@5177 370 // Quit handler
michaelm@5177 371 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app {
michaelm@5177 372 [ApplicationDelegate _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_QUIT];
michaelm@5177 373 return NSTerminateLater;
michaelm@5177 374 }
michaelm@5177 375
michaelm@5177 376 + (void)_systemWillPowerOff {
michaelm@5177 377 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SHUTDOWN];
michaelm@5177 378 }
michaelm@5177 379
michaelm@5177 380 + (void)_appDidActivate {
michaelm@5177 381 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_ACTIVE_APP_GAINED];
michaelm@5177 382 }
michaelm@5177 383
michaelm@5177 384 + (void)_appDidDeactivate {
michaelm@5177 385 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_ACTIVE_APP_LOST];
michaelm@5177 386 }
michaelm@5177 387
michaelm@5177 388 + (void)_appDidHide {
michaelm@5177 389 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_APP_HIDDEN];
michaelm@5177 390 }
michaelm@5177 391
michaelm@5177 392 + (void)_appDidUnhide {
michaelm@5177 393 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_APP_SHOWN];
michaelm@5177 394 }
michaelm@5177 395
michaelm@5177 396 + (void)_sessionDidActivate {
michaelm@5177 397 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_USER_SESSION_ACTIVE];
michaelm@5177 398 }
michaelm@5177 399
michaelm@5177 400 + (void)_sessionDidDeactivate {
michaelm@5177 401 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_USER_SESSION_INACTIVE];
michaelm@5177 402 }
michaelm@5177 403
michaelm@5177 404 + (void)_screenDidSleep {
michaelm@5177 405 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SCREEN_SLEEP];
michaelm@5177 406 }
michaelm@5177 407
michaelm@5177 408 + (void)_screenDidWake {
michaelm@5177 409 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SCREEN_WAKE];
michaelm@5177 410 }
michaelm@5177 411
michaelm@5177 412 + (void)_systemDidSleep {
michaelm@5177 413 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SYSTEM_SLEEP];
michaelm@5177 414 }
michaelm@5177 415
michaelm@5177 416 + (void)_systemDidWake {
michaelm@5177 417 [self _notifyJava:com_apple_eawt__AppEventHandler_NOTIFY_SYSTEM_WAKE];
michaelm@5177 418 }
michaelm@5177 419
michaelm@5177 420 + (void)_registerForNotification:(NSNumber *)notificationTypeNum {
michaelm@5177 421 NSNotificationCenter *ctr = [[NSWorkspace sharedWorkspace] notificationCenter];
michaelm@5177 422 Class clz = [ApplicationDelegate class];
michaelm@5177 423
michaelm@5177 424 jint notificationType = [notificationTypeNum intValue];
michaelm@5177 425 switch (notificationType) {
michaelm@5177 426 case com_apple_eawt__AppEventHandler_REGISTER_USER_SESSION:
michaelm@5177 427 [ctr addObserver:clz selector:@selector(_sessionDidActivate) name:NSWorkspaceSessionDidBecomeActiveNotification object:nil];
michaelm@5177 428 [ctr addObserver:clz selector:@selector(_sessionDidDeactivate) name:NSWorkspaceSessionDidResignActiveNotification object:nil];
michaelm@5177 429 break;
michaelm@5177 430 case com_apple_eawt__AppEventHandler_REGISTER_SCREEN_SLEEP:
michaelm@5177 431 [ctr addObserver:clz selector:@selector(_screenDidSleep) name:NSWorkspaceScreensDidSleepNotification object:nil];
michaelm@5177 432 [ctr addObserver:clz selector:@selector(_screenDidWake) name:NSWorkspaceScreensDidWakeNotification object:nil];
michaelm@5177 433 break;
michaelm@5177 434 case com_apple_eawt__AppEventHandler_REGISTER_SYSTEM_SLEEP:
michaelm@5177 435 [ctr addObserver:clz selector:@selector(_systemDidSleep) name:NSWorkspaceWillSleepNotification object:nil];
michaelm@5177 436 [ctr addObserver:clz selector:@selector(_systemDidWake) name:NSWorkspaceDidWakeNotification object:nil];
michaelm@5177 437 break;
michaelm@5177 438 default:
michaelm@5177 439 NSLog(@"EAWT attempting to register for unknown notification: %d", (int)notificationType);
michaelm@5177 440 break;
michaelm@5177 441 }
michaelm@5177 442 }
michaelm@5177 443
michaelm@5177 444 // Retrieves the menu to be attached to the Dock icon (AppKit callback)
michaelm@5177 445 - (NSMenu *)applicationDockMenu:(NSApplication *)sender {
michaelm@5177 446 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 447 return self.fDockMenu;
michaelm@5177 448 }
michaelm@5177 449
michaelm@5177 450 - (CMenuBar *)defaultMenuBar {
michaelm@5177 451 return [[self.fDefaultMenuBar retain] autorelease];
michaelm@5177 452 }
michaelm@5177 453
michaelm@5177 454
michaelm@5177 455 #pragma mark Helpers called on the main thread from Java
michaelm@5177 456
michaelm@5177 457 // Sets a new NSImageView on the Dock tile
michaelm@5177 458 + (void)_setDockIconImage:(NSImage *)image {
michaelm@5177 459 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 460
michaelm@5177 461 NSDockTile *dockTile = [NSApp dockTile];
michaelm@5177 462 if (image == nil) {
michaelm@5177 463 [dockTile setContentView:nil];
michaelm@5177 464 return;
michaelm@5177 465 }
michaelm@5177 466
michaelm@5177 467 // setup an image view for the dock tile
michaelm@5177 468 NSRect frame = NSMakeRect(0, 0, dockTile.size.width, dockTile.size.height);
michaelm@5177 469 NSImageView *dockImageView = [[NSImageView alloc] initWithFrame: frame];
michaelm@5177 470 [dockImageView setImageScaling:NSImageScaleProportionallyUpOrDown];
michaelm@5177 471 [dockImageView setImage:image];
michaelm@5177 472
michaelm@5177 473 // add it to the NSDockTile
michaelm@5177 474 [dockTile setContentView: dockImageView];
michaelm@5177 475 [dockTile display];
michaelm@5177 476
michaelm@5177 477 [dockImageView release];
michaelm@5177 478 }
michaelm@5177 479
michaelm@5177 480 // Obtains the image of the Dock icon, either manually set, a drawn copy, or the default NSApplicationIcon
michaelm@5177 481 + (NSImage *)_dockIconImage {
michaelm@5177 482 AWT_ASSERT_APPKIT_THREAD;
michaelm@5177 483
michaelm@5177 484 NSDockTile *dockTile = [NSApp dockTile];
michaelm@5177 485 NSView *view = [dockTile contentView];
michaelm@5177 486
michaelm@5177 487 if ([view isKindOfClass:[NSImageView class]]) {
michaelm@5177 488 NSImage *img = [((NSImageView *)view) image];
michaelm@5177 489 if (img) return img;
michaelm@5177 490 }
michaelm@5177 491
michaelm@5177 492 if (view == nil) {
michaelm@5177 493 return [NSImage imageNamed:@"NSApplicationIcon"];
michaelm@5177 494 }
michaelm@5177 495
michaelm@5177 496 NSRect frame = [view frame];
michaelm@5177 497 NSImage *image = [[NSImage alloc] initWithSize:frame.size];
michaelm@5177 498 [image lockFocus];
michaelm@5177 499 [view drawRect:frame];
michaelm@5177 500 [image unlockFocus];
michaelm@5177 501 [image autorelease];
michaelm@5177 502 return image;
michaelm@5177 503 }
michaelm@5177 504
michaelm@5177 505 @end
michaelm@5177 506
michaelm@5177 507
michaelm@5177 508 #pragma mark Native JNI calls
michaelm@5177 509
michaelm@5177 510 /*
michaelm@5177 511 * Class: com_apple_eawt_Application
michaelm@5177 512 * Method: nativeInitializeApplicationDelegate
michaelm@5177 513 * Signature: ()V
michaelm@5177 514 */
michaelm@5177 515 JNIEXPORT void JNICALL Java_com_apple_eawt_Application_nativeInitializeApplicationDelegate
michaelm@5177 516 (JNIEnv *env, jclass clz)
michaelm@5177 517 {
michaelm@5177 518 JNF_COCOA_ENTER(env);
michaelm@5177 519 // Force initialization to happen on AppKit thread!
serb@7373 520 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
michaelm@5177 521 [ApplicationDelegate sharedDelegate];
michaelm@5177 522 }];
michaelm@5177 523 JNF_COCOA_EXIT(env);
michaelm@5177 524 }
michaelm@5177 525
michaelm@5177 526 /*
michaelm@5177 527 * Class: com_apple_eawt__AppEventHandler
michaelm@5177 528 * Method: nativeOpenCocoaAboutWindow
michaelm@5177 529 * Signature: ()V
michaelm@5177 530 */
michaelm@5177 531 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeOpenCocoaAboutWindow
michaelm@5177 532 (JNIEnv *env, jclass clz)
michaelm@5177 533 {
michaelm@5177 534 JNF_COCOA_ENTER(env);
michaelm@5177 535
serb@7373 536 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
michaelm@5177 537 [NSApp orderFrontStandardAboutPanel:nil];
michaelm@5177 538 }];
michaelm@5177 539
michaelm@5177 540 JNF_COCOA_EXIT(env);
michaelm@5177 541 }
michaelm@5177 542
michaelm@5177 543 /*
michaelm@5177 544 * Class: com_apple_eawt__AppEventHandler
michaelm@5177 545 * Method: nativeReplyToAppShouldTerminate
michaelm@5177 546 * Signature: (Z)V
michaelm@5177 547 */
michaelm@5177 548 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeReplyToAppShouldTerminate
michaelm@5177 549 (JNIEnv *env, jclass clz, jboolean doTerminate)
michaelm@5177 550 {
michaelm@5177 551 JNF_COCOA_ENTER(env);
michaelm@5177 552
serb@7373 553 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
michaelm@5177 554 [NSApp replyToApplicationShouldTerminate:doTerminate];
michaelm@5177 555 }];
michaelm@5177 556
michaelm@5177 557 JNF_COCOA_EXIT(env);
michaelm@5177 558 }
michaelm@5177 559
michaelm@5177 560 /*
michaelm@5177 561 * Class: com_apple_eawt__AppEventHandler
michaelm@5177 562 * Method: nativeRegisterForNotification
michaelm@5177 563 * Signature: (I)V
michaelm@5177 564 */
michaelm@5177 565 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppEventHandler_nativeRegisterForNotification
michaelm@5177 566 (JNIEnv *env, jclass clz, jint notificationType)
michaelm@5177 567 {
michaelm@5177 568 JNF_COCOA_ENTER(env);
michaelm@5177 569 [ThreadUtilities performOnMainThread:@selector(_registerForNotification:)
pchelko@7871 570 on:[ApplicationDelegate class]
michaelm@5177 571 withObject:[NSNumber numberWithInt:notificationType]
pchelko@7871 572 waitUntilDone:NO]; // AWT_THREADING Safe (non-blocking)
michaelm@5177 573 JNF_COCOA_EXIT(env);
michaelm@5177 574 }
michaelm@5177 575
michaelm@5177 576 /*
michaelm@5177 577 * Class: com_apple_eawt__AppDockIconHandler
michaelm@5177 578 * Method: nativeSetDockMenu
michaelm@5177 579 * Signature: (J)V
michaelm@5177 580 */
michaelm@5177 581 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockMenu
michaelm@5177 582 (JNIEnv *env, jclass clz, jlong nsMenuPtr)
michaelm@5177 583 {
michaelm@5177 584 JNF_COCOA_ENTER(env);
michaelm@5177 585
michaelm@5177 586 NSMenu *menu = (NSMenu *)jlong_to_ptr(nsMenuPtr);
serb@7373 587 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
michaelm@5177 588 [ApplicationDelegate sharedDelegate].fDockMenu = menu;
michaelm@5177 589 }];
michaelm@5177 590
michaelm@5177 591 JNF_COCOA_EXIT(env);
michaelm@5177 592 }
michaelm@5177 593
michaelm@5177 594 /*
michaelm@5177 595 * Class: com_apple_eawt__AppDockIconHandler
michaelm@5177 596 * Method: nativeSetDockIconImage
michaelm@5177 597 * Signature: (J)V
michaelm@5177 598 */
michaelm@5177 599 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconImage
michaelm@5177 600 (JNIEnv *env, jclass clz, jlong nsImagePtr)
michaelm@5177 601 {
michaelm@5177 602 JNF_COCOA_ENTER(env);
michaelm@5177 603
michaelm@5177 604 NSImage *_image = (NSImage *)jlong_to_ptr(nsImagePtr);
serb@7373 605 [ThreadUtilities performOnMainThread:@selector(_setDockIconImage:)
serb@7373 606 on:[ApplicationDelegate class]
serb@7373 607 withObject:_image
serb@7373 608 waitUntilDone:NO];
michaelm@5177 609
michaelm@5177 610 JNF_COCOA_EXIT(env);
michaelm@5177 611 }
michaelm@5177 612
michaelm@5177 613 /*
michaelm@5177 614 * Class: com_apple_eawt__AppDockIconHandler
michaelm@5177 615 * Method: nativeGetDockIconImage
michaelm@5177 616 * Signature: ()J
michaelm@5177 617 */
michaelm@5177 618 JNIEXPORT jlong JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeGetDockIconImage
michaelm@5177 619 (JNIEnv *env, jclass clz)
michaelm@5177 620 {
michaelm@5177 621 __block NSImage *image = nil;
michaelm@5177 622
michaelm@5177 623 JNF_COCOA_ENTER(env);
michaelm@5177 624
serb@7373 625 [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
michaelm@5177 626 image = [ApplicationDelegate _dockIconImage];
michaelm@5177 627 CFRetain(image);
michaelm@5177 628 }];
michaelm@5177 629
michaelm@5177 630 JNF_COCOA_EXIT(env);
michaelm@5177 631
michaelm@5177 632 return ptr_to_jlong(image);
michaelm@5177 633 }
michaelm@5177 634
michaelm@5177 635 /*
michaelm@5177 636 * Class: com_apple_eawt__AppDockIconHandler
michaelm@5177 637 * Method: nativeSetDockIconBadge
michaelm@5177 638 * Signature: (Ljava/lang/String;)V
michaelm@5177 639 */
michaelm@5177 640 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconBadge
michaelm@5177 641 (JNIEnv *env, jclass clz, jstring badge)
michaelm@5177 642 {
michaelm@5177 643 JNF_COCOA_ENTER(env);
michaelm@5177 644
michaelm@5177 645 NSString *badgeString = JNFJavaToNSString(env, badge);
serb@7373 646 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
michaelm@5177 647 NSDockTile *dockTile = [NSApp dockTile];
michaelm@5177 648 [dockTile setBadgeLabel:badgeString];
michaelm@5177 649 [dockTile display];
michaelm@5177 650 }];
michaelm@5177 651
michaelm@5177 652 JNF_COCOA_EXIT(env);
michaelm@5177 653 }
michaelm@5177 654
michaelm@5177 655 /*
michaelm@5177 656 * Class: com_apple_eawt__AppMiscHandlers
michaelm@5177 657 * Method: nativeRequestActivation
michaelm@5177 658 * Signature: (Z)V
michaelm@5177 659 */
michaelm@5177 660 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeRequestActivation
michaelm@5177 661 (JNIEnv *env, jclass clz, jboolean allWindows)
michaelm@5177 662 {
michaelm@5177 663 JNF_COCOA_ENTER(env);
michaelm@5177 664
serb@7373 665 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
michaelm@5177 666 NSApplicationActivationOptions options = allWindows ? NSApplicationActivateAllWindows : 0;
michaelm@5177 667 options |= NSApplicationActivateIgnoringOtherApps; // without this, nothing happens!
michaelm@5177 668 [[NSRunningApplication currentApplication] activateWithOptions:options];
michaelm@5177 669 }];
michaelm@5177 670
michaelm@5177 671 JNF_COCOA_EXIT(env);
michaelm@5177 672 }
michaelm@5177 673
michaelm@5177 674 /*
michaelm@5177 675 * Class: com_apple_eawt__AppMiscHandlers
michaelm@5177 676 * Method: nativeRequestUserAttention
michaelm@5177 677 * Signature: (Z)V
michaelm@5177 678 */
michaelm@5177 679 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeRequestUserAttention
michaelm@5177 680 (JNIEnv *env, jclass clz, jboolean critical)
michaelm@5177 681 {
michaelm@5177 682 JNF_COCOA_ENTER(env);
michaelm@5177 683
serb@7373 684 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
michaelm@5177 685 [NSApp requestUserAttention:critical ? NSCriticalRequest : NSInformationalRequest];
michaelm@5177 686 }];
michaelm@5177 687
michaelm@5177 688 JNF_COCOA_EXIT(env);
michaelm@5177 689 }
michaelm@5177 690
michaelm@5177 691 /*
michaelm@5177 692 * Class: com_apple_eawt__AppMiscHandlers
michaelm@5177 693 * Method: nativeOpenHelpViewer
michaelm@5177 694 * Signature: ()V
michaelm@5177 695 */
michaelm@5177 696 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeOpenHelpViewer
michaelm@5177 697 (JNIEnv *env, jclass clz)
michaelm@5177 698 {
michaelm@5177 699 JNF_COCOA_ENTER(env);
michaelm@5177 700
serb@7373 701 [ThreadUtilities performOnMainThread:@selector(showHelp:)
serb@7373 702 on:NSApp
serb@7373 703 withObject:nil
serb@7373 704 waitUntilDone:NO];
michaelm@5177 705
michaelm@5177 706 JNF_COCOA_EXIT(env);
michaelm@5177 707 }
michaelm@5177 708
michaelm@5177 709 /*
michaelm@5177 710 * Class: com_apple_eawt__AppMiscHandlers
michaelm@5177 711 * Method: nativeEnableSuddenTermination
michaelm@5177 712 * Signature: ()V
michaelm@5177 713 */
michaelm@5177 714 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeEnableSuddenTermination
michaelm@5177 715 (JNIEnv *env, jclass clz)
michaelm@5177 716 {
michaelm@5177 717 JNF_COCOA_ENTER(env);
michaelm@5177 718
michaelm@5177 719 [[NSProcessInfo processInfo] enableSuddenTermination]; // Foundation thread-safe
michaelm@5177 720
michaelm@5177 721 JNF_COCOA_EXIT(env);
michaelm@5177 722 }
michaelm@5177 723
michaelm@5177 724 /*
michaelm@5177 725 * Class: com_apple_eawt__AppMiscHandlers
michaelm@5177 726 * Method: nativeDisableSuddenTermination
michaelm@5177 727 * Signature: ()V
michaelm@5177 728 */
michaelm@5177 729 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMiscHandlers_nativeDisableSuddenTermination
michaelm@5177 730 (JNIEnv *env, jclass clz)
michaelm@5177 731 {
michaelm@5177 732 JNF_COCOA_ENTER(env);
michaelm@5177 733
michaelm@5177 734 [[NSProcessInfo processInfo] disableSuddenTermination]; // Foundation thread-safe
michaelm@5177 735
michaelm@5177 736 JNF_COCOA_EXIT(env);
michaelm@5177 737 }
michaelm@5177 738
michaelm@5177 739 /*
michaelm@5177 740 * Class: com_apple_eawt__AppMenuBarHandler
michaelm@5177 741 * Method: nativeSetMenuState
michaelm@5177 742 * Signature: (IZZ)V
michaelm@5177 743 */
michaelm@5177 744 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMenuBarHandler_nativeSetMenuState
michaelm@5177 745 (JNIEnv *env, jclass clz, jint menuID, jboolean visible, jboolean enabled)
michaelm@5177 746 {
michaelm@5177 747 JNF_COCOA_ENTER(env);
michaelm@5177 748
serb@7373 749 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
michaelm@5177 750 ApplicationDelegate *delegate = [ApplicationDelegate sharedDelegate];
michaelm@5177 751 switch (menuID) {
michaelm@5177 752 case com_apple_eawt__AppMenuBarHandler_MENU_ABOUT:
michaelm@5177 753 [delegate _updateAboutMenu:visible enabled:enabled];
michaelm@5177 754 break;
michaelm@5177 755 case com_apple_eawt__AppMenuBarHandler_MENU_PREFS:
michaelm@5177 756 [delegate _updatePreferencesMenu:visible enabled:enabled];
michaelm@5177 757 break;
michaelm@5177 758 }
michaelm@5177 759 }];
michaelm@5177 760
michaelm@5177 761 JNF_COCOA_EXIT(env);
michaelm@5177 762 }
michaelm@5177 763
michaelm@5177 764 /*
michaelm@5177 765 * Class: com_apple_eawt__AppMenuBarHandler
michaelm@5177 766 * Method: nativeSetDefaultMenuBar
michaelm@5177 767 * Signature: (J)V
michaelm@5177 768 */
michaelm@5177 769 JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMenuBarHandler_nativeSetDefaultMenuBar
michaelm@5177 770 (JNIEnv *env, jclass clz, jlong cMenuBarPtr)
michaelm@5177 771 {
michaelm@5177 772 JNF_COCOA_ENTER(env);
michaelm@5177 773
michaelm@5177 774 CMenuBar *menu = (CMenuBar *)jlong_to_ptr(cMenuBarPtr);
serb@7373 775 [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
michaelm@5177 776 [ApplicationDelegate sharedDelegate].fDefaultMenuBar = menu;
michaelm@5177 777 }];
michaelm@5177 778
michaelm@5177 779 JNF_COCOA_EXIT(env);
michaelm@5177 780 }