0

I am facing difficulty presenting my app window on a specific screen (i.e., the main display as opposed to my external display). The reason why I want to display my app on the main display is that I would like to blank out my external display later on by using CGDisplayCapture(CGDirectDisplayID(2)).

I found several suggestions and implementations as follows.

Swift 3/macOS: Open window on certain screen

How to change the NSScreen a NSWindow appears on

Show window on multiple displays on os x

how to move NSWindow to a particular screen?

However, I cannot figure out how to actualize this in Swift 5. This could be because the previous posts got outdated. For example, the following my code (based on Swift 3/macOS: Open window on certain screen) does not work... it does not do anything.

override func viewDidLoad() {
    super.viewDidLoad()
    
    //set up the main display as the display where window shows up
    let screens = NSScreen.screens
    var pos = NSPoint()
    pos.x = screens[0].visibleFrame.midX
    pos.y = screens[0].visibleFrame.midY
    self.view.window?.setFrameOrigin(pos)

I would appreciate it if I could hear how to implement this.

Added:

The answer provided to Cocoa show NSWindow on a specific screen seems to be written in objective-c. Unfortunately, I do not understand objective-c.

Added:

Thanks to the answer provided by @al45tair, I tried to use windowController in appDegate as follows:

 func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Insert code here to initialize your application
    let storyboard = NSStoryboard(name: "Main", bundle: nil)
    if let windowController = storyboard.instantiateController(withIdentifier: "mainWindow") as? NSWindowController {
        
        //keep the window top
        windowController.window?.level = .floating


        //set up the main display as the display where window shows up
        let screens = NSScreen.screens
        var pos = NSPoint()
        pos.x = screens[0].visibleFrame.midX
        pos.y = screens[0].visibleFrame.midY
        windowController.window?.setFrameOrigin(pos)


        windowController.window?.zoom(self)
        windowController.window?.level = .floating
        windowController.window?.backgroundColor = NSColor.white

        //stop the user from moving window
        windowController.window?.isMovable = false
        //disable resizable mode
        windowController.window?.styleMask.remove(.resizable)
        windowController.showWindow(self)

    } else {
        print ("failed to show the window")
    }
 }

I also ticked off the main window controller as initial controller (because otherwise, I get two same initial windows). However, I realized by using this method, I cannot hide and show the window by using self.view.window?.setIsVisible(false) (or true) in ViewController.swift. What am I doing wrong?

user8460166
  • 73
  • 1
  • 6
  • 24
  • Does `self.view.window` return a window? – Willeke Dec 06 '21 at 10:53
  • Thank you for the question! I checked and realized that `self.view.window` does not return a window! How could I go from here? – user8460166 Dec 06 '21 at 12:35
  • Does this answer your question? [Cocoa show NSWindow on a specific screen](https://stackoverflow.com/questions/33710289/cocoa-show-nswindow-on-a-specific-screen) – Willeke Dec 07 '21 at 07:28
  • Thank you, @Willeke. The things is, the provided answer in the linked question seems to be written in `objective-c` And I do not understand objective-c. I am looking for a `swift 5` alternative. – user8460166 Dec 07 '21 at 10:04

2 Answers2

1

The ViewController isn't the right place to be doing this. Either use a WindowController and put the relevant code in windowDidLoad, or, if you really want a view that causes its parent window to fill the primary display, override viewDidMoveToWindow on your view. (The latter would be a bit odd in most cases IMO.)

al45tair
  • 4,405
  • 23
  • 30
  • Thank you very much, @al45tair for your answer! I really appreciate learning this as a very beginner. If possible, could you elaborate on why I should not deal this (self.view.window?? And related stuff ? ) in `ViewController`? It would also be of great help if you could provide a simple sample code where this is implemented in `WindowController`. I have been looking for sample codes dealing with screens, but I have not been able to find simple codes with explanations that I can understand online. – user8460166 Dec 06 '21 at 14:21
0

Thanks to the question asked by @Willeke, I was able to use the following code to display the window on the main screen (as opposed to external displays). I just needed to use DispatchQueue.main.async {}.

   override func viewDidLoad() {
         super.viewDidLoad()
         DispatchQueue.main.async {
             
             //set up the main display as the display where window shows up
             let screens = NSScreen.screens
             var pos = NSPoint()
             pos.x = screens[0].visibleFrame.midX
             pos.y = screens[0].visibleFrame.midY
             self.view.window?.setFrameOrigin(pos)
             
         }
    }
user8460166
  • 73
  • 1
  • 6
  • 24