public
Last active

Two ways of messing with spaces

  • Download Gist
spaceutil.c
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
#include <unistd.h>
#include <CoreServices/CoreServices.h>
#include <ApplicationServices/ApplicationServices.h>
 
typedef int CGSConnection;
extern OSStatus CGSGetWorkspace(const CGSConnection cid, int *workspace);
extern OSStatus CGSSetWorkspace(const CGSConnection cid, int workspace);
extern CGSConnection _CGSDefaultConnection(void);
 
int get_space_id(void);
void set_space_by_index(int space);
 
int get_space_id(void)
{
int space;
CFArrayRef windows = CGWindowListCopyWindowInfo( kCGWindowListOptionOnScreenOnly, kCGNullWindowID );
CFIndex i, n;
for (i = 0, n = CFArrayGetCount(windows); i < n; i++) {
CFDictionaryRef windict = CFArrayGetValueAtIndex(windows, i);
CFNumberRef spacenum = CFDictionaryGetValue(windict, kCGWindowWorkspace);
if (spacenum) {
CFNumberGetValue(spacenum, kCFNumberIntType, &space);
return space;
}
}
return -1;
}
 
void set_space_by_index(int space)
{
CFNotificationCenterRef nc = CFNotificationCenterGetDistributedCenter();
CFStringRef numstr = CFStringCreateWithFormat(NULL, nil, CFSTR("%d"), space);
CFNotificationCenterPostNotification(nc, CFSTR("com.apple.switchSpaces"), numstr, NULL, TRUE);
}
 
int main (int argc, char * const argv[])
{
int useCGS = 0, ch, space;
while ((ch = getopt(argc, argv, "-c")) != -1) {
switch (ch) {
case 'c':
useCGS = 1;
break;
}
}
argc -= optind;
argv += optind;
if (argc > 0) {
space = atoi(argv[0]);
if (useCGS) CGSSetWorkspace(_CGSDefaultConnection(), space);
else set_space_by_index(space);
} else {
if (useCGS) CGSGetWorkspace(_CGSDefaultConnection(), &space);
else space = get_space_id();
printf("%d\n", space);
}
return 0;
}

Hey, thanks for this work. I am using the Slate window manager, and working with the javascript api it exposes. I am on Lion. This makes an acceptable bridge to overcome the fact that Slate can't handle spaces. My usecases revolve around being able to customize desktops/spaces for configuration and recognizing which space is current, as to Slate this is the global context. Not ideal, but cool with your work..

I understand this approach will not work with Mountain Lion/Mavericks from comments on StackOverflow, http://stackoverflow.com/questions/6768684/osx-lion-applescript-how-to-get-current-space-from-mission-control. This is not yet my problem, but is too bad if that is true. Anyway, thanks for publishing this.

Have a good one,
Dave

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.