Cocoa / GNUstep miniwindows

The default behaviour when you minimise a window on Mac OS X is to display a miniaturised version of the window's view in the Dock. This is a good technique for video players, where the information in the window is still comprehensible in the tiny version. However, it doesn't work so well for most other apps, where the window becomes illegible and the miniaturised view is useless. The icons here are miniaturised from iTunes (say hello to MMini-MMalc) and Mail.

The problem of what to display in a miniaturised view has been around for much longer than Cocoa has. Indeed, even in the original OpenStep specification published by NeXT, minimised windows were converted into Miniwindows which the application could choose how to display. This technique was implemented in OPENSTEP as well as OpenStep for Solaris and OpenStep Enterprise, and is used in GNUstep too. It's available in Cocoa but seldom used. Here, I'll change the Miniwindow for the TypingTutor application, from Aaron Hillegass' book Cocoa Programming for Mac OS X. The default Miniwindow is shown at the top of this paragraph. As you can see, it's not really possible to see what's going on.

N.B. If you're on a version of Mac OS X from the developer previews to Jaguar inclusive, you need to enable Miniwindows by setting the default AppleDockIconEnabled to YES. On all other versions of Mac OS X, Rhapsody, GNUstep and OpenStep, Miniwindows are automatically activated. The methods described here are available in even the earliest implementations of OpenStep, from which Cocoa is derived.

The only part of the TypingTutor main window which shows information is the BigLetterView on the right, so we'll make that the Miniwindow. Firstly, in AppController.h create an outlet for the main window:

	IBOutlet NSWindow *mainWindow;

Now open MainMenu.nib and drag AppController.h onto it, to register this new outlet. Control-drag from the AppController instance to the window, and connect the window to the mainWindow outlet. Save and close Interface Builder, and edit the -showAnotherLetter method in AppController.m. Here, we get the view to generate an image of itself, and use that image as the contents of the Miniwindow. Note that it's also possible to change the title of the Miniwindow with NSWindow's -setMiniwindowTitle: (NSString *)newTitle; method. Only the new code is shown below.

- (void)showAnotherLetter
{
	NSImage *miniImage;
	NSData *miniImageEPSData;
	miniImageEPSData = [outLetterView dataWithEPSInsideRect: [outLetterView bounds]];
	miniImage = [[[NSImage alloc] initWithData: miniImageEPSData] autorelease];
	[mainWindow setMiniwindowImage: miniImage];
}

Build and run the application again, then miniaturise the main window. The miniaturised view now looks like the image to the left; not necessarily very pretty but it is definitely easier to see what's going on in the tiny view. As a bonus, when you port your application to GNUstep you'll automatically get good miniaturised views on all other Operating Systems ;-).