OSX Lion AppleScript:如何从任务控制获取当前空间#?
我试图弄清楚如何从任务控制中心获取当前的空间#。来源会有所帮助,但更有用的是有关如何自己解决这个问题的信息。我写了一些苹果脚本,但通常情况下,每当我需要做一些新的事情(我找不到字典文档)时,它都属于“告诉这个特定应用程序”的类别(例如“系统”)事件”)这个非常具体的事情”,我不知道如何真正弄清楚这一点。
具体来说,我想做的是:
我讨厌 OSX 10.7 中的新任务控制。我希望我的空间“网格”回来,因为我一直使用它。我曾经每隔几秒钟使用箭头键(例如 ALT+↑)在空格之间导航。现在我只能使用这个笨重的 1x9 空间数组,而不是优雅的 3x3 网格。我已经重新映射了所有空间以使用数字键盘,这部分解决了问题(因为它是 3x3 网格),但仅限于连接了外部键盘时。
基本上,我希望能够再次使用 ALT+↑ 和 ↓,但要做到这一点,我需要检测当前空间 # 所以例如,我可以从空间 5-->2 切换。
戴夫下面的答案虽然比我预期的要详细得多,但需要编写一个应用程序来执行此操作(而且它仍然没有完全回答问题)。如果可能的话,我宁愿将几个键绑定到苹果脚本。
I'm trying to figure out how to get the current space # from mission control. Source would be helpful, but more helpful would be info on how to figure this out myself. I've written a few applescripts, but more often than not it seems like any time I need to do something new (that I can't find dictionary documentation for) it falls under the category of "tell this specific app (e.g. "System Events") this very specific thing" and I've no clue how I would actually figure that out.
Specifically what I am trying to do:
I hate the new mission control in OSX 10.7. I want my spaces "grid" back since I used it all the time. I used to navigate between spaces using arrow keys (e.g. ALT+↑) 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.
Basically, I want to be able to use ALT+↑ and ↓ again, but to do so I need to detect the current space # so that I can switch from space 5-->2, for example.
Dave's answer below, although far more detailed than I expected, requires writing an app to do this (plus it still doesn't fully answer the question). If it's at all possible, I'd rather just bind a few keys to an applescript.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
我正在尝试自己解决这个问题。还没有,但方向正确:
uuid
...您可以在这里阅读它们:
文件位置:
这是我的。我启用了四个空格,并显示了三个条目:
如果删除空格,该条目将从文件中删除。如果添加空格,则会添加一个条目。同样,从来没有桌面 1 或仪表板的条目。
我不确定是否有公共 API 来确定显示器上显示的空间
uuid
。我假设没有uuid
意味着 Display 1,而其他则意味着 Display 1+n。我快速浏览了一下 AppleScript 编辑器库(窗口 ---> 库),并没有在“系统事件”下看到任何
spaces
条目。这可能可以通过 Cocoa 来完成,也许可以通过私有 API,但我不确定 AppleScript 是否可以。更新 - 2011 年 7 月 23 日
看起来 Dock 控制着 Mission Control。您可以像这样获取其头文件:
/System/Library/CoreServices/Dock
/Contents/MacOS /
Dock
二进制文件复制并粘贴到桌面。这将吐出所有头文件(很长;几乎 7,500 行)。您可以看到其中出现
spaceUUID
字符串。有一个名为WVSpace
的类,它似乎代表任务控制中的单个空间,以及许多其他 WV* 类。明天我会继续看;现在太累了。 :)
更新 - 2011 年 7 月 24 日
Dock 内部有一个名为
WVSpaces
的类。它具有许多属性,包括:每个
WVSpace
类都有一个NSString *_uuid;
属性,该属性可能是其 SpaceUUID。所以理论上你可以像这样获取当前的空间编号:技巧是,如何访问隐藏在 Dock 内的私有
WVSpaces
类?我假设它是 Singleton,因为它有一个 NSMutableArray *_spaces; 属性,可能其中列出了每个空格。一次仅显示一个空间(如果您使用多个显示器,则这一点成立;空间跨越两个显示器),因此只有一个WVSpaces
实例是有意义的。因此,看起来需要对 Dock 进行一些 SIMBL 黑客攻击才能访问
WVSpaces
。I'm trying to figure this out myself. Not there yet, but in the right direction:
uuid
assigned to it...You can read them here:
File locations:
Here's mine. I have four spaces enabled, and three entries show up:
If you delete a space, that entry will get removed from the file. If you add a space, an entry will be added. Again, there's never an entry for Desktop 1 or Dashboard.
I'm not sure if there's a public API to figure out what space
uuid
is being displayed on a display. I'd assume that nouuid
means Display 1, and the others' mean Display 1+n.I took a quick glance through the AppleScript Editor Library (Window ---> Library) and didn't see any entries under System Events for
spaces
. This is probably something that can be done with Cocoa, perhaps via private API, but I'm not sure about AppleScript.UPDATE - July 23, 2011
It looks like Dock controls Mission Control. You can grab its header files like so:
/System/Library/CoreServices/Dock
/Contents/MacOS/
Dock
binary to your desktop.$class-dump ~/Desktop/Dock
That'll spit out all of its header files (it's long; almost 7,500 lines). You can see the
spaceUUID
strings appearing in there. There's a class calledWVSpace
which appears to represent a single Space in Mission Control, and a lot of other WV* classes.I'll keep looking at it tomorrow; too tired now. :)
UPDATE - July 24, 2011
Inside Dock there's a class called
WVSpaces
. It has a number of attributes including:Each
WVSpace
class has anNSString *_uuid;
attribute, which is likely its SpaceUUID. So theoretically you can get the current space number like so:The trick is, how to get access to the private
WVSpaces
class buried inside of Dock? I'm assuming it's Singleton as it has anNSMutableArray *_spaces;
attribute, probably with every space listed in it. Only one space gets displayed at a time (this holds true if you're using multiple monitors; the space spans across both of them), so it makes sense to only have oneWVSpaces
instance.So it looks like it'll require some SIMBL hacking of Dock to gain access to
WVSpaces
.我一直在摸索,我想出了这个: https://gist.github.com/1129406
空间有一个非顺序 ID 和顺序索引(从 0 开始)。您可以通过两种方式获取 ID:
get_space_id
)CGSGetWorkspace
您可以使用公共 API 通过索引设置当前空间(尽管通知本身未公开记录):请参阅
set_space_by_index
您可以使用私有 CGS API
CGSSetWorkspace
按 ID 设置当前空间。您无法直接获取当前空间索引。但是,如果您始终使用同一组九个空间,则可以使用
set_space_by_index
轮换一次,收集它们的 ID 并构建映射。然后你就可以从ID中获取当前索引。I've been poking around, and I came up with this: https://gist.github.com/1129406
Spaces have a nonsequential ID and a sequential index (0-based). You can get the ID in two ways:
get_space_id
)CGSGetWorkspace
You can set the current space by index using public APIs (though the notifications themselves are not publicly documented): see
set_space_by_index
You can set the current space by ID using private the CGS API
CGSSetWorkspace
.You cannot get the current space index directly. However, if you're always using the same set of nine spaces, you can rotate through them once using
set_space_by_index
, collect their IDs, and build a mapping. Then you will be able to get the current index from the ID....也一直在研究这个:)
你说你“需要检测当前空间#”。这并不完全正确:要向下移动一行,您只需向右移动 3 个空格,因此原则上您可以将类似
Alt-down 的内容绑定到(使用 FastScripts,Alfred 或其他一些避免 Automator 开销的快速方法)。当然,如果你击中了底行,这种方法就会失败——但如果你真的是硬连线,你永远不会这样做:)
您必须在“通用访问”首选项窗格中“启用对辅助设备的访问”才能使
键代码
方法发挥作用。警告:这不起作用。当我启动上面的脚本时,我很好地跳了三个空格。问题是,之后我的键盘没有响应:似乎只有窗口管理器正在接收事件:我可以关闭窗口并切换空间,但无法与任何应用程序交互。
我的理论是,当跳转导致当前应用程序在脚本执行期间发生更改时,就会发生这种情况 - 但我不知道如何解决这个问题。
相关观察:
Mission Control
(即/Applications/Mission Control.app/Contents/MacOS/Mission\ Control
)似乎对一些命令行参数:Mission\ Control
:显示任务控制Mission\ Control 1
:显示桌面Mission\ Control 2
:显示当前应用程序窗口I尝试放入一些UUID 来自
默认读取 com.apple.spaces
,但这并没有多大作用。在黑暗中摸索就这么多了。... also been working on this :)
You say that you "need to to detect the current space #". This is not strictly true: To move down one row, you just move 3 spaces right, so in principle you could just bind something like
to Alt-down (with FastScripts, Alfred or some other fast method that avoids the overhead of Automator). This approach will fail if you ever hit down in the bottom row, of course -- but if you are truly hard-wired, you never do :)
You have to "Enable access for assistive devices" in the Universal Access preference pane for the
key code
approach to work.Caveat: This doesn't work. When I launch the script above, I nicely jump three spaces. The problem is that afterwards my keyboard goes unresponsive: It seems that only the window manager is receiving events: I can close windows and switch space, but I cannot interact with any applications.
My theory is that this happens when the jump causes the current application to change during the execution of the script -- but I have no idea how to fix this.
A related observation: The
Mission Control
(i.e./Applications/Mission Control.app/Contents/MacOS/Mission\ Control
) seems to react to some command line arguments:Mission\ Control
: show mission controlMission\ Control 1
: show desktopMission\ Control 2
: show current application windowsI tried putting in some of the UUID's from
defaults read com.apple.spaces
, but that didn't do much. So much for fumbling in the dark.我写了一个应用程序 - 它对你有用吗?
Change Space.app
使其工作的按键是 Control-Shift 和箭头键,尽管这如果您卡在 ALT 上,可能可以修复。
确保在开始之前设置了 9 个空格(桌面),并且需要将系统偏好设置中默认的 ctrl-up 和 ctrl-down 键绑定更改为其他内容(在键盘 -> 键盘快捷键 -> 中)任务控制:任务控制和显示桌面)。
第一次运行时,它会在您第一次更改空间时循环遍历您的桌面以枚举它们。
然后您应该能够像在 3x3 网格中一样在桌面之间进行更改。
可能会有一些皱纹,但它基本上是功能性的,至少对我来说是这样。
I wrote an app - does it work for you?
Change Space.app
The keys to make it work are control-shift and the arrow keys, although this may be fixable if you are stuck on ALT.
Make sure you have 9 spaces (desktops) set up before you start, and you'll need to change the default ctrl-up and ctrl-down key bindings in System Preferences to something else (in Keyboard -> Keyboard Shortcuts -> Mission Control : Mission Control and Show Desktop).
On the first run it it will cycle through your desktops to enumerate them when you first change space.
Then you should be able to change between desktops like in a 3x3 grid.
There may be a few wrinkles, but it's basically functional, at least for me.
http://switchstep.com/ReSpaceApp
这有效,免费(现在)并且很棒。
只需确保手动创建与您的布局(在首选项中)期望的空间一样多的空间。
http://switchstep.com/ReSpaceApp
This works, is free (right now) and is awesome.
Just be sure to manually create as many spaces as your layout (in preferences) is expecting.
我在 Mountain Lion,这似乎对我有用。
默认读取 com.apple.spaces
查找“当前空间”。您会注意到,使用不同的活动空间运行此命令不会更改当前空间,但如果您选中和取消选中“系统偏好设置”中的复选框按钮并再次运行它,您将看到它已更新。
希望这对其他人有帮助!
编辑:它很难看,但我正在使用这个:
Killall 码头&&睡眠 0.2 &&默认读取 com.apple.spaces | grep -A1“当前空间”|尾部-1 | awk '{print $NF }' |切-f1-d';'
I'm on Mountain Lion and this seems to work for me.
defaults read com.apple.spaces
Look for "Current Space". You'll notice that running this command with different active spaces doesn't change the current space BUT if you check and uncheck a checkbox button in "System Preferences" and run it again, you'll see it updated.
Hopefully this helps someone else!
EDIT: It's ugly, but I'm using this:
killall Dock && sleep 0.2 && defaults read com.apple.spaces | grep -A1 "Current Space" | tail -1 | awk '{print $NF }' | cut -f1 -d';'
我在 macOS Catalina 中为自己想出了一个解决方法,不过我预计这应该适用于多个 macOS 版本。该解决方案解决了我的问题,即:
我很久以前就使用 Stickies.app 解决了第 1 项。我将项目名称设置为足够大的字体,以便在 Mission Control 的桌面缩略图中轻松辨认,并将粘性窗口隐藏在 Dock 后面,专门分配给相应项目的桌面。 (我还用从扩展坞左侧下方伸出的小上标文本复制了桌面名称,以便我可以识别任务控制之外的当前桌面。)
我刚刚通过 applescript 解决了第 2 项。在便签中,我添加了一个微小的、不显眼的字体字符串,将便签标识为桌面名称,例如“dtop”。例如“small_superscripted_name LARGE_NAME tiny_dtop_string”或“project1 PROJECT1 dtop”。请注意,此脚本假定项目名称不包含空格(即只有一个单词)。如果您愿意,您可以拆分不同的字符/字符串。这是运行时生成桌面名称的 applescript:
就第 3 项而言,我还没有实现它,但我可以通过使用 osascript 调用脚本来轻松地通过 cron 作业进行轮询。不过,我可能会探索映射用于触发脚本的桌面键盘快捷键的可能性,例如,在按 Ctrl-右/左箭头后 1 秒、在 F3 或 Ctrl-上箭头后 10 秒等延迟之后。 (它不会捕获触发桌面更改的窗口拖动,但自从我开始使用 2 个显示器以来,这无论如何都不起作用。)
一旦我完成了设置,我可能会将桌面名称和时间戳输出到日志中这样我就可以跟踪在每个桌面上花费的时间。
更新:我确实最终通过在 cron 作业中每分钟运行一次的 Applescript 解决了第 3 项。我还编写了一个 Perl 脚本来生成两者的条形图:在一段时间内(例如过去一周)在每个项目(即桌面)上花费了多少时间,以及每天的图显示我在什么上花费了多少时间每天都有项目。这是一个示例:
I have come up with a workaround for this for myself in macOS Catalina, though I expect this should work for multiple macOS versions. This solution solves my problems, namely:
I solved item 1 quite some time back using Stickies.app. I put the project name in a huge enough font that it's easily legible in the desktop thumbnails in Mission Control and I hide the stickie window behind my Dock, assigned specifically to the corresponding project's desktop. (I also duplicate the desktop name in small superscripted text that pokes out from under the left side of the dock so that I can identify the current desktop outside of mission control.)
I just solved item 2 via applescript just now. In the stickie, I add a tiny, unobtrustive font string that identifies the stickie as the desktop name, e.g. 'dtop'. E.g. "small_superscripted_name LARGE_NAME tiny_dtop_string" or "project1 PROJECT1 dtop". Note, this script assumes that the project name contains no spaces (i.e. it's just one word). You can split on a different charcter/string, if you wish. Here is the applescript that, when run, results in the desktop name:
And as far as item 3 goes, I have yet to implement it, but I could easily poll via a cron job by calling the script using osascript. However, I may explore the possibility of mapping the desktop keyboard shortcuts I use to trigger the script, say, after a delay like 1 second after a control-right/left-arrow, 10 seconds after F3 or control-up-arrow. (It wouldn't catch window-drags that trigger desktop changes, but that hasn't worked anyway since I started using 2 monitors.)
Once I have that set up, I'll likely output the desktop name and a timestamp to a log so I can track time spent on each desktop.
UPDATE: I did eventually solve item 3 with an Applescript run once a minute in a cron job. I also wrote a perl script to generate a bar plot of both: how much time spent on each project (i.e. desktop) over a period of time (e.g. the past week), and a per day plot showing how much time I spent on what projects each day. Here's an example:
为了回答 OP 中如何获取空间编号的实际问题(而不是解决如何显示和支持 3x3 空间网格的问题)并忽略使用 Lion 的限制:
我一直在使用名为 WhichSpace 的 Gihub 实用程序莫哈韦和卡塔琳娜。没有任何报告表明我看到它在以后的版本中也不起作用,所以我认为它可以。 https://github.com/gechr/WhichSpace
运行时,它会在上部工具栏。无论哪种进程导致桌面工作区发生变化,它都能很好地可靠地更新该数字。它似乎也不关心 16 个桌面的伪限制。我目前有 45 台台式机。当数量超过 99 时,图标大小可能无法获得可接受的结果,我没有测试过。
我使用 AppleScript 访问该号码。
我从 Keyboard Maestro 论坛获得了 WhichSpace 实用程序的提示和 AppleScript 片段。 https://forum.keyboardmaestro.com/t/macros-desktop-spaces-macros-for-navigation-and-window-management-v1-1-superseded/21507/11
我希望这有帮助。
To answer the actual question in the OP of how to get the space number (rather than address the issue of how to display and support a 3x3 grid of Spaces) and ignoring the limitation of using Lion:
I have been using a Gihub utility called WhichSpace on Mojave and Catalina. There have been no reports that I've seen of it not working on later versions as well, so I presume it does. https://github.com/gechr/WhichSpace
When running, it places a small numerical icon in the upper toolbar. It does a good job of updating that number reliably, no matter what kind of process causes the change of Desktop Workspace. It also does not seem to care about the psuedo-limit of 16 Desktops. I currently have 45 Desktops. The icon size might not allow acceptable results when the number is over 99, I have not tested it.
I access the number using AppleScript.
I got the tip to the WhichSpace utility and the AppleScript snippet from the Keyboard Maestro Forum. https://forum.keyboardmaestro.com/t/macros-desktop-spaces-macros-for-navigation-and-window-management-v1-1-superseded/21507/11
I hope this helps.
好的,这是截至 2024 年索诺玛的更新:
Ok, here's an update as of 2024 and Sonoma:
不建议在索诺玛上使用最新的答案,因为我注意到 plist 文件几乎总是过时的,并且不会对实时更改做出反应。
输出是用户友好的,并且对空格进行“1 索引”,而不是输出您在 p-list 文件中看到的一些令人困惑的 UUID/数字值(无论如何您都不能依赖它)
我构建了一个 Rust 板条箱来连接使用本机 mac os API 来处理此问题:
https://github.com/Schachte/space-monitor-rs
即席
订阅空间更改
The most recent answer is not recommended on Sonoma as I noticed the plist file is almost always out of date and doesn't react to real-time changes.
The output is user-friendly and "1-indexes" the spaces instead of outputting some confusing UUID/numeric value you'd see in the p-list files (which you can't rely on anyways)
I built a Rust crate that interfaces with the native mac os APIs to handle this:
https://github.com/Schachte/space-monitor-rs
Adhoc
Subscribe to space changes