Search code examples
javamacoscocoajava-native-interface

NSOpenPanel hangs java app


I have a Swing app and make a JNI method call that opens a NSOpenPanel. On some computers (I didn't find similarities between them, unfortunately) it completely hangs the app. On most computers it works correctly. If the code hangs the app on a particular Mac, it does it every time it executes.

Here is how I open a NSOpenPanel:

JNF_COCOA_ENTER(env);    
// My helper Obj-c object to make a selector call
OpenFileObject *openFile = [[OpenFileObject alloc] init];    
if ([NSThread isMainThread])
    [openFile showOpenFileDialog];
else
    [JNFRunLoop performOnMainThread:@selector(showOpenFileDialog) on:openFile withObject:nullptr waitUntilDone:TRUE];
// ...Handles results    
JNF_COCOA_EXIT(env);

and here is showOpenFileDialog method:

NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setCanChooseFiles:canChooseFiles];
[panel setCanChooseDirectories:canChooseFolders];
[panel setAllowsMultipleSelection:allowMultiSelection];
[panel setAllowedFileTypes:fileTypes];
[panel setTitle:dialogTitle];

if ([panel runModal] == NSFileHandlingPanelOKButton)
    urls = [[panel URLs] copy];
else
    urls = nullptr;

and here is a hang report: https://gist.github.com/4207956

Any ideas?


Solution

  • I found the culprit. The problem was due to another app using the Accessibility API of MacOS. When a modal dialog is shown, the main Java frame doesn't respond to required native Accessibility API calls and this hangs the whole app. Avoiding native modal dialogs solves the problem.

    For example, for NSOpenPanel we should change [panel runModal] to [panel beginSheetModalForWindow]. This solves the problem.