Home > Back-end >  Stop child NSWindow disappearing when moved to another screen
Stop child NSWindow disappearing when moved to another screen

Time:03-01

On macOS Monetrey, when I move a child NSWindow to another screen (by manually dragging it), it disappears. Minimal repro using SwiftUI:

import SwiftUI

struct ContentView: View {
    var body: some View {
        Button("Hello World", action:  openChild)
            .padding(50)
    }
    
    func openChild()  {
        let win = NSWindow();
        let parent = NSApp.mainWindow
        parent?.addChildWindow(win, ordered: NSWindow.OrderingMode.above)
        win.makeKeyAndOrderFront(self)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

(I know this may not be the "correct" SwiftUI way of doing things, it's just to demonstrate the problem in as little code as possible - this happens in low level Obj-C code in reality)

The interesting thing is if you:

  • Show the child window
  • Move it to another screen (it disappears)
  • Select "Window -> Move to [Name of other screen]"

The child window reappears and can now be moved freely between screens.

From user reports I understand that this behavior doesn't occur on Big Sur.

I know there are applications that show child windows and allow them to be moved between screens, what is the correct incantation to allow this?

CodePudding user response:

I do believe you just want to add a second NSWindow, or a NSPanel. Without a child window relation. In AppKit document-based apps you would for example overwrite -[NSDocument makeWindowControllers] and setup multiple window controllers for one document.

Child windows are for special use cases, for example: functionality like autocompletions lists, where you would want a chrome-less window with a table view beneath a textfield, which automatically follows the parent window when moved.

Here is TextEdit with such a autocompletions window and the Xcode Debug View Hierarchy of the same:

TextEdit Xcode Debug View Hierarchy

See this note from the documentation:

After the childWin is added as a child of the window, it is maintained in relative position indicated by place for subsequent ordering operations involving either window. While this attachment is active, moving childWin will not cause the window to move (as in sliding a drawer in or out), but moving the window will cause childWin to move.

I don't believe that a child window was ever intended to be independently moved from its parent window, especially different screens.

  • Related