OSX Lion AppleScript:如何从任务控制获取当前空间#?

发布于 2024-11-25 02:29:27 字数 597 浏览 6 评论 0原文

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


具体来说,我想做的是:

讨厌 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

司马昭之心 2024-12-02 02:29:27

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

  • 每个任务控制“空间”都会分配一个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";
        }
    );
}

如果删除空格,该条目将从文件中删除。如果添加空格,则会添加一个条目。同样,从来没有桌面 1 或仪表板的条目。

我不确定是否有公共 API 来确定显示器上显示的空间 uuid。我假设没有 uuid 意味着 Display 1,而其他则意味着 Display 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???

技巧是,如何访问隐藏在 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:

  • Each Mission Control "space" gets a uuid assigned to it...
  • ...except for the very first one (AFAIK), and the Dashboard one.

You can read them here:

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

File locations:

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

Here's mine. I have four spaces enabled, and three entries show up:

$ 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";
        }
    );
}

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 no uuid 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:

  1. Go to: /System/Library/CoreServices/Dock
  2. Right-Click and Show Package Contents
  3. Navigate: /Contents/MacOS/
  4. Copy and paste the Dock binary to your desktop.
  5. Run: $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 called WVSpace 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:

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

Each WVSpace class has an NSString *_uuid; attribute, which is likely its SpaceUUID. So theoretically you can get the current space number like so:

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

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 an NSMutableArray *_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 one WVSpaces instance.

So it looks like it'll require some SIMBL hacking of Dock to gain access to WVSpaces.

留一抹残留的笑 2024-12-02 02:29:27

我一直在摸索,我想出了这个: https://gist.github.com/1129406

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

  • 从公共 API(请参阅 get_space_id
  • 从私有 CGS API 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:

  • from public APIs (see get_space_id)
  • from the private CGS API 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.

站稳脚跟 2024-12-02 02:29:27

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

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

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

Alt-down 的内容绑定到(使用 FastScriptsAlfred 或其他一些避免 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

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

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 control
  • Mission\ Control 1: show desktop
  • Mission\ Control 2: show current application windows

I 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.

彻夜缠绵 2024-12-02 02:29:27

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

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.

悲喜皆因你 2024-12-02 02:29:27

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.

世态炎凉 2024-12-02 02:29:27

我在 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';'

表情可笑 2024-12-02 02:29:27
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
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
ゝ偶尔ゞ 2024-12-02 02:29:27

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

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

我很久以前就使用 Stickies.app 解决了第 1 项。我将项目名称设置为足够大的字体,以便在 Mission Control 的桌面缩略图中轻松辨认,并将粘性窗口隐藏在 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 作业进行轮询。不过,我可能会探索映射用于触发脚本的桌面键盘快捷键的可能性,例如,在按 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:

  1. The inability to identify which desktop contains which project, because desktops cannot be named. (I usually am splitting time on work on multiple projects at once and each desktop is dedicated to work on a different project [and they all use the same apps])
  2. The inability to programmatically(/easily) determine which desktop I'm on at any one time
  3. The lack of tools to track time spent on each desktop

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:

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

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:

enter image description here
enter image description here

多情癖 2024-12-02 02:29:27

为了回答 OP 中如何获取空间编号的实际问题(而不是解决如何显示和支持 3x3 空间网格的问题)并忽略使用 Lion 的限制:

我一直在使用名为 WhichSpace 的 Gihub 实用程序莫哈韦和卡塔琳娜。没有任何报告表明我看到它在以后的版本中也不起作用,所以我认为它可以。 https://github.com/gechr/WhichSpace

运行时,它会在上部工具栏。无论哪种进程导致桌面工作区发生变化,它都能很好地可靠地更新该数字。它似乎也不关心 16 个桌面的伪限制。我目前有 45 台台式机。当数量超过 99 时,图标大小可能无法获得可接受的结果,我没有测试过。

我使用 AppleScript 访问该号码。

tell application ¬
    "System Events" to tell process ¬
    "WhichSpace" to set temp to (title of menu bar items of menu bar 1)
return item 1 of temp

我从 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.

tell application ¬
    "System Events" to tell process ¬
    "WhichSpace" to set temp to (title of menu bar items of menu bar 1)
return item 1 of temp

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-12-02 02:29:27

好的,这是截至 2024 年索诺玛的更新:

#!/bin/bash

# Read the output of the defaults command
output=$(defaults read com.apple.spaces)
current_space_id=$(echo "$output" | awk '/"Current Space"/,/\}/' | grep 'ManagedSpaceID' | awk '{print $3}' | tr -d ';')
space_list=$(echo "$output" | awk '/Spaces =/,/\);/')
managed_space_ids=$(echo "$space_list" | awk '/ManagedSpaceID/')
# Find and print the line containing the current_space_id
line_number=$(echo "$managed_space_ids" | awk -v id="$current_space_id" '
BEGIN { RS=";"; FS="\n"; ORS=""; }
{
    if ($0 ~ "ManagedSpaceID = " id) {
        print NR;
    }
}')

echo "$line_number"

Ok, here's an update as of 2024 and Sonoma:

#!/bin/bash

# Read the output of the defaults command
output=$(defaults read com.apple.spaces)
current_space_id=$(echo "$output" | awk '/"Current Space"/,/\}/' | grep 'ManagedSpaceID' | awk '{print $3}' | tr -d ';')
space_list=$(echo "$output" | awk '/Spaces =/,/\);/')
managed_space_ids=$(echo "$space_list" | awk '/ManagedSpaceID/')
# Find and print the line containing the current_space_id
line_number=$(echo "$managed_space_ids" | awk -v id="$current_space_id" '
BEGIN { RS=";"; FS="\n"; ORS=""; }
{
    if ($0 ~ "ManagedSpaceID = " id) {
        print NR;
    }
}')

echo "$line_number"
迟月 2024-12-02 02:29:27

不建议在索诺玛上使用最新的答案,因为我注意到 plist 文件几乎总是过时的,并且不会对实时更改做出反应。

输出是用户友好的,并且对空格进行“1 索引”,而不是输出您在 p-list 文件中看到的一些令人困惑的 UUID/数字值(无论如何您都不能依赖它)

我构建了一个 Rust 板条箱来连接使用本机 mac os API 来处理此问题:

https://github.com/Schachte/space-monitor-rs

即席

use macos_space_monitor::SpaceMonitor;

fn main() {
    let space = SpaceMonitor::get_current_space_number();
    println!("Current space: {}", space);
}

订阅空间更改

use std::thread;

use macos_space_monitor::{MonitorEvent, SpaceMonitor};

fn main() {
    let (monitor, rx) = SpaceMonitor::new();
    let _monitoring_thread = thread::spawn(move || {
        while let Ok(event) = rx.recv() {
            match event {
                MonitorEvent::SpaceChange(space) => {
                    println!("Space change detected! Active space is: {}", space);
                }
            }
        }
    });

    monitor.start_listening();
}

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

use macos_space_monitor::SpaceMonitor;

fn main() {
    let space = SpaceMonitor::get_current_space_number();
    println!("Current space: {}", space);
}

Subscribe to space changes

use std::thread;

use macos_space_monitor::{MonitorEvent, SpaceMonitor};

fn main() {
    let (monitor, rx) = SpaceMonitor::new();
    let _monitoring_thread = thread::spawn(move || {
        while let Ok(event) = rx.recv() {
            match event {
                MonitorEvent::SpaceChange(space) => {
                    println!("Space change detected! Active space is: {}", space);
                }
            }
        }
    });

    monitor.start_listening();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文