How to get the current workspace programmatically on macOS
Asked Answered
D

3

5

I would like to be able to tell at any time which mission control workspace the user is currently using programmatically on macOS 10.13. I could not find any working answer during my search. Any langage will do, and any workspace identifier works for me (uuid, workspace number...)

Thank you for the help!

Dorinedorion answered 3/11, 2018 at 15:36 Comment(1)
After I posted my "working answer" down below, I created for myself a "Menu Bar Icon" that consists of a simple .sh-script . . . #!/bin/bash _/¯ osascript /Users/myComputerName/.config/bitbar/Workingspace_Desktop.app. . . simply placed in a 3rd party's ("BitBar") plugIns folder which calls an AppleScript that with if BGname is "Sierra.jpg" then set BGname to " [ 1 ] " etc. displays [ 1 ] or [ 2 ] or [ 3 ] or [ 4 ] in my right-side menu bar. If you read so far you will guess that ANY message can thus be displayed permanently …Mcneal
B
8
  • Download the private CGSInternal headers
  • Put them in a folder on your system
  • Go to your Projects Build Settings and add that folder to User Header Search Paths

Then you can do this:


#import "AppDelegate.h"
#import "CGSInternal/CGSSpace.h"

@implementation AppDelegate

typedef int CGSConnection;
extern CGSConnection _CGSDefaultConnection(void);

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    CGSSpaceID activeSpace = CGSGetActiveSpace(_CGSDefaultConnection());
    NSLog(@"activeSpace: %zu", activeSpace);

    CFArrayRef spaceArray = CGSCopySpaces(_CGSDefaultConnection(), kCGSAllSpacesMask);
    NSLog(@"allSpaces: %@", spaceArray);
}

@end
Bea answered 18/11, 2018 at 12:7 Comment(2)
Hi, I've got some extension to this question. my objective is to put the window created by my application on the front. So I create new space using CGSSpaceCreate and want to set it's precedence above all using CGSSpaceSetAbsoluteLevel, but how do I find what input I should put in level ? thanks !Heterochromous
@Heterochromous The CGSSpaces API is probably not the best choice for what you're trying to do. I tried using it to create spaces and I couldn't manage to. I think there is more reverse engineering necessary to uncover all the functions needed to do that. But maybe you can achieve what you're after by calling makeKeyAndOrderFront: or toggleFullscreen: on the NSWindow you created.Olivaolivaceous
M
3

If you want a "working answer" use an indirect GUI "variable" to tell you where you are:

tell application "System Events" to text items 27 thru -1 of item 1 of (picture of every desktop as list) as string (<= shorter but politically in-correct)

set delimOrgs to text item delimiters
set text item delimiters to {"/"}
tell application "System Events" to set BGpict to ¬
     last text item of (picture of current desktop as text)
set text item delimiters to delimOrgs
return BGpict                         [improved: user3439894's suggestion]

… which e.g. returns "Lion.jpg" on one of my 4 workspaces, "Sierra.jpg" on another, which means I was using desktop 3 first and desktop 1 right now.

Mcneal answered 20/11, 2018 at 15:39 Comment(3)
Thanks, that's pragmatic!Dorinedorion
(What reason did ANYone have to vote DOWN this answer that actually helped someone – and was clearly marked as a "working solution" ?!? I DO not understand some "users" here ... "So sad" ;-) .)Mcneal
thank you that solves my use case too, do you think you can convert that to JXA?Ultramundane
D
2

Looks like this requires undocumented API calls.

https://github.com/asmagill/hs._asm.undocumented.spaces/blob/master/CGSSpace.h

and

CG_EXTERN CGSSpaceID CGSGetActiveSpace(CGSConnectionID cid);

may do what you want, but this code hasn't been touched in 3 years so system/api may have migrated, and all the problems with using undocumented APIs apply.

Found this in the project https://github.com/asmagill/hs._asm.undocumented.spaces

haven't used or verified it.

Dna answered 3/11, 2018 at 16:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.