CGSPrivate is a super cool header which allows Mac developers to use nice animations on their apps. There are many animations, but the most popular one is the cube. On the Mac OS X, when you switch the user usingthe fast user switching, the desktop rotates and the other user’s desktop appears. You can use that and many other animations on an ordinary NSWindow with a few lines of code.
CGSPrivate uses private APIs, which means it can stop working anytime as Apple may update Mac OS X and remove the support for the animations with no prior notice. Mostly likely it’s not going to happen any time soon, as CGSPrivate has been here for a couple years(the first version of CGSPrivate was wrote back in 2003, I believe). It also can’t be used on apps you pretend to sell on the Mac App Store. Apple doesn’t like apps that use private APIs.
To get started, click here to download CGSPrivate.h. Once you have downloaded it, add it to your Xcode project and import the header file. There’s no need to add other frameworks to the project.
For this example, we will create a simple app with a NSPopUpButton that allows you to select the animation and 2 views. The back view will have a back button. On the project header file add the following IBOutlets:
IBOutlet NSView *mainView;
IBOutlet NSView *backView;
IBOutlet NSPopUpButton *transition;
Now add the following IBActions:
Connect the IBActions and the IBOutlets to the interface elements. First, let’s code the getTransition method:
int i = [transition indexOfSelectedItem];
if(i == 0)
if(i == 1)
if(i == 2)
if(i == 3)
if(i == 4)
if(i == 5)
if(i == 6)
if(i == 7)
This method basically checks which transition the user selected on the NSPopUpButton. The method may be different depending on the order the items in your drop down menu are. There are 9 different transitions available. Note that I didn’t use else if. I didn’t use it because once the method returns, the conditional structure gets stopped. I would not write more code for nothing.
Now let’s write the method that performs the transition. First of all, declare the following variables:
Now, let’s assign the transition handle:
handle = -1;
Now we need to create the specifications. I don’t know what’s this item for, but let’s set it to 0:
spec.unknown1 = 0;
Let’s pick a direction. In this case, the transition goes to the left. That’s why I’m using CGSLeft. To go to the right, use CGSRight. (1 << 7) makes the background transparent. If you don’t set this, the screen will get black by default. If you don’t want a transparent background, remove the (1 << 7). You can also set the background to colors.
spec.option = CGSLeft | (1 << 7);
Now let’s set the transition type:
spec.type = [self getTransition];
The next line sets the background color. It means nothing to us because we’ve set the background to transparent. And yes, it’s backColour, in British English.
spec.backColour = 0;
The following line sets which window you want the transition to be performed:
spec.wid = [window windowNumber];
Now that we’ve created the transition specification, let’s create a connection.
CGSConnection con = _CGSDefaultConnection();
This line creates the transition:
Let’s change the window’s content view.
Let’s redraw the window content. If you don’t do that, the window content will be redrawn once the transition finishes.
Now we want to invoke the transition. The last argument is the duration of it. I’ve set it to 2 seconds.
CGSInvokeTransition(con, handle, 2);
We don’t want the transition to be released before it gets finished, right? So we need to pause the thread execution for 2 seconds.
Finally, we can release the transition.
Great! We’ve created and performed the transition. Now write the same code for the back button, but change its direction to right.
CGSPrivate uses Carbon, and best of all: it works on 64bit. It’s one of the parts of the Carbon framework that works on 64bit. You can download the sample app by clicking here.