3

I have an macOS xcode swiftui document-based app. I can see that if I, "view->show tab bar" in the app, I get multiple tabs for free. However, if I do a "file open ...", it creates a new window. Now I eventually found that holding down option when selecting the file will open it in a new tab of an existing window. Does anyone know if it is possible to configure a document-based app to always open in a new tab rather than a new window each time?

altimes
  • 380
  • 2
  • 13
  • Hint: `makeWindowControllers` – El Tomato Sep 15 '21 at 03:46
  • Have you tried the tabbing settings of the window? – Willeke Sep 15 '21 at 07:59
  • I can enable tabs via "Show Tab Bar", which persists between runs. However, each time that I open a new file it is opened into its own tabbed window. I am trying to organise it such that when I open a file it is added to a new tab of the current window. I have found the addTabbedWindow function, which I could use in makeWindowsControllers (where the document window is instantiated). I am currently stuck digging around trying to work out how to find and identify the parent window to use as the arg to addTabbedWindow. – altimes Sep 15 '21 at 08:33
  • Have you tried setting the `tabbingMode` property of the window to `preferred`? – Willeke Sep 16 '21 at 06:00

2 Answers2

1

OK, for anyone who ends up here. Thanks to the hint from El Tomato, I have achieved (mostly) what I wanted. Key steps are:

  1. Get the window in the application that has a tabGroup property that is not nil
  2. Having got that, then use the addTabbedWindow function to add your window to the tabGroup
  3. If the application has no window with a populated tabGroup property, then you have no tabs, so once you have a new window, invoke the toggleTabBar function to show the tabBar. The subsequent calls to makeViewControllers will find the window that contains the tabs.

Code from the makeWindowControllers for me was...

let tabsWindow = NSApplication.shared.windows.filter({$0.tabGroup != nil}).first
let window = NSWindow(
  contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
  styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
  backing: .buffered, defer: false)
window.isReleasedWhenClosed = false
window.center()
window.contentView = NSHostingView(rootView: contentView)
if tabsWindow != nil {tabsWindow!.addTabbedWindow(window, ordered: .below)}
else { window.toggleTabBar(self) }
altimes
  • 380
  • 2
  • 13
1

Set window.tabbingMode to preferred in makeWindowControllers().

override func makeWindowControllers() {
    // Create the SwiftUI view that provides the window contents.
    let contentView = ContentView()

    // Create the window and set the content view.
    let window = NSWindow(
        contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
        styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
        backing: .buffered, defer: false)
    window.isReleasedWhenClosed = false
    window.center()
    window.contentView = NSHostingView(rootView: contentView)
    
    window.tabbingMode = .preferred // open new document in tab
    
    let windowController = NSWindowController(window: window)
    self.addWindowController(windowController)
}
Willeke
  • 14,578
  • 4
  • 19
  • 47
  • Many thanks, even simpler. Easy when you know the magic 8-). However, I learnt a lot other useful stuff along the way. – altimes Sep 19 '21 at 04:20