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:

When seen live the water effect actually moves, as can be seen here.

This work is not nearly finished, I haven’t even started to think about how do handle input events, but it does look promising.

4 thoughts on “Wobbly widgets”

  1. Now, that’s cool. If I remember correctly, the lack of a to-bitmap-renderer for GTK+ Widgets is the one thing that hinders Gecko from using native GTK+ widgets for HTML forms.

  2. Really nice stuff 🙂 This allows nice transition effects to UI elements … I’ll be waiting for this!

  3. Yeah, we’d love this for Mozilla!!!

    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.

Comments are closed.