美文网首页
使用CGBeginDisplayConfiguration切换

使用CGBeginDisplayConfiguration切换

作者: 称一称 | 来源:发表于2017-05-04 10:33 被阅读0次

    有遇到这种情况吗?当你有一台外借显示器和一台 Macbook,而且你的显示器是有支架可以移动的!有时候,我把笔记本放在显示器右边写代码,而有时候,我把显示器放在电脑正上方码字,而有时候,我还想把显示器竖起来??(喂,你怎么那么无聊啊!)感觉每次到设置-显示器排列里面拖太麻烦了?(其实并没有 QAQ)让我们用简单的几行 Swift 代码实现一个 Mac 程序剞劂他吧!

    获取目前显示器信息

    • 获取显示器配置比较简单,我们可以通过一行代码搞定它。
        NSScreen.screens()
    
    • 获取的结果是一个 NSScreen数组。
    • 对于每个 NSScreen 对象,我们可以用screen.deviceDescription 获取显示器信息的 NSDictionary 基本信息字典,从而获取我们需要的基本信息,长这样。
        let screen_info = screen.deviceDescription
        print(screen_info)
    
    // ["NSDeviceBitsPerSample": 8, "NSDeviceColorSpaceName": NSCalibratedRGBColorSpace, "NSScreenNumber": 69680128, "NSDeviceSize": NSSize: {1440, 900}, "NSDeviceResolution": NSSize: {72, 72}, "NSDeviceIsScreen": YES]
    
    
    
            screen_id = screen_info["NSScreenNumber"] as! CGDirectDisplayID // screen_id 用来指定要配置的显示器
    
            let screen_size = screen_info["NSDeviceSize"] as! NSSize
            screen_width = Int32(screen_size.width)
            screen_height = Int32(screen_size.height)
            
            let position = screen.frame
            position_x = Int32(position.origin.x)
            position_y = Int32(position.origin.y)
    
    • 之后,自己处理这些信息的保存,用于后续一键配置显示器排列中使用~

    配置显示器信息

    • 首先我们要创建一个 config 指针用于后续各种配置

      import AppKit
      
      let config = UnsafeMutablePointer<CGDisplayConfigRef?>.allocate(capacity:1)
      
    • 调用 CGBeginDisplayConfiguration开始配置显示器

      CGBeginDisplayConfiguration(config)
      

      现在开始配置。

       for display in displays{ //假设这里有个 display s 数组存储了各个显示器的相关信息(display 为自定义结构体)
                  
                  let error:CGError
                  
                  if display.position_x == 0 && display.position_y == 0{
                      
                      //坐标为(0,0)的显示器可以直接设置无需计算坐标矫正
                      error = CGConfigureDisplayOrigin(config.pointee, display.screen_id, 0, 0)
                     
                  }else{
                      //其他显示器需要计算坐标偏移,将在下面讲解。
                      error = CGConfigureDisplayOrigin(config.pointee, display.screen_id, display.position_x, -display.position_y - display.screen_height + main_height)
                  }
                  
                  if error != .success{
                      //若配置失败,取消配置,防止内存泄漏等现象
                      CGCancelDisplayConfiguration(config.pointee)
                      return
                  }
                  
      }
      
      

      为什么需要计算坐标偏移呢?
      如下图,在我们之前通过 NSScreen.screens 获取的 Screen 坐标中,坐标系的原点是主显示器的左下角,也就是说所有显示器都是以左下角为基准计算偏移量的。如下图。

    downleft.png
    而我们通过 api 进行排列设置的时候,很坑的是此时系统坐标系是以显示器的左上角为原点计算偏移量的!如下图。注意此时主显示器设置的坐标依然是(0,0),而其他显示器的坐标的 y 轴就需要进行小小的转换。对了,系统坐标系中,x 坐标轴是从左往右,而` y 轴坐标是从上往下`。不要弄错了 ORZ。
    
    upleft.png
    于是,目前来看,公式应该是这样的(简单小学数学?)主显示器 y 轴分辨率 - 所设置显示器竖向辨率大小 - 所设置显示器之前所获得y轴坐标
    
    - 完成显示器配置
    
    ``` Swift
        let error = CGCompleteDisplayConfiguration(config.pointee, .permanently) //设置配置为永久
            if error != .success{
                CGCancelDisplayConfiguration(config.pointee)
            }
    
    ```
    
    ## Finished!

    相关文章

      网友评论

          本文标题:使用CGBeginDisplayConfiguration切换

          本文链接:https://www.haomeiwen.com/subject/isyrtxtx.html