Почему GtkWindow не запускает событие рисования?

Я пытаюсь получить прозрачное окно с GTK+ 3.x. Насколько я знаю, следующий код должен работать, но мое окно никогда не запускает сигнал «рисовать». Что может быть причиной?

Мой код:

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

person mspanc    schedule 18.05.2012    source источник


Ответы (2)


Вы не назначаете вновь созданный экземпляр WallpaperWindow переменной. Vala не собирает мусор... когда объект выходит за пределы области видимости, он немедленно не ссылается, и если вы не присваиваете его переменной, он выходит из области видимости в конце конструктора вызов. Сгенерированный C из вашего примера выглядит так:

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

Как вы можете видеть, ваш новый WallpaperWindow получает ссылку до вызова gtk_main. Если вы присвоите его переменной (так что он длится после gtk_main), ваш пример будет работать так, как вы ожидаете.

person nemequ    schedule 19.05.2012

Транспозиция в 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!
person ntd    schedule 19.05.2012