I am trying to get a transparent window with GTK+ 3.x. AFAIK the following code should work, but my window never fires the "draw" signal. What could be the reason?
My code:
using Gtk;
public class WallpaperWindow : Object {
private Window window;
public static int main (string[] args) {
Gtk.init (ref args);
new WallpaperWindow();
Gtk.main();
return 0;
}
public WallpaperWindow() {
// Initialize window
this.window = new Window();
this.window.resize(200, 200);
this.window.set_decorated(false);
this.window.set_border_width(8);
// Enable transparency
var screen = this.window.get_screen();
var visual = screen.get_rgba_visual();
if(visual != null && screen.is_composited()) {
message("Composition is enabled, enabling transparency");
this.window.set_visual(visual);
} else {
warning("Composition is not enabled, cannot enable transparency");
}
this.window.draw.connect(on_window_draw);
// Run!
this.window.show_all();
}
// NEVER CALLED
private bool on_window_draw(Cairo.Context cr) {
warning("on_window_draw");
cr.set_source_rgba(0.0, 0.0, 0.0, 0.0);
cr.set_operator(Cairo.Operator.SOURCE);
cr.paint();
cr.set_operator(Cairo.Operator.OVER);
return true;
}
}
You don't assign the newly created WallpaperWindow instance to a variable. Vala isn't garbage collected... when an object goes out of scope it is immediately unrefed, and if you don't assign it to a variable it goes out of scope at the end of the constructor call. The generated C from your example looks like this:
_tmp0_ = wallpaper_window_new ();
_tmp1_ = _tmp0_;
_g_object_unref0 (_tmp1_);
gtk_main ();
As you can see, your new WallpaperWindow gets unrefed before gtk_main is called. If you assign it to a variable (so it lasts past gtk_main
) your example works as you expect.