A shaped input example with gtk+, cairo and XShape 1.1

Do you want fully dynamic vector-based graphics alongside with a non-trival shape for masking out input-events for your application-window? Then this is it! I’ve done this for my cairo-clock release 0.3.1 due “real soon now ™”. The example I extracted from this work on the cairo-clock uses one - and only one - single function to draw the user-visible graphics and the input-shape mask. Thus you get ultra-precise arbitrary shaped window-borders that match the visible graphics up to the pixel, because all the drawing is done with cairo. How’s that ladies and gentlemen?! *g* Of course everything is finely anti-aliased, no jagged frame-borders or anything like that. Here’s the example program at work:




To have it look like this you need some compositing-manager running (tested with xcompmgr and compiz) and a recent version of gtk+ (tested with gtk+-2.8.11 and gtk+ from CVS-head). You can try it yourself by grabbing the source here. Take a look at the source for further information. Use at your own risk! Placed under the GPL. Share and enjoy!

10 Responses to “A shaped input example with gtk+, cairo and XShape 1.1”

  1. Mike’s Journal » Blog Archive » more bling Says:

    [...] He has also done it far better than I did, with even a spiffy video to go with the code. That said, the code to set input area along with the drawing is quite complicated, so hopefully GTK+ will soon be supporting all this natively so we don’t have to write the boilerplate screen/cm handling code over and over (as pointed out by desrt in the comments, I got this slightly wrong). [...]

  2. malted method Says:

    Your AVI demo looks very smooth. Just curious, what graphics card/processor and amount of RAM were you using when you took it?

  3. MacSlow Says:

    @malted: This was recorded on an AMD 1.6 GHz with a GeForceFX 5900 using gvidcap.

  4. James Su Says:

    I tried this program, it\’s amazing. However I found an issue: if the image opacity is less than 0.5, then the mask will be zero, then the program won\’t receive any mouse event. Is there any way to fix it to make the area with non zero opacity clickable?

  5. chandra shekhar sengupta Says:

    I was trying this code to add transparency to a widget. In this code i have added a drawing area as a child of pWindow and drawn the shape in drawing area. But the drawing area was having black background. Could anyone tell me how to make that drawing area transparent.

  6. Pedro Lopes Says:

    This sample is very nice. One problem I found is that it doesnt gracefully degrade in the case of having no compositing manager - you get an ugly black square as background. Fortunately this is very easy to fix using the old style shaped window api. Add these 2 lines in update_input_shape (after the endif):

    gtk_widget_shape_combine_mask (pWindow, NULL, 0, 0);
    gtk_widget_shape_combine_mask (pWindow, pShapeBitmap, 0, 0);

    This way it still looks reasonably good even if there is no compositing manager running.

  7. Viet Says:

    Hi!

    Thank you for sharing. Really great stuff! May I know if the same is possible on Windows with GTK+ & Cairo and without Cygwin (the code you wrote can run on Linux & Mac only). Please kindly advise.

    Thank you,
    Viet.

  8. MacSlow Says:

    @ Viet: I don’t know if any X11-server for Windows supports XShape 1.1+, but you best bet on Windows will be the xming X11-server.

  9. BoAC Says:

    What about drop shadows for this kind of windows?

  10. MacSlow Says:

    @ BoAC: You can add them too. But you have to do that yourself, in application-code, because the window-managers decorations are switched off. For example in cairo-clock I do that via the theme SVGs. In composite-aware gksu, in current Ubuntu 8.10, I’ve done it in-application. In the long run to do these an related kinds of visual elements, we should do "client drawn decorations". That means the toolkit will have to provide the rendering of decorations and _not_ the window-manager. This move makes a lot of sense and will enable us to do a lot UI-elements we currently cannot do at all or achieve in an easy manner.

Leave a Reply