OSX/Objective C窗口管理:操纵其他应用程序的框架和可见性

Zan*_*aes 3 macos objective-c

我想创建一个能够帮助窗口管理的系统工具/应用程序.我正在尝试找到有关以下主题的文档,如果它们确实可以在OSX的安全沙箱中使用.

  • 显示名称和图标正在运行的应用程序列表,并允许用户选择一个
  • 从我的应用程序操作所述应用程序窗口的框架(例如,调整大小,重新定位)(带有动画 - 虽然我认为一旦我可以执行实际更改,这将是微不足道的)
  • 从任务管理器等隐藏或显示这些应用程序.
  • 能够启动(或终止)给定应用程序的实例

在我看来,Quicksilver完成了许多这些事情,但缺乏AppStore可用性让我想知道是否有可能在保留在OSX沙箱中时这样做.

ian*_*nyh 7

有许多软件可以进行窗口管理.你可以看看我一直在黑客攻击的平铺窗口管理器,叫做Amethyst.像这样的软件背后的基本思想依赖于Accessibility(你可以在这里找到文档).作为一个快速概述,API通过获取对可访问性元素(应用程序,窗口,按钮,文本字段等)的引用来工作,这些元素具有属性(隐藏,位置,大小等),其中一些是可写的.

举个例子,假设您想将每个正在运行的应用程序中的所有窗口移动到屏幕的左上角.该代码可能看起来像

for (NSRunningApplication *runningApplication in [[NSWorkspace sharedWorkspace] runningApplications)] {
    AXUIElementRef applicationRef = AXUIElementCreateApplication([runningApplication processIdentifier]);
    CFArrayRef applicationWindows;
    AXUIElementCopyAttributeValues(applicationRef, kAXWindowsAttribute, 0, 100, &applicationWindows);

    if (!applicationWindows) continue;

    for (CFIndex i = 0; i < CFArrayGetCount(applicationWindows); ++i) {
        AXUIElementRef windowRef = CFArrayGetValueAtIndex(applicationWindows, i);
        CGPoint upperLeft = { .x = 0, .y = 0 };
        AXValueRef positionRef = AXValueCreate(kAXValueCGPointType, &upperLeft);
        AXUIElementSetAttributeValue(windowRef, kAXPositionAttribute, positionRef);
    }
}
Run Code Online (Sandbox Code Playgroud)

其中说明了如何获取对应用程序及其窗口的引用,如何从辅助功能元素复制属性以及如何设置辅助功能元素的属性.

NSWorkspace应用程序的启动和终止中记录了各种通知,并且可访问性框架还具有诸如创建或销毁窗口的应用程序或窗口小型化或半空间化等通知的感觉.

动画窗口更改是非常重要的,我还没有想出如何做到这一点,尽管它可能是可能的.如果没有访问私有API,可能根本不可能.但是你列出的其他事情应该是可能的.例如,隐藏应用程序可以通过设置kAXHiddenAttribute应用程序辅助功能元素来完成.启动应用程序实际上可以通过-[NSWorkspace launchApplication:].

请注意,使用辅助功能需要用户已Enable access for assistive devices打开System Preferences > Accessibility.