So just to kick off my posts I thought I’d drop a little super-awesome Cocoa/CoreGraphics code to apply a Core Image filter to, or underneath, a window. This is similar to what Apple themselves use in Mac OS X v10.5 “Leopard” to create a blur under menus, etc.
Believe it or not, this is a private API on the desktop, so you ought to test and make sure it all works on your target OS before using it in a project!

Firstly, you’ll need to define some things:
extern OSStatus CGSNewConnection(const void **attributes, CGSConnection * id);
Then you’ll need to use the following code to create a filter and apply it to a window. For this example, I use a blur placed beneath a window’s contents (similar to menus, or Glass in Vista). The code in awakeFromNib could be placed inside your App Delegate or somewhere similar. The filter is a standard Core Image CIFilter class as explained in the Core Image documentation. Not all filters work, but I leave that to you to experiment!
NB: For a window to accept a filter, the window needs to be at least 10% opaque (same as for receiving touch events). That means you have to make sure your window has a background colour and is not [NSColor clearColor].
{
NSWindow *w = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 256, 256) styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO];
[w setBackgroundColor:[NSColor colorWithDeviceWhite:1.0 alpha:0.2]];
[w setOpaque:NO];
[self enableBlurForWindow:w];
[w makeKeyAndOrderFront:nil];
}
-(void)enableBlurForWindow:(NSWindow *)window
{
CGSConnection thisConnection;
NSUInteger compositingFilter;
/*
Compositing Types
Under the window = 1 << 0
Over the window = 1 << 1
On the window = 1 << 2
*/
NSInteger compositingType = 1 << 0; // Under the window
/* Make a new connection to CoreGraphics */
CGSNewConnection(NULL, &thisConnection);
/* Create a CoreImage filter and set it up */
CGSNewCIFilterByName(thisConnection, (CFStringRef)@"CIGaussianBlur", &compositingFilter);
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:3.0] forKey:@"inputRadius"];
CGSSetCIFilterValuesFromDictionary(thisConnection, compositingFilter, (CFDictionaryRef)options);
/* Now apply the filter to the window */
CGSAddWindowFilter(thisConnection, [window windowNumber], compositingFilter, compositingType);
}









9 Responses
Could someone upload a working version?
I swear, either I’m being incredibly thick (which is highly likely after a 4 hours Stats and Calc test) or somethings wrong with it
Confirmed working by another reader earlier; sorry!
Great tutorial! One thing that should probably be mentioned is: The NSWindow _must_ be visible when the filter is being applied to it, for this code to work.
So very cool! So cool I had to play around with it
Recorded a video: http://vimeo.com/4508431
Nevermind, found my problem
Nice tute, just wasted the last 20 minutes playing with other CI filters
Shouldn’t that be “an NSWindow”?
LOL. Sometimes, I start to wonder if I missed the memo that “an” has been deleted from the english language.
BTW, I forgot to mention: FREAKING AWESOME EFFECT!!!!
works just fine with clearColor background on the window as long as the window has some content in it