Change Space grows up


At the end of August I posted about Change, which seeks to replace the sorely missed 2D grid spaces feature that was in Snow Leopard for those unlucky enough to be using OSX Lion.

Now it’s two and a half months and over 50 commits later, and I have just released version 2.2.0. I think the app is getting pretty usable.

The last post I mentioned how I was using MacRuby to write the app, and indeed this was a pretty quick and easy way to get it off the ground.

But there are a couple of issues with MacRuby. Firstly, you need to set your Xcode up to include the MacRuby framework and runtime in the .app file otherwise users will have to install it themselves. And the runtime adds about 10Mb to your app size.

Secondly, when integrating with other libraries and certain calls to the Cocoa libraries and other APIs you find yourself having to write bridge code where the structures you are dealing with do not map easily to ruby objects.

Given these issues, I decided to rewrite the app completely in Objective C.

By mid October I had the App running nicely in the new language, and it was coming in at about half a meg as opposed to just under ten.

Some great libraries helped with the features I needed. Shortcutrecorder provided an ability to change the global hotkeys.

Change Space also displays the current desktop number in the status bar at the top of your screen.

At this time, rather than fade the desktop number out as I had been doing previously, the number was shown in the status bar permanently by polling the system for which desktop was active each second. I was to find a better way to do this though – it turns out that there is a notification for desktop change, so I can just subscribe to that and remove the polling altogether.

NSNotificationCenter *notCenter;    notCenter = [[NSWorkspace sharedWorkspace] notificationCenter];    [notCenter addObserver:self               selector:@selector(workspaceObserver:)               name:NSWorkspaceActiveSpaceDidChangeNotification object:nil];

I also wanted to add central screen notifications of the direction of movement between your spaces, and which you went from and to.

I started off with a simple arrow, but it would be far nicer to see an entire grid of the right dimensions. Step in Harry Groover, who provided code for a very nice looking grid. I added the arrow, and we had a really great looking result.


Next up I wanted the desktops to move in the right direction.

The importan APIs are defined like this:

extern OSStatus CGSNewTransition(const CGSConnection cid,   const CGSTransitionSpec* spec, int *pTransitionHandle);        extern OSStatus CGSInvokeTransition(const CGSConnection cid,   int transitionHandle, float duration);

The reverse engineering has already been done for us by previous apps such as DesktopManager, so the enum documentation can be found.

Not everything seems to work in Lion, but we have enough to work with. Calling CGSNewTransition will freeze the existing desktop, and wait for a transition to be invoked.

CGSInvokeTransition will perform the specified transition.

Unfortunately I do not have (as yet) a way to disable the standard left or right lion transitions, so when I want the desktop to move up or down I need to wait for the left or right transition to happen between creating the new transition and invoking it. Experimentation tells me that 0.3s is a long enough wait for that.

So the vertical transitions have a slight delay before they activate, but I think it’s worth it to preserve illusion of a grid.

For those who can’t stand the extra wait, I added a preference option to allow these transitions to be turned off.

So now, I think Change has come of age.

There are still a few problems to iron out, in particular the space 1 issue (I must use the AppleScript bridge to navigate to it, which is slower and is affected by which modifier keys you are holding down).

I hope to have this problem licked soon though.

Download Change v2.2.0 here.


