使用CGBeginDisplayConfiguration切換 Mac 顯示器排列

有遇到這種情況嗎辙浑?當(dāng)你有一臺外借顯示器和一臺 Macbook激涤,而且你的顯示器是有支架可以移動的!有時(shí)候判呕,我把筆記本放在顯示器右邊寫代碼倦踢,而有時(shí)候,我把顯示器放在電腦正上方碼字侠草,而有時(shí)候辱挥,我還想把顯示器豎起來?边涕?(喂晤碘,你怎么那么無聊肮游ⅰ!)感覺每次到設(shè)置-顯示器排列里面拖太麻煩了园爷?(其實(shí)并沒有 QAQ)讓我們用簡單的幾行 Swift 代碼實(shí)現(xiàn)一個 Mac 程序剞劂他吧宠蚂!

獲取目前顯示器信息

  • 獲取顯示器配置比較簡單,我們可以通過一行代碼搞定它童社。
    NSScreen.screens()
  • 獲取的結(jié)果是一個 NSScreen數(shù)組求厕。
  • 對于每個 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)
  • 之后灭抑,自己處理這些信息的保存十艾,用于后續(xù)一鍵配置顯示器排列中使用~

配置顯示器信息

  • 首先我們要創(chuàng)建一個 config 指針用于后續(xù)各種配置

    import AppKit
    
    let config = UnsafeMutablePointer<CGDisplayConfigRef?>.allocate(capacity:1)
    
  • 調(diào)用 CGBeginDisplayConfiguration開始配置顯示器

    CGBeginDisplayConfiguration(config)
    

    現(xiàn)在開始配置。

     for display in displays{ //假設(shè)這里有個 display s 數(shù)組存儲了各個顯示器的相關(guān)信息(display 為自定義結(jié)構(gòu)體)
                
                let error:CGError
                
                if display.position_x == 0 && display.position_y == 0{
                    
                    //坐標(biāo)為(0腾节,0)的顯示器可以直接設(shè)置無需計(jì)算坐標(biāo)矯正
                    error = CGConfigureDisplayOrigin(config.pointee, display.screen_id, 0, 0)
                   
                }else{
                    //其他顯示器需要計(jì)算坐標(biāo)偏移忘嫉,將在下面講解。
                    error = CGConfigureDisplayOrigin(config.pointee, display.screen_id, display.position_x, -display.position_y - display.screen_height + main_height)
                }
                
                if error != .success{
                    //若配置失敗案腺,取消配置庆冕,防止內(nèi)存泄漏等現(xiàn)象
                    CGCancelDisplayConfiguration(config.pointee)
                    return
                }
                
    }
    
    

    為什么需要計(jì)算坐標(biāo)偏移呢?
    如下圖劈榨,在我們之前通過 NSScreen.screens 獲取的 Screen 坐標(biāo)中访递,坐標(biāo)系的原點(diǎn)是主顯示器的左下角,也就是說所有顯示器都是以左下角為基準(zhǔn)計(jì)算偏移量的同辣。如下圖拷姿。

downleft.png
而我們通過 api 進(jìn)行排列設(shè)置的時(shí)候,很坑的是此時(shí)系統(tǒng)坐標(biāo)系是以顯示器的左上角為原點(diǎn)計(jì)算偏移量的旱函!如下圖响巢。注意此時(shí)主顯示器設(shè)置的坐標(biāo)依然是(0,0),而其他顯示器的坐標(biāo)的 y 軸就需要進(jìn)行小小的轉(zhuǎn)換。對了,系統(tǒng)坐標(biāo)系中棒妨,x 坐標(biāo)軸是從左往右踪古,而` y 軸坐標(biāo)是從上往下`。不要弄錯了 ORZ券腔。
upleft.png
于是伏穆,目前來看,公式應(yīng)該是這樣的(簡單小學(xué)數(shù)學(xué)纷纫?)主顯示器 y 軸分辨率 - 所設(shè)置顯示器豎向辨率大小 - 所設(shè)置顯示器之前所獲得y軸坐標(biāo)

- 完成顯示器配置

``` Swift
    let error = CGCompleteDisplayConfiguration(config.pointee, .permanently) //設(shè)置配置為永久
        if error != .success{
            CGCancelDisplayConfiguration(config.pointee)
        }

```

## Finished枕扫!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市辱魁,隨后出現(xiàn)的幾起案子铡原,更是在濱河造成了極大的恐慌偷厦,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件燕刻,死亡現(xiàn)場離奇詭異只泼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)卵洗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門请唱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人过蹂,你說我怎么就攤上這事十绑。” “怎么了酷勺?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵本橙,是天一觀的道長。 經(jīng)常有香客問我脆诉,道長甚亭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任击胜,我火速辦了婚禮亏狰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘偶摔。我一直安慰自己暇唾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布辰斋。 她就那樣靜靜地躺著策州,像睡著了一般。 火紅的嫁衣襯著肌膚如雪宫仗。 梳的紋絲不亂的頭發(fā)上够挂,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機(jī)與錄音锰什,去河邊找鬼。 笑死丁逝,一個胖子當(dāng)著我的面吹牛汁胆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播霜幼,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼嫩码,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了罪既?” 一聲冷哼從身側(cè)響起铸题,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤铡恕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后丢间,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體探熔,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年烘挫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诀艰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡饮六,死狀恐怖其垄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情卤橄,我是刑警寧澤绿满,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站窟扑,受9級特大地震影響喇颁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜辜膝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一无牵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧厂抖,春花似錦茎毁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至墙懂,卻和暖如春橡卤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背损搬。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工碧库, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人巧勤。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓嵌灰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親颅悉。 傳聞我的和親對象是個殘疾皇子沽瞭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)剩瓶,斷路器驹溃,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,773評論 6 342
  • 柳塘韻透城丧,玉碗盈漿漸翠。幽寒已過千山豌鹤,乾暑未臨萬水亡哄。難信海棠窗下,孰敢濃妝傍药,自比新花媚磺平。 雕欄倚」樟桑看遍桃紅李紫拣挪。可...
    深藍(lán)色木魚閱讀 277評論 2 7