49

我试图弄清楚如何从任务控制中获取当前空间#。来源会有所帮助,但更有帮助的是有关如何自己解决这个问题的信息。我写了一些applescripts,但似乎任何时候我都需要做一些新的事情(我找不到字典文档)它属于“告诉这个特定的应用程序”的类别(例如“系统事件“)这个非常具体的事情”,我不知道我将如何真正弄清楚这一点。


特别是我想要做的事情:

讨厌OSX 10.7 中的新任务控制。我希望我的空间“网格”回来,因为我一直在使用它。我曾经使用箭头键在空格之间导航(例如ALT+↑</kbd>) every few seconds. Now I'm stuck with this clunky 1x9 array of spaces instead of an elegant 3x3 grid. I've re-mapped all my spaces to use the number pad, which partially takes care of the problem (since it is a 3x3 grid), but only when I have an external keyboard attached.

基本上,我希望能够使用ALT+↑</kbd> and ↓</kbd> again, but to do so I need to detect the current space # so that I can switch from space 5-->2, for example.

戴夫在下面的回答虽然比我预期的要详细得多,但需要编写一个应用程序才能做到这一点(而且它仍然不能完全回答这个问题)。如果可能的话,我宁愿将几个键绑定到一个applescript。

4

8 回答 8

34

我正在尝试自己解决这个问题。还没有,但在正确的方向:

  • 每个任务控制“空间”都有一个uuid分配给它......
  • ...除了第一个(AFAIK)和仪表板。

你可以在这里阅读它们:

$ defaults read com.apple.spaces
$ defaults read com.apple.desktop

文件位置:

~/Library/Preferences/com.apple.spaces.plist
~/Library/Preferences/com.apple.desktop.plist

这是我的。我启用了四个空格,并显示了三个条目:

$ defaults read com.apple.spaces
{
    spaces =     (
                {
            type = 0; 
            uuid = "9F552977-3DB0-43E5-8753-E45AC4C61973";
        },
                {
            type = 0;
            uuid = "44C8072A-7DC9-4E83-94DD-BDEAF333C924";
        },
                {
            type = 0;
            uuid = "6FADBDFE-4CE8-4FC9-B535-40D7CC3C4C58";
        }
    );
}

如果您删除一个空格,该条目将从文件中删除。如果添加空格,则会添加一个条目。同样,Desktop 1 或 Dashboard 从来没有条目。

我不确定是否有公共 API 可以确定uuid显示器上显示的空间。我假设这不是uuid指显示器 1,而其他人的意思是显示器 1+n。

我快速浏览了 AppleScript 编辑器库(窗口 ---> 库),并没有看到系统事件下的任何条目spaces。这可能是 Cocoa 可以通过私有 API 完成的事情,但我不确定 AppleScript。


更新 - 2011 年 7 月 23 日

它看起来像 Dock 控制 Mission Control。你可以像这样获取它的头文件:

  1. 去:/System/Library/CoreServices/Dock
  2. 右键单击并显示包内容
  3. 导航:/Contents/MacOS/
  4. 将二进制文件复制并粘贴Dock到您的桌面。
  5. 跑:$class-dump ~/Desktop/Dock

这将吐出它的所有头文件(它很长;将近 7,500 行)。您可以看到其中spaceUUID出现的字符串。有一个名为的类WVSpace似乎代表任务控制中的单个空间,以及许多其他 WV* 类。

我明天继续看;现在太累了。:)


更新 - 2011 年 7 月 24 日

在 Dock 里面有一个类叫做WVSpaces. 它具有许多属性,包括:

WVSpace *currentSpace;
unsigned int currentWorkspace;
WVSpace *nextSpace;                     // Space on the right???
WVSpace *previousSpace;                 // Space on the left???
BOOL currentSpaceIsDashboard;
BOOL dashboardIsCurrent;
...lots more...

每个WVSpace类都有一个NSString *_uuid;属性,很可能是它的 SpaceUUID。所以理论上你可以像这样得到当前的空间号:

WVSpace *currentSpace = [[WVSpaces sharedInstance] currentSpace];
NSString *currentSpaceUUID = [currentSpace _uuid];     // Empty string if main space???

诀窍是,如何访问WVSpaces隐藏在 Dock 中的私有类?我假设它是单例,因为它有一个NSMutableArray *_spaces;属性,可能每个空格都列在其中。一次只显示一个空间(如果您使用多台显示器,这也是如此;空间跨越它们),因此只有一个WVSpaces实例是有意义的。

所以看起来它需要对 Dock 进行一些SIMBL黑客攻击才能访问WVSpaces.

于 2011-07-21T22:38:05.217 回答
16

我一直在四处寻找,我想出了这个:https ://gist.github.com/1129406

空格具有非顺序 ID 和顺序索引(从 0 开始)。您可以通过两种方式获取 ID:

  • 来自公共 API(参见 参考资料get_space_id
  • 来自私有 CGS APICGSGetWorkspace

您可以使用公共 API 按索引设置当前空间(尽管通知本身没有公开记录):请参阅set_space_by_index

您可以使用私有 CGS API 按 ID 设置当前空间CGSSetWorkspace

无法直接获取当前空间索引。但是,如果您始终使用同一组九个空格,则可以使用 旋转一次set_space_by_index,收集它们的 ID,并构建映射。然后您将能够从 ID 中获取当前索引。

于 2011-08-06T14:59:50.330 回答
8

...也一直在研究这个:)

你说你“需要检测当前空间#”。这并不完全正确:要向下移动一行,您只需向右移动 3 个空格,因此原则上您可以绑定类似

tell application "System Events" to tell process "WindowServer"
    key code {124, 124, 124} using control down
end tell

