使用Accessibility API在Mac OS X上移动其他窗口

第三

我正在尝试使用Accessibility API来更改其他应用程序窗口的位置。我希望做的是从所有应用程序中获取屏幕上的所有窗口,然后将它们全部移动给定的偏移量(比如说5或10)或任何值)。我很难做到这一点,因为这对我来说是Objective-C编程的第一天。

这是我现在正在做的事情。首先,我使用找到窗口及其PID的列表CGWindowListCopyWindowInfo然后,对每个窗口我用AXUIElementCreateApplication得到的AXUIElementRef窗口。之后,我应该将AXUIElementCopyAttributeValue其与属性一起使用(该属性kAXPositionAttribute未能获得正确的位置,始终为零)。最后,我应该将所需的偏移量添加到位置,并AXUIElementSetAttributeValue与属性kAXPositionAttribute和新的位置点一起使用(即使我将绝对值设置为0,0,也会出现运行时错误)。

有人可以帮我做上面介绍的内容,因为我尝试了很多事情却没有运气。另外,它不必完全像我决定在上面实现它一样。如果有更好的方法可以做到这一点,那么我很乐意对其进行更改。

更新:根据注释中的要求,以下是其中一种尝试的代码段:

// 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, kAXPositionAttribute, (CFTypeRef *)&position);
}
gaige

根据您的示例代码(稍作修改,因为您发布的内容将无法编译,并且崩溃后不会被修改),我做了一些实验。

以下是一些警告:

  • 您正在通过PID检索应用程序,但随后将其当作窗口来对其进行操作。那是您问题的核心,但这仅仅是解决方案的开始。
  • 您将需要遍历可访问性应用程序对象的窗口列表,以便找到可随可访问性框架一起移动的可重定位窗口。
  • CGWindowListCopyWindowInfo当询问您的调用方式时,它将返回“屏幕上的所有窗口”,但不能保证这些窗口是“用户窗口”或具有辅助功能的窗口。大多数菜单栏项目都有一个“在屏幕上”的根窗口,并且其中大多数是不可访问的(当您尝试遍历检索到的PID的可访问性树时会显示该窗口)。
  • 您可能会发现AXRole的测试会有所帮助,或者您可能会发现其他窗口可访问性属性对于确定是否移动窗口更为有用。

我在此处包括对您的代码的修改(此修改将在不崩溃的情况下运行),它将从您通过PID检索的应用程序中获取相关的窗口信息,然后移动窗口。我有一个sleep语句,因此我可以停止执行,因为我只是在测试运动的效果:

#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, kAXPositionAttribute, (CFTypeRef *)&position);
        AXValueGetValue(position, kAXValueCGPointType, &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, kAXPositionAttribute, position);
        sleep(5);
    }       
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Move other windows on Mac OS X using Accessibility API

来自分类Dev

使用Accessibility API获取OS X中最前面的窗口的名称

来自分类Dev

在OS X / Mac上使用Windows蓝牙API?

来自分类Dev

在OS X / Mac上使用Windows蓝牙API?

来自分类Dev

SDL创建窗口未在Mac OS X上创建窗口

来自分类Dev

在Mac OS上禁用窗口

来自分类Dev

在Mac OS上禁用窗口

来自分类Dev

如何使用Sip或其他方式以编程方式使Mac OS X ICNS具有10个不同的图像

来自分类Dev

如何在Mac OS X上获得窗口拖放功能?

来自分类Dev

使用BSD sed(或任何其他工具)在OS X上剥离颜色

来自分类Dev

如何使用Homebrew在Mac OS X 10.10.2上安装R?

来自分类Dev

在Mac OS X上使用java命令运行DynamoDB Local

来自分类Dev

在Mac OS X上使用pip安装pyopencv

来自分类Dev

无法在Mac OS X上使用NPM安装Cordova

来自分类Dev

使用Mac OS X上的键盘关闭pyplot图

来自分类Dev

使用sed在Mac OS X上删除回车

来自分类Dev

在Mac OS X 10.9(Mavericks)上使用macports安装opencv

来自分类Dev

在Mac OS X上使用SWIG为JavaScript编译C ++

来自分类Dev

使用Homebrew在Mac OS X上安装libRmath

来自分类Dev

在Mac OS X上使用gstreamer的Pocketsphinx。AudioUnitRender返回-10863

来自分类Dev

PHP在Mac OS X上不使用更新的OpenSSL

来自分类Dev

在Mac OS X上使用Conda安装pyzbar时出错

来自分类Dev

如何在Mac OS X上使用Windows键盘?

来自分类Dev

在Mac OS X上使用cron截屏

来自分类Dev

无法在Mac OS X上使用NPM安装Cordova

来自分类Dev

Mac OS X上的MetaTrader 4与C ++或R结合使用

来自分类Dev

阻止某些程序在Mac OS X 10.10上使用VPN

来自分类Dev

使用sed在Mac OS X上删除回车

来自分类Dev

如何使用XCode在Mac OS X上删除char *数组?

Related 相关文章

热门标签

归档