Wobbly widgets

Recently I’ve been researching a bit into requirements and usecases for a new canvas for Gnome/Gtk+. One of the important features of a canvas is the ability to embedd normal Gtk+ widgets into the canvas and have them integrate nicely. This means the embedded widgets should properly stack with other canvas items, and (less importantly) they should support arbitrary transformations.

The problem with this is that widgets in Gtk+ use child X windows, for clipping/scrolling and to get events. These windows are managed by X and won’t correctly mix with the drawing of the other items in the canvas. This can be seen in the widget item in gnome-canvas, which just doesn’t work very well.

An obvious solution to this is to render the whole widget to an offscreen pixmap and then just copy that translated to the canvas when rendering the canvas item. However, currently there isn’t a way to render Gtk+ widgets to a pixmap. There are some hacks you can use, but they don’t work at all for widgets that have child windows.

This week I’ve been working on a change to Gdk that will allow it to take any GdkWindow and make it (and its children) into an offscreen pixmap, much like the Composite Extension but client-side. Once we have this you can do all sorts of effects with widgets, just like Composite allows effects on a larger scale.

Yesterday I managed to get it to render an actual widget tree for the first time, so I hacked up a simple demo to show off the sort of things you can do with this:

One thing I have to ask: what happens if you render into an RGBA surface? We need to get back proper alpha values (e.g. 255 if the widget painted an opaque pixel, 0 if it didn’t paint the pixel, something in between if it painted something translucent). Currently we have some terrible hacks to get this.