如何获取macOS 14+系统Dock的宽度?适配类Dock窗口布局
在macOS 14+获取Dock实际尺寸的非截图方案
以下是几种无需截图分析即可获取Dock完整尺寸的可行方案,均适配macOS 14+系统:
1. 借助辅助功能AXUIElement API
macOS辅助功能框架允许访问系统应用的UI元素属性,Dock的Bundle ID为com.apple.dock,可通过该API直接获取其位置和尺寸。注意:应用需在系统偏好设置「安全性与隐私」→「辅助功能」中获得用户授权。
示例Swift实现:
import ApplicationServices func getDockFrame() -> CGRect? { guard let dockBundle = Bundle(identifier: "com.apple.dock") else { return nil } let dockElement = AXUIElementCreateApplication(dockBundle.bundleIdentifier!) // 获取位置 var position: AnyObject? guard AXUIElementCopyAttributeValue(dockElement, kAXPositionAttribute as CFString, &position) == .success, let point = position as? CGPoint else { return nil } // 获取尺寸 var size: AnyObject? guard AXUIElementCopyAttributeValue(dockElement, kAXSizeAttribute as CFString, &size) == .success, let dockSize = size as? CGSize else { return nil } return CGRect(origin: point, size: dockSize) }
拿到Dock的frame后,结合当前屏幕宽度即可计算左右空白区域:(屏幕宽度 - Dock宽度) / 2,即为单侧空白的宽度。
2. 通过CGWindowList遍历系统窗口
利用Core Graphics的窗口列表接口,筛选出标记为"Dock"的系统窗口,直接读取其边界信息。该方法无需辅助功能权限,但需注意Dock窗口名称在系统版本中的一致性(macOS 14+中仍为"Dock")。
示例Objective-C实现:
#import <CoreGraphics/CoreGraphics.h> CGRect getDockFrame() { CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID); for (NSDictionary *windowInfo in (__bridge NSArray *)windowList) { NSString *windowName = windowInfo[(id)kCGWindowName]; if ([windowName isEqualToString:@"Dock"]) { NSDictionary *bounds = windowInfo[(id)kCGWindowBounds]; CGRect frame = CGRectMake([bounds[@"X"] floatValue], [bounds[@"Y"] floatValue], [bounds[@"Width"] floatValue], [bounds[@"Height"] floatValue]); CFRelease(windowList); return frame; } } CFRelease(windowList); return CGRectZero; }
3. 利用AppleScript间接查询
通过执行AppleScript脚本获取Dock的边界信息,再将结果解析为CGRect。本质依赖辅助功能权限,但可在应用内通过NSAppleScript调用,无需额外工具。
示例Swift实现:
import Foundation func getDockFrameViaAppleScript() -> CGRect? { let scriptSource = """ tell application "System Events" return bounds of application process "Dock" end tell """ let appleScript = NSAppleScript(source: scriptSource) var error: NSDictionary? guard let result = appleScript?.executeAndReturnError(&error), let boundsArray = result.arrayValue, boundsArray.count == 4 else { return nil } guard let x1 = boundsArray[0].doubleValue, let y1 = boundsArray[1].doubleValue, let x2 = boundsArray[2].doubleValue, let y2 = boundsArray[3].doubleValue else { return nil } return CGRect(x: x1, y: y1, width: x2 - x1, height: y2 - y1) }
内容的提问来源于stack exchange,提问作者TinyOlap
相关产品推荐
相关产品推荐

