0

My document-based cocoa app has a shared inspector window whose contents change depending on which document is active.

The inspector window controller is a shared singleton, instantiated form its storyboard on demand.

The document class simply creates its main window from a storyboard, and becomes the window's delegate:

class Document: NSDocument {

    override func makeWindowControllers() {
    let storyboard = NSStoryboard(name: "Main", bundle: nil)
    guard let windowController = storyboard.instantiateController(withIdentifier: "Document Window Controller") as? NSWindowController else {
        fatalError("Storyboard Inconsistency!")
    }

    windowController.window?.delegate = self

    self.addWindowController(windowController)
}

Whenever a document's main window becomes active, it adds the inspector's window controller to its own:

extension Document: NSWindowDelegate {

    func windowDidBecomeMain(_ notification: Notification) {
        self.addWindowController(InspectorWindowController.shared)
    }
}

(this also updates the window controller's document property)

In anticipation to the case where the last document is closed, I also added:

func windowWillClose(_ notification: Notification) {
    self.removeWindowController(InspectorWindowController.shared)
}

(This is only needed for the last document, since otherwise the new active document takes over and the window controller is automatically removed from the closing document once it is added to the newly activated document)

The Inspector itself overrides the property document and the method windowTitle(forDocumentDisplayName:), in order to keep up with the active document:

class InspectorWindowController override var document: AnyObject? { didSet { // (Update view controller's contents) } }

override func windowTitle(forDocumentDisplayName displayName: String) -> String {
     if document == nil {
          return "Inspector - No Active Document"
     } else {
          return "Inspector - \(displayName)"
     }
}

The problem is, when I close the last open document window, the inspector's window title stays at the (custom) title set for the last document. That is, when the inspector window controller's document property is set to nil, windowTitle(forDocumentDisplayName:) is not called.

Even calling synchronizeWindowTitleWithDocumentName() does not help, since the docs clearly mention that:

Does nothing if the window controller has no associated document or loaded window. This method queries the window controller’s document to get the document’s display name and full filename path, then calls windowTitle(forDocumentDisplayName:) to get the display name to show in the window title.

(emphasis mine)

I can reset the Inspector's content to the "No document" state; How can I do the same for the window title?

Nicolas Miari
  • 16,006
  • 8
  • 81
  • 189
  • What should the inspector window controllers title be when the last document is closed? – l'L'l Mar 14 '17 at 08:06
  • Something along the lines of "Imnspector (no document selected)" (it's already in the question). In any case, the name of the last document -which is closed- is no good. – Nicolas Miari Mar 14 '17 at 08:07

1 Answers1

0

OK, I found the (silly and obvious) answer:

override var document: AnyObject? {
    didSet {
        // (Update view controller's contents, etc...)

        if document == nil {
            self.window?.title = "Inspector - No Active Document"
        }
    }
}

I'm not sure if this is the correct way of dealing with it, but it does get the job done.

I will accept any better answer though.

Nicolas Miari
  • 16,006
  • 8
  • 81
  • 189
  • 1
    I was going to suggest exactly that, or perhaps `func removeDocument(NSDocument)`, or `var currentDocument: NSDocument?`... – l'L'l Mar 14 '17 at 08:19