WindowWarp
By Erling Ellingsen on May 26, 2006Update 7/26: Someone used the screenshot below to make some fake screenshots of OSX Leopard.
I thought I might post this while there are still a number of OSX developers running around the blog. There is a nice undocumented window manager call, CGSSetWindowWarp, which lets you twist and bend windows. I played around with a few years ago, but never got around to using it for anything.
![]()
![]()
The warped windows are fully functional, with the exception that mouse input is not remapped. Still some work to do there.
Some suggestions for things to do with it:
- 3D Exposé replacement: "rotate" the screen, so can you can see windows from the side and pick one out
- Fish-eye window manager: keep full-sized windows in the center of the screen; shrink and warp when they reach the edge
- Rotational virtual desktops: something similar to the FrontRow menu, where the windows would be on the outside of a cylinder. You could zoom out slightly, then spin the cylinder to get to the windws you want.
- Wobbly windows: pretend that the windows are only pinned to the desktop at the top, and use the motion sensor and some simple physics to wobble the windows.
If you do something cool, please post a link here!
Full-size screenshots after the fold.
Full size screenshots:

Two browsers and a terminal.

As you can see, the windows can overlap themselves, though only in one direction.
Comments
Any chance of you posting the source for these examples?
I'm sorry. I had a little test program that let you manually fold windows, but you had to use a debugger to get it running, then type in the window ID, then fiddle. For all I know, it might not even work with 10.4.
This was a bit of a selfish post. I know cool things could be done with this API, so I justed wanted to make sure as many developers as possible know about it. The code referenced in the first comment shows the API call; there's no documentation I know of.
I've been thinking about the desktop switching idea for VirtueDesktops for a while now - I think you've given me the call to do some of it. Any chance you have that sample code lying around? The mesh stuff is new to me, and I could use some working code to learn off of.
Here's what I did:
// get the connection ID for *this* application
CGSConnectionID conn = (CGSConnectionID) _CGSDefaultConnection();
// give that connection universal access - this only works if the Dock is not running
// for serious use, you'll need to inject the code into Dock, of course
CGSSetUniversalOwner(conn, 0);
// this is a grid of {windowX, windowY, screenX, screenY} coordinates - fill this with whatever you want
float grid[USIZE * VSIZE][4];
// this will warp the window
CGSSetWindowWarp(conn, windowId, USIZE, VSIZE, grid);
To see how it is used, move Dock.app away (so it doesn't relaunch), kill the dock, then run the (now renamed) dock under gdb. Set a breakpoint on CGSSetWindowWarp, then try minimizing an application, so the Genie effect kicks in. The Dock will run CGSSetWindowWarp on the window to be minimized, and you can see what parameters are used.
Here's the numbers from my system. The width of the grid is 2, so the only control points are on the left and right sides of the window:
(gdb) x/100f $r7 0xf007f130: 0 0 1818.29419 447.108521 0xf007f140: 1150 0 2707.63965 447.108521 0xf007f150: 0 19.3788147 1795.12415 466.487335 0xf007f160: 1150 19.3788147 2652.46533 466.487335 0xf007f170: 0 38.7575989 1771.10889 485.866119 0xf007f180: 1150 38.7575989 2595.27832 485.866119 0xf007f190: 0 58.1364136 1746.35498 505.244934 0xf007f1a0: 1150 58.1364136 2536.33252 505.244934 0xf007f1b0: 0 77.5151978 1720.97229 524.623718 0xf007f1c0: 1150 77.5151978 2475.88916 524.623718 0xf007f1d0: 0 116.272827 1668.77283 563.381348 0xf007f1e0: 1150 116.272827 2351.58789 563.381348 0xf007f1f0: 0 155.030457 1615.43555 602.138977 0xf007f200: 1150 155.030457 2224.57715 602.138977 0xf007f210: 0 193.788086 1561.90564 640.896606 0xf007f220: 1150 193.788086 2097.10742 640.896606 0xf007f230: 0 232.545654 1509.13159 679.654175 0xf007f240: 1150 232.545654 1971.43799 679.654175 0xf007f250: 0 251.9245 1483.32129 699.03302 0xf007f260: 1150 251.9245 1909.97656 699.03302
In this case, the window was 1150 pixels wide, had its top left corner (0,0) mapped to (1818,447), and was pretty badly warped.
It helps to have another computer handy so you can SSH in and restart processes if your system locks up; applications will occasionally try to notify the dock of something, and if the dock is stopped by gdb, that application will hang until gdb releases the dock. If "that application" happens to be the terminal you're using to talk to gdb, you're kinda screwed.
Did anything concrete come out of this? Latest VirtueDesktop perhaps?
No, nothing yet - I would like to do something with this, but I want VirtueDesktops to be stable before I add features like this.
Could you possibly post a revised Dock using your Window Warp, or a link to something? I'm not too good at compiling and stuff, so I don't want to mess anything up, but I'd really like to try it out.
Hey Erling, That is in deed very cool! I'm just wondering whether someone can confirm that it is still supported in 10.4? As Jason I have no real exprience in compiling etc. but I'm willing to dive into. So before things get messy it'll be cool to know whether it's me or 10.4 not supporting this feature any longer. Cool! Hannes
I can't provide any real docs; this gives the method signature for SetWindowWarp, at the very least:
http://paste.lisp.org/display/2717
There's a partial header file for the private CGS functions in the DesktopManager distribution.