20 thoughts on “Change Space grows up

  1. Oh man you are a life saver! I hated what Apple did to Spaces in Lion. I loved the number in the menu bar, and being about to move up and down in a grid.So finding this app is awesome! Thanks!

  2. Hi Steve,I find your application ‘Change Space’ great I’ve been looking for something like it ever since Lion was released!Thought I would let you know I have found a fix for the Desktop 1 issue by turning off the default OS ctrl arrow key change space commands, setting your app to use ctrl arrow keys for every direction up down left and rightRe enabling the default OS arrow keys.This works beautifully and the only downside is your space layout diagram only appears when moving up or down as the OS takes priority moving left and right.Hope this is somewhat helpful!Cheers,Steve (I’m Steve too)

  3. Yep, that’s a pretty good workaround. I’ve been working on a more complete solution, but it requires some more research before I have anything working (so it’ll take a while).

  4. <html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Yes, but it involves code injection. Wait until the next version of Change Space.<div><br><div><div></div></div></div></body></html>

  5. (which is in response to this, which came by email by didn’t appear in the comments for some reason)HippoMan just commented on the post "Change Space grows up" on PennysmallsVery good job with Change Space!I am trying to write a similar utility that uses a status menu for space changes. I have a functioning prototype, but to switch to the first space, it requires that a hotkey be mapped for switching to that space, and then it has to send an event to simulate this hotkey press. For spaces 2 through N, I don’t have to simulate a hotkey, and this works:// the ‘space’ variable contains the one-based space number.// this only works for space > 1CFNotificationCenterRef nCenter = CFNotificationCenterGetDistributedCenter();CFStringRef spaceNumString = CFStringCreateWithFormat(NULL, nil, CFSTR("%d"), space – 1);CFNotificationCenterPostNotification(nCenter, CFSTR(""), spaceNumString, NULL, TRUE);My question is this: do you know of any way in Lion to switch to the first space without sending an event that simulates a hotkey press?Thanks in advance.

  6. Thank you for your reply! I’m looking forward to seeing how this code-injection will work!For some reason, every time I try to post a message here, PennySmalls says that it is probably spam and I have to log in. But I _did_ register and _did_ successfully log in, and nonetheless, I keep being told I must do so. So you might get this response via email, also, until I figure out what’s wrong with my PennySmalls registration.

  7. A related question: does anyone know how to get the private function CGSSetWorkspace() to work under Lion? When I call it as follows, it causes my screen to blank out and turn grey, no matter what values I put into the ‘space’ space = [whatever];CGSSetWorkspace(_CGSDefaultConnection(), space);So this routine clearly is doing _something_, and I’m guessing that the grey screen might be due to the fact that the ‘space’ variable is somehow out of range for Lion; i.e., maybe its values under Lion are no longer 1, 2, 3, etc., but some other values … ???Anyway, has anyone been able to get CGSSetWorkspace to work under Lion?

  8. I figured out that the ‘space’ variable passed to CGSSetWorkspace has to be the integer ID value for the given space which is returned from CGSGetWorkspace. However, even if I use these ID’s, CGSSetWorkspace doesn’t seem to function properly. After calling it with any of these space ID’s, the right side of the menu bar blanks out and no space switching takes place.So I still don’t know how to get CGSSetWorkspace to work under Lion.

  9. Tks for the app, you’ve saved me a loot of struggling time with mission control.What about FullScreen Apps? Will be possible to include them as one space so we can cycle into them to ?Tks.

  10. I just donated, thank you for your work on this so far. With this, and the ability to "expose" all windows in either leopard or SnowLeopard fashion, iLion will finally be "useable" ;-).PS. there is a codebase of a developer that coded a virtual desktop solution for osx 10.3, the SVN source is HERE: The dev’s website is here:'m not sure if it will be usable, or helpful in any way, but wanted to send you the link, just in case it could help you out in some form.Thank you again, I check the github page often, hoping for new updates 🙂

  11. Are there any screenshots or videos of this? I can’t figure out exactly what it’s supposed to do. I downloaded it and still I’ve no clue what it’s supposed to do really. I don’t see any changes.

  12. Have you used GDB to see if there are more preferences to re-discover in Lion that can re-enable better functionality in Change Space?, would you consider creating an desktop/spaces grid overlay on the main monitor(only) that can be triggered with a keystroke, and also contain (mini)previews of the windows in each desktop, like dockview & hyperdock perform by pull from the system’s cached images of the openwindows(and grabbing and sorting them by the desktop "numbers" they are "on")?

  13. I donated to your ChangeSpace project, and am VERY glad to see you moving ahead in the development of this solution. Cant wait to test out ReSpaceApp

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s