为什么GtkWindow不会触发“绘制”事件?

时间:2012-05-18 14:54:55

标签: gtk vala

我正在尝试使用GTK + 3.x获得透明窗口。 AFAIK下面的代码应该可以工作,但我的窗口永远不会触发“绘制”信号。可能是什么原因?

我的代码:

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;
  }
}

2 个答案:

答案 0 :(得分:1)

您不会将新创建的WallpaperWindow实例分配给变量。 Vala不是垃圾收集的...当一个对象超出范围时,立即未完成,如果你没有将它分配给一个变量,它就会超出构造函数末尾的范围呼叫。您示例中生成的C如下所示:

_tmp0_ = wallpaper_window_new ();
_tmp1_ = _tmp0_;
_g_object_unref0 (_tmp1_);
gtk_main ();

正如您所看到的,在调用gtk_main之前,您的新WallpaperWindow会被取消。如果您将其分配给变量(因此它持续超过gtk_main),您的示例将按预期工作。

答案 1 :(得分:0)

C中的换位按预期工作。

#include <gtk/gtk.h>

static gboolean
on_window_draw(GtkWidget *window, cairo_t *cr)
{
    g_message("Called!\n");

    cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
    cairo_paint(cr);
    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);

    return TRUE;
}

int main(int argc, char *argv[])
{
    GtkWidget *window;
    GdkScreen *screen;
    GdkVisual *visual;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_resize(GTK_WINDOW(window), 200, 200);

    gtk_window_set_decorated(GTK_WINDOW(window), FALSE);

    screen = gtk_window_get_screen(GTK_WINDOW(window));
    visual = gdk_screen_get_rgba_visual(screen);

    if (visual != NULL && gdk_screen_is_composited(screen)) {
        g_message("Composition is enabled, enabling transparency");
        gtk_widget_set_visual(window, visual);
    } else {
        g_message("Composition is not enabled, cannot enable transparency");
    }

    g_signal_connect(window, "draw", G_CALLBACK(on_window_draw), NULL);

    gtk_widget_show_all(GTK_WIDGET(window));

    gtk_main();
    return 0;
}

这就是我得到的:

$ gcc $(pkg-config --cflags --libs gtk+-3.0) a.c
$ ./a.out
** Message: Composition is enabled, enabling transparency
** Message: Called!

** Message: Called!

** Message: Called!

** Message: Called!