在 Swift 中以编程方式在 MacOS 上移动窗口

J. *_*Doe 6 macos swift

我正在尝试以编程方式在桌面上移动窗口。为此我尝试过:

let options = CGWindowListOption(arrayLiteral: .excludeDesktopElements, .optionOnScreenOnly)
    let windowsListInfo = CGWindowListCopyWindowInfo(options, CGWindowID(0))
    let windowsList = windowsListInfo as NSArray? as? [[String: AnyObject]]
    let visibleWindows = windowsList?.filter{ $0["kCGWindowLayer"] as! Int == 0 }

    for window in visibleWindows! {
        let windowTitle = window["kCGWindowOwnerName"] as! String
        let windowNumber = window["kCGWindowNumber"] as! Int32

        if windowNumber == 124 { // Safari
            let nsWindow = NSApp.window(withWindowNumber: Int(windowNumber))
            nsWindow?.cascadeTopLeft(from: NSPoint(x: 100.0, y: 100.0))
            nsWindow?.setFrameTopLeftPoint(NSPoint(x: 100.0, y: 100.0))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试NSWindow使用时windowNumber

NSApp.window(withWindowNumber: Int(windowNumber))
Run Code Online (Sandbox Code Playgroud)

我明白了nil

所以我的问题是,如何通过知道窗口编号以编程方式移动任何窗口?我什至尝试把那个窗户放在前面

let pid = window["kCGWindowOwnerPID"] as? Int32 {
let app = NSRunningApplication(processIdentifier: pid)
app?.activate(options: .activateIgnoringOtherApps)
Run Code Online (Sandbox Code Playgroud)

这样做但没有任何帮助我。有人可以帮我找出如何以编程方式移动 Safari 窗口(例如)吗?

小智 6

这应该可以完成这个技巧:

let owner = entry[kCGWindowOwnerName as String] as! String
var bounds = entry[kCGWindowBounds as String] as? [String: Int]
let pid = entry[kCGWindowOwnerPID as String] as? Int32

if owner == "Safari"
{
    let appRef = AXUIElementCreateApplication(pid!);
    var value: AnyObject?
    let result = AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute as CFString, &value)

    if let windowList = value as? [AXUIElement] {
        print ("windowList #\(windowList)")
        if let window = windowList.first
        {
            var position : CFTypeRef
            var size : CFTypeRef
            var  newPoint = CGPoint(x: 0, y: 0)
            var newSize = CGSize(width: 300, height: 800)

            position = AXValueCreate(AXValueType(rawValue: kAXValueCGPointType)!,&newPoint)!;
            AXUIElementSetAttributeValue(windowList.first!, kAXPositionAttribute as CFString, position);

            size = AXValueCreate(AXValueType(rawValue: kAXValueCGSizeType)!,&newSize)!;
            AXUIElementSetAttributeValue(windowList.first!, kAXSizeAttribute as CFString, size);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我在另一个讨论中找到了这段代码,但目前找不到,对此感到抱歉

哦,您需要此代码来请求辅助功能访问:

let options: NSDictionary = [kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String : true]
let accessEnabled = AXIsProcessTrustedWithOptions(options)

if !accessEnabled {
    print("Access Not Enabled")
}
Run Code Online (Sandbox Code Playgroud)

希望这会有所帮助,即使距离您发布此问题已经过去了一年零五天:)