2

我有以下(次要)问题,我想以编程方式解决。每当我从笔记本电脑上拔下辅助显示器时,每个窗口都会移动到现在更小的分辨率下可见。当我重新插入外接显示器时,我需要手动将窗户更换到正确的位置。我每天早上都必须这样做(叹气)。

现在我决定编写一个简单的命令行程序,它可以保存每个打开窗口的位置,并在我想恢复它们的位置时重新定位它们。

通过使用可访问性 API,我已经成功地完成了一些工作,它允许我控制不属于我的进程空间的窗口。但是我有一个问题:程序只能看到我当前空间中的窗口(我在这里谈论的是 OSX Spaces 功能)。

换句话说,当我运行我的程序来保存窗口位置时,它只能保存我当前所在空间中的窗口位置。

关于我的程序的更多细节:

  • 它遍历所有正在运行的进程并获取它们的 PID。
  • 它从这些 PID 创建应用程序元素 ( AXUIElementCreateApplication)
  • 它获取与此应用程序关联的窗口,然后是它们的位置

从应用程序元素获取 windows 元素时,AXUIElementCopyAttributeValues只返回当前空间的窗口。

现在,有没有办法控制任何窗口(跨不同的空间)?如果不是,我不介意以编程方式更改空间来获取每个窗口,但这似乎是不可能的。

任何帮助,将不胜感激!

4

2 回答 2

1

如果您想避免使用私有 API,您可以利用 Mission Control 具有用于移动到各个空间的键盘快捷键这一事实,并且您可以以编程方式发送密钥代码来激活它们。我写了一篇关于它的博客文章(http://ianyh.com/blog/2013/06/05/accessibility/),用于我一直在研究的名为Amethyst的平铺窗口管理器,其中包含一些示例代码,您可以查看在-[AMWindow moveToSpace:].

简短的版本正在移动到一个空间,看起来就像使用默认值ctrl + arrow key移动到相邻的空间:

CGEventRef keyboardDownEvent = CGEventCreateKeyboardEvent(NULL, kVK_RightArrow, true);
CGEventRef keyboardUpEvent = CGEventCreateKeyboardEvent(NULL, kVK_RightArrow, false);

CGEventSetFlags(keyboardDownEvent, kCGEventFlagMaskControl);
CGEventSetFlags(keyboardUpEvent, 0);

CGEventPost(kCGHIDEventTap, keyboardDownEvent);
CGEventPost(kCGHIDEventTap, keyboardUpEvent);

CFRelease(keyboardEvent);
CFRelease(keyboardEventUp);

您可以将其与NSWorkspaceActiveSpaceDidChangeNotification遍历所有空间并收集窗口数据相结合。

此外,作为一个潜在有趣的注意事项,可访问性 API 实际上可以同时为您提供跨所有空间的窗口,但它只会为您提供自启动使用 API 的过程以来您已遍历的空间中的窗口。我不知道为什么会这样,但似乎确实如此。

于 2013-08-19T23:27:43.290 回答
1

我不知道有记录的切换空间的方法。

您可能想要CGSPrivate.h -CGSSetWorkspace等。请记住,这些函数是 SPI,即使在 10.6.x 版本中也可能会在没有警告的情况下中断。

于 2010-04-21T01:13:25.493 回答