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.
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.
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?
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)
}
}