Window Tabbing Pox

macOS Sierra introduces a new system-wide window tabbing feature, which by default enables tabs within the windows of most document-based apps. Apple’s own TextEdit is a canonical example: open the app and select View -> Show Tab Bar to see how it looks.

Unfortunately, the default tabbing behaviors doesn’t make sense in all apps, even if they are document-based. I’ve had to disable the functionality in both MarsEdit and Black Ink, at least for the time being. Doing so is easy. Just add the following line somewhere early in the lifetime of your app:

NSWindow.allowsAutomaticWindowTabbing = NO;

This class property on NSWindow shuts the whole window tabbing system out of your app, so you don’t have to fuss with how to disable it on a window-by-window basis. Handy!

Unfortunately, setting that property to NO doesn’t do anything about windows that may already have been created, and which have their tab bar visible. I added the line to my app delegate’s applicationDidFinishLaunching: method, assuming that would take care of everything. After all, any documents will be instantiated later in the app’s lifetime, right? Right?

Wrong. Not with window restoration, at least, which causes a freeze-drying and restoration of open document windows when a user quits and relaunches the app. The window in this circumstance is actually created before applicationDidFinishLaunching. If it had its tab bar visible when you quit, it will have the tab bar visible when it’s restored, even if you’ve since disabled all window tabbing for the app.

What’s worse? Showing or hiding the tab bar on any window sets that choice as the default for all future windows in the app. So even new documents that are created by users, and which don’t have their tab bar visible because you’ve disabled it app-wide, will have a tab bar appended when they are restored at launch time, because “Show Tab Bar” was the last user action before disabling tabbing altogether.

The long and short of it? An app stuck in this situation will not have a View -> Show/Hide Tab Bar, and none of its windows will support tabbing, except for any document that is restored at launch time. Even new documents that are created without tab bars will have the tab bar imposed the next launch.

I filed Radar 28578742, suggesting that setting NSWindow.allowsAutomaticWindowTabbing=NO should also turn off window tabbing for any open windows that have it enabled.

If your app gets stuck in this predicament, one workaround is to move the NSWindow.allowsAutomaticWindowTabbing=NO line to an even earlier point in your app’s lifetime, such as in your app’s main.m or main.swift file.