2017-03-15 5 views
2

Je crée une application Cocoa avec une fenêtre flottante. La fenêtre flottante est censée être centrée sur l'écran principal, à une taille qui est 1/4 de l'écran principal. Le Swift suivant est l'essence de ma demande:Comment mon application Cocoa peut-elle être notifiée des changements de résolution de NSScreen?

import Cocoa 
@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate { 
    var panel: NSPanel! 
    func applicationDidFinishLaunching(_ aNotification: Notification) { 
     let screenRect:CGRect = NSScreen.main()!.frame 
     panel = NSPanel(
      contentRect: NSRect(
       x: screenRect.width/4, 
       y: screenRect.height/4, 
       width: screenRect.width/2, 
       height: screenRect.height/2 
      ), 
      styleMask: NSWindowStyleMask.nonactivatingPanel, 
      backing: NSBackingStoreType.buffered, 
      defer: false 
     ) 
     panel.alphaValue = 0.5 
     panel.backgroundColor = NSColor.red 
     panel.level = Int(CGWindowLevelForKey(CGWindowLevelKey.maximumWindow)) 
     panel.orderFront(nil) 
    } 
} 

Cela produit un panneau comme celui-ci:

CORRECTLY POSITIONED

Le problème se pose lorsque les principaux changements de résolution d'écran. Une façon de montrer cela est d'aller dans Préférences Système> Affichages et de définir la résolution sur "Scaled" et "Plus d'espace". Après cela, le groupe ressemble à ceci:

INCORRECTLY POSITIONED AFTER RESOLUTION CHANGE

Comme vous pouvez le voir, la position du panneau est incorrect après la résolution est modifiée. Je souhaite que le panneau maintienne sa position: centré et 1/4 de la taille de l'écran. Pour ce faire, je dois détecter quand la résolution de l'écran (c'est-à-dire, la propriété frame du NSScreen) change, de sorte que je puisse changer la taille et la position du panneau.

Y a-t-il un événement qui est déclenché lorsque la propriété frame d'un NSScreen change? Ou existe-t-il une manière différente de traiter ce problème?

Répondre

0

Avec l'aide de @Adolfo, cela fonctionne:

import Cocoa 
@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate { 
    var panel: NSPanel! 

    func getPanelRect() -> NSRect { 
     let screenRect:CGRect = NSScreen.main()!.frame 
     return NSRect(
      x: screenRect.width/4, 
      y: screenRect.height/4, 
      width: screenRect.width/2, 
      height: screenRect.height/2 
     ) 
    } 

    func applicationDidFinishLaunching(_ aNotification: Notification) { 
     panel = NSPanel(
      contentRect: self.getPanelRect(), 
      styleMask: NSWindowStyleMask.nonactivatingPanel, 
      backing: NSBackingStoreType.buffered, 
      defer: false 
     ) 
     panel.alphaValue = 0.5 
     panel.backgroundColor = NSColor.red 
     panel.level = Int(CGWindowLevelForKey(CGWindowLevelKey.maximumWindow)) 
     panel.orderFront(nil) 

     NotificationCenter.default.addObserver(
      forName: NSNotification.Name.NSApplicationDidChangeScreenParameters, 
      object: NSApplication.shared(), 
      queue: OperationQueue.main 
     ) { notification -> Void in 
      print("screen parameters changed") 
      self.panel.setFrame(self.getPanelRect(), display: true) 
     } 
    } 
}