到 Alt-down(使用FastScriptsAlfred或其他一些避免 Automator 开销的快速方法)。当然,如果您在最后一行中击中,这种方法将失败 - 但如果您真的是硬连线,您永远不会这样做:)
您必须在通用访问首选项窗格中为“启用辅助设备访问”key code工作方式。

警告:这不起作用。当我启动上面的脚本时,我很好地跳了三个空格。问题是之后我的键盘无响应:似乎只有窗口管理器正在接收事件:我可以关闭窗口并切换空间,但我无法与任何应用程序交互。
我的理论是,当跳转导致当前应用程序在脚本执行期间发生变化时,就会发生这种情况——但我不知道如何解决这个问题。

一个相关的观察: ( Mission Controlie /Applications/Mission Control.app/Contents/MacOS/Mission\ Control) 似乎对一些命令行参数有反应:

  • Mission\ Control: 显示任务控制
  • Mission\ Control 1: 显示桌面
  • Mission\ Control 2: 显示当前应用程序窗口

我尝试从 中放入一些 UUID defaults read com.apple.spaces,但这并没有起到太大作用。这么多在黑暗中摸索。

于 2011-08-05T08:33:39.370 回答
5

我写了一个应用程序——它对你有用吗?

改变空间.app

使其工作的关键是控制换档和箭头键,尽管如果您卡在 ALT 上,这可能是可以修复的。

确保在开始之前设置了 9 个空格(桌面),并且您需要将系统偏好设置中的默认 ctrl-up 和 ctrl-down 键绑定更改为其他内容(在键盘 -> 键盘快捷键 -> 任务控制中:任务控制和显示桌面)。

在第一次运行时,它将在您的桌面循环以在您第一次更改空间时枚举它们。

然后您应该能够在 3x3 网格中的桌面之间进行切换。

可能会有一些皱纹,但它基本上是功能性的,至少对我来说是这样。

于 2011-08-30T13:36:41.540 回答
3

http://switchstep.com/ReSpaceApp

这有效,是免费的(现在)并且很棒。

只要确保手动创建与您的布局(在首选项中)期望的一样多的空间。

于 2012-03-22T06:49:02.400 回答
2

我在山狮上,这似乎对我有用。

defaults read com.apple.spaces

寻找“当前空间”。您会注意到,使用不同的活动空间运行此命令不会更改当前空间,但是如果您选中并取消选中“系统偏好设置”中的复选框按钮并再次运行它,您会看到它已更新。

希望这对其他人有帮助!

编辑:这很丑陋,但我正在使用这个:

killall Dock && sleep 0.2 && defaults read com.apple.spaces | grep -A1 "Current Space" | tail -1 | awk '{print $NF }' | cut -f1 -d';'

于 2012-12-07T04:49:38.710 回答
2
on openNewSpace()
    tell application "System Events"
        —start mission control
        do shell script "/Applications/Mission\\ Control.app/Contents/MacOS/Mission\\ Control"
        tell process "Dock"
            set countSpaces to count buttons of list 1 of group 1
            --new space
            click button 1 of group 1
            --switch to new space
            repeat until (count buttons of list 1 of group 1) = (countSpaces + 1)
            end repeat
            click button (countSpaces + 1) of list 1 of group 1
        end tell
    end tell
end openNewSpace
于 2015-03-20T21:23:49.627 回答
0

我在 macOS Catalina 中为自己想出了一个解决方法,尽管我希望这应该适用于多个 macOS 版本。该解决方案解决了我的问题,即:

  1. 无法识别哪个桌面包含哪个项目,因为无法命名桌面。(我通常同时在多个项目上分配时间,每个桌面都专门用于不同的项目[并且它们都使用相同的应用程序])
  2. 无法以编程方式(/轻松)确定我在任何时候都在哪个桌面上
  3. 缺乏工具来跟踪在每个桌面上花费的时间

我在很久以前使用 Stickies.app 解决了第 1 项。我将项目名称放在足够大的字体中,以便在任务控制中的桌面缩略图中很容易辨认,并将便签窗口隐藏在我的 Dock 后面,专门分配给相应项目的桌面。(我还将桌面名称复制为从扩展坞左侧下方伸出的小上标文本,以便我可以识别任务控制之外的当前桌面。)

我刚刚通过applescript解决了第2项。在便签中,我添加了一个很小的、不显眼的字体字符串,将便签标识为桌面名称,例如“dtop”。例如“small_superscripted_name LARGE_NAME tiny_dtop_string”或“project1 PROJECT1 dtop”。请注意,此脚本假定项目名称不包含空格(即只有一个单词)。如果您愿意,可以拆分为不同的字符/字符串。这是运行时生成桌面名称的applescript:

tell application "System Events"
    --obtain the stickie with the desktop name
    set dstr to name of first item of (windows of application process "Stickies" of application "System Events" whose name contains "dtop")

    --Parse the desktop name from the stickie
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to " "
    set dname to first item of (dstr's text items)
    set AppleScript's text item delimiters to astid

    --Show the result in a dialog window
     display dialog "Desktop: " & dname
end tell

就第 3 项而言,我还没有实现它,但我可以通过使用 osascript 调用脚本轻松地通过 cron 作业进行轮询。但是,我可能会探索映射我用来触发脚本的桌面键盘快捷键的可能性,例如,在 control-right/left-arrow 后 1 秒、F3 或 control-up-arrow 后 10 秒后延迟。(它不会捕获触发桌面更改的窗口拖动,但自从我开始使用 2 个显示器以来,它一直没有起作用。)

完成设置后,我可能会将桌面名称和时间戳输出到日志中,以便跟踪在每个桌面上花费的时间。

于 2021-02-03T21:44:04.640 回答