加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

objective-c – 使用Accessibility API在Mac OS X上移动其他窗口

发布时间:2020-12-16 06:00:31 所属栏目:百科 来源:网络整理
导读:我正在尝试使用Accessibility API来更改其他应用程序的窗口.我想要做的是从屏幕上获取所有窗口的所有应用程序,然后将它们全部移动给定的偏移量(可以说5或10或任何值).我在这方面遇到困难,因为这是Objective-C为我编程的第一天. 这是我现在在做什么首先,我使
我正在尝试使用Accessibility API来更改其他应用程序的窗口.我想要做的是从屏幕上获取所有窗口的所有应用程序,然后将它们全部移动给定的偏移量(可以说5或10或任何值).我在这方面遇到困难,因为这是Objective-C为我编程的第一天.

这是我现在在做什么首先,我使用CGWindowListCopyWindowInfo找到窗口及其PID的列表.然后,对于每个窗口,我使用AXUIElementCreateApplication获取窗口的AXUIElementRef.之后,我应该使用AXUIElementCopyAttributeValue与属性kAXPositionAttribute(我没有得到正确的位置,总是得到零).最后,我应该将所需的偏移量添加到位置,并使用属性kAXPositionAttribute和新的位置点(即使我设置了绝对值,如0,0),我得到运行时错误的AXUIElementSetAttributeValue).

有人可以用我上面描述的代码片段来帮助我,因为我尝试了许多事情,没有任何运气.此外,它不应该像我决定在上面实现的那样完全正确.如果有更好的方法去做,那么我会很乐意改变它.

更新:
根据评论的要求,以下是一个尝试的代码段:

// Get all the windows
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly,kCGNullWindowID);
NSArray* arr = CFBridgingRelease(windowList);
// Loop through the windows
for (NSMutableDictionary* entry in arr)
{
    // Get window PID
    pid_t pid = [[entry objectForKey:(id)kCGWindowOwnerPID] intValue];
    // Get AXUIElement using PID
    AXUIElementRef elementRef = AXUIElementCreateApplication(pid);
    CFTypeRef position;
    CGPoint point;
    // Get the position attribute of the window (maybe something is wrong?)
    AXUIElementCopyAttributeValue(elementRef,kAXPositionAttribute,(CFTypeRef *)&position);
    AXValueGetValue(position,kAXValueCGPointType,&point);
    // Debugging (always zeros?)
    NSLog(@"point=%@",point);
    // Create a point
    NSPoint newPoint;
    newPoint.x = 0;
    newPoint.y = 0;
    position = (CFTypeRef)(AXValueCreate(kAXValueCGPointType,(const void *)&newPoint));
    // Set the position attribute of the window (runtime error over here)
    AXUIElementSetAttributeValue(elementRef,(CFTypeRef *)&position);
}

解决方法

根据您的示例代码(稍微修改,因为您发布的内容不会编译,并且将不会修改),我做了一些实验.

这里有几个注意事项:

>您正在通过PID检索应用程序,然后作为窗口执行.这是您问题的核心,但它只是解决方案的开始.
>您将需要走出可访问性应用程序对象的窗口列表,以便找到可以使用辅助功能框架移动的可重定位窗口.
> CGWindowListCopyWindowInfo将在询问您的方式时返回“全屏幕”窗口,但不能保证这些窗口是“用户窗口”或具有可访问性的窗口.大多数菜单栏项目都有一个根窗口,它是“屏幕上的”,大多数菜单栏是不可访问的(当您尝试走出您检索的PID的辅助功能树时显示).
>您可能会发现AXRole的测试是有帮助的,或者您可能会发现其他窗口辅助功能属性在确定是否移动窗口方面更有用.

我已经在这里修改了你的代码(这将运行而不会崩溃),这将从您通过PID检索的应用程序获取相关的窗口信息,然后移动窗口.我有一个睡眠声明,所以我可以停止执行,因为我只是测试运动的效果:

#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import <ApplicationServices/ApplicationServices.h>

int main(int argc,char *argv[]) {
    @autoreleasepool {
    // Get all the windows
    CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly,kCGNullWindowID);
    NSArray* arr = CFBridgingRelease(windowList);
    // Loop through the windows
    for (NSMutableDictionary* entry in arr)
    {
        // Get window PID
        pid_t pid = [[entry objectForKey:(id)kCGWindowOwnerPID] intValue];
        // Get AXUIElement using PID
        AXUIElementRef appRef = AXUIElementCreateApplication(pid);
        NSLog(@"Ref = %@",appRef);

        // Get the windows
        CFArrayRef windowList;
        AXUIElementCopyAttributeValue(appRef,kAXWindowsAttribute,(CFTypeRef *)&windowList);
        NSLog(@"WindowList = %@",windowList);
        if ((!windowList) || CFArrayGetCount(windowList)<1)
            continue;


        // get just the first window for now
        AXUIElementRef windowRef = (AXUIElementRef) CFArrayGetValueAtIndex( windowList,0);
        CFTypeRef role;
        AXUIElementCopyAttributeValue(windowRef,kAXRoleAttribute,(CFTypeRef *)&role);         
        CFTypeRef position;
        CGPoint point;

        // Get the position attribute of the window (maybe something is wrong?)
        AXUIElementCopyAttributeValue(windowRef,(CFTypeRef *)&position);
        AXValueGetValue(position,&point);
        // Debugging (always zeros?)
        NSLog(@"point=%f,%f",point.x,point.y);
        // Create a point
        CGPoint newPoint;
        newPoint.x = 0;
        newPoint.y = 0;
        NSLog(@"Create");
        position = (CFTypeRef)(AXValueCreate(kAXValueCGPointType,(const void *)&newPoint));
        // Set the position attribute of the window (runtime error over here)
        NSLog(@"SetAttribute");
        AXUIElementSetAttributeValue(windowRef,position);
        sleep(5);
    }       
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读