1

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

我的代码:

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

2 回答 2

1

您不会将新创建的 WallpaperWindow 实例分配给变量。Vala 不会被垃圾回收......当一个对象超出范围时,它会立即取消引用,如果你不将它分配给一个变量,它会在构造函数调用结束时超出范围。从您的示例生成的 C 如下所示:

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

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

于 2012-05-19T17:33:06.580 回答
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!
于 2012-05-19T11:04:38.307 回答