Search code examples
objective-cmacoscocoadocument-basednsdocumentcontroller

Disable Open Panel in Cocoa Document Based App Launch


I have written a document based application which has disabled auto-creation of new documents when the app launches without restoring a previously opened document.

Now I would also like to disable the open panel that appears on app launch.

The open panel is being launched sometimes between applicationWillFinishLaunching: and applicationDidFinishLaunching: in my app delegate.

The only way that I can figure out how to disable this functionality is to overwrite [NSDocumentController openDocument:] in a subclass and then create a secondary 'helper' method that I would then connect to the File>Open menu. This seems like a very hacky solution and want to see if anyone has any better ideas.

1   Core Animator                       0x0000000100042121 -[NSDocumentController openDocument:] + 49
2   AppKit                              0x00007fff8772ffe6 -[NSDocumentController(NSInternal) _showOpenPanel] + 63
3   AppKit                              0x00007fff87244184 -[NSApplication _doOpenUntitled] + 290
4   AppKit                              0x00007fff87243c91 __58-[NSApplication(NSAppleEventHandling) _handleAEOpenEvent:]_block_invoke + 252
5   AppKit                              0x00007fff87243a59 __97-[NSDocumentController(NSInternal) _autoreopenDocumentsIgnoringExpendable:withCompletionHandler:]_block_invoke_3 + 140
6   AppKit                              0x00007fff872435a1 -[NSDocumentController(NSInternal) _autoreopenDocumentsIgnoringExpendable:withCompletionHandler:] + 798
7   AppKit                              0x00007fff87241cc6 -[NSApplication _reopenWindowsAsNecessaryIncludingRestorableState:registeringAsReady:completionHandler:] + 331
8   AppKit                              0x00007fff87241a49 -[NSApplication(NSAppleEventHandling) _handleAEOpenEvent:] + 561
9   AppKit                              0x00007fff87241495 -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] + 244

Solution

  • I was not able to find an acceptable built in solution so after a bit of debugging I ended up finding a good override point in NSDocumentController. This is a very hacky solution – but it is the best I could come up with.

    [NSDocumentController openDocument:] is the method that get's called and handles the loading of the Open Panel in Cocoa Document Based Applications. This is also the method that is connected to the File > Open menu item. So two steps are necessary.

    1.) Create an NSDocumentController subclass and override open document.

    @interface MyDocumentController : NSDocumentController
    
    /// Connected to File>Open menu item in replacement of openDocument:.
    /// openDocument: is called sometimes at app launch to present user with open window.
    /// This has been disabled by overriding openDocument:
    /// This method is now used in the Main Menu to replace it
    - (IBAction)openDocumentOverride:(id)sender;
    
    @end
    

    and

    #import "MyDocumentController.h"
    
    @implementation MyDocumentController
    
    // New method to replace openDocument: in File>Open menu item.
    - (IBAction)openDocumentOverride:(id)sender {
        [super openDocument:sender];
    }
    
    // Override method to prevent call on app open
    - (IBAction)openDocument:(id)sender {}
    
    @end
    

    2.) Then in your MainMenu.xib connect the File>Open menu item to [MyDocumentController openDocumentOverride:].


    Now the File > Open menu item works but it will not be able to display the Open box on app launch.