【问题标题】:OSX / Objective-C Window Management: manipulate the frames & visibility of other applicationsOSX / Objective-C 窗口管理:操作其他应用程序的框架和可见性
【发布时间】:2013-06-09 14:28:28
【问题描述】:

我想创建一个能够帮助进行窗口管理的系统工具/应用程序。如果考虑到 OSX 的安全沙盒,我正在尝试查找有关以下主题的文档。

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

在我看来,Quicksilver 完成了许多这些事情,但是 AppStore 可用性的缺乏让我想知道是否可以在保留在 OSX 沙箱中的同时做到这一点。

【问题讨论】:

    标签: objective-c macos


    【解决方案1】:

    有很多软件可以进行窗口管理。您可以查看我一直在破解的名为 Amethyst 的平铺窗口管理器。此类软件背后的基本思想依赖于可访问性(您可以找到 here 的文档)。作为快速概览,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);
        }
    }
    

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

    NSWorkspace 中记录了各种通知,用于启动和终止应用程序,辅助功能框架还具有通知意义,例如应用程序创建或销毁窗口,或窗口小型化或小型化。

    对窗口的更改进行动画处理并非易事,我还没有弄清楚如何做到这一点,尽管它可能是可能的。如果不使用私有 API,可能根本不可能。但是您列出的其他事情应该是可能的。例如,可以通过在应用程序可访问性元素上设置kAXHiddenAttribute 来隐藏应用程序。启动应用程序实际上可以通过-[NSWorkspace launchApplication:] 完成。

    请注意,使用辅助功能需要用户在System Preferences &gt; Accessibility 中打开Enable access for assistive devices

    【讨论】:

    • 为了隐藏,最好使用-[NSRunningApplication hide]
    • 这个答案中的代码至少包含2个错误:第一行的“)”之前应该有一个“]”,并且应该在开始第二行之前确保applicationWindows不为空循环。
    • @mollerhoj 修复了您提到的错误。感谢您指出。 @KenThomases 这实际上是一个有趣的观点。 NSRunningApplication 实现了可访问性行为的一小部分,并使用 Objective-c 接口实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2020-08-02
    相关资源
    最近更新 更多