g_signal_connect_object doesn't always work unlike g_signal_connect (GtkBuilder)



Hi,

I have a very strange problem, sometimes, g_signal_connect_object stops
working (g_signal_connect is not affected by this problem). I use Vala
but I also checked the C code generated and it seems correct.

I have an application which has a main window, I want to be able to
duplicate this main window to have different views of my program. For
each different view I create a GtkBuilder and from it, I create widgets
I need for the view (a GtkWindow). And I bind the signals from those
widgets to local callbacks.

Now, when I start the application, I create a default view. There the
signals works, and when I click on a widget, the action gets executed.

If I create another view, which itself will create a GtkBuilder, then a
GtkWindow and setup signals. Then I execute gtk_widget_show_all() on
the GtkWindow. But the problem is that the actions bound using
g_signal_connect_object doesn't work at all with this new window. On
the other hand, the signals bound using g_signal_connect works
perfectly.

I checked with gdb, the functions are being called and the callbacks
are not.


The Vala code looks like:



public class MailBrowserView : GLib.Object {

  private Gtk.Builder  builder;
  private Gtk.Window   main_window;
  private bool         closed = false;
  public  MailBrowser  app { get; construct; }
  
  //
  // Constructor and setup
  //
  
  public MailBrowserView(MailBrowser mailbrowser){
    this.app = mailbrowser;
  }
  
  public void setup() throws GLib.Error {
    builder = new Gtk.Builder();
    //Gtk.Action menu_file_new;
    //Gtk.Action menu_file_close;
    //Gtk.Action menu_file_quit;
    //Gtk.Action menu_help_about;
    try {
      builder.add_from_file(app.cfg.file_mail_browser_ui);
    } catch (GLib.Error err) {
      var msg = new Gtk.MessageDialog (
                null, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL,
                "Failed to load UI\n" + err.message);
      msg.run();
      throw err;
    }
        main_window     = (Gtk.Window) builder.get_object("main_window");
    var menu_file_new   = (Gtk.Action) builder.get_object("menu_file_new_view");
    var menu_file_close = (Gtk.Action) builder.get_object("menu_file_close_view");
    var menu_file_quit  = (Gtk.Action) builder.get_object("menu_file_quit");
    var menu_help_about = (Gtk.Action) builder.get_object("menu_help_about");
    main_window.destroy      += this.do_close_view;
    menu_file_new.activate   += this.do_new_view;
    menu_file_close.activate += this.do_close_view;
    menu_file_quit.activate  += Gtk.main_quit;  
    menu_help_about.activate += this.do_about;
    stdout.printf("main_window created: %p (%p)\n", main_window, this);
  }
  
  //
  // Callbacks
  //
  
  private void do_new_view(){
    stdout.printf("new view for window %p\n", main_window);
    MailBrowserView v = new MailBrowserView(app);
    v.start(); // In fact we show an error if there is
  }
  
  private void do_close_view(){
    if(closed) return;
    closed = true;
    stdout.printf("close view for window %p\n", main_window);
    main_window.destroy();
    app.on_closed_view();
  }
  
  private void do_quit(){
    app.quit();
  }
  
  private void do_about(){
    app.show_about_dialog();
  }
  
  //
  // show and start
  //
  
  public void show_all(){
    main_window.show_all();
  }
  
  public void start() throws GLib.Error {
    app.on_new_view();
    setup();
    show_all();
  }

}



The C code looks like:







//
// Routines to create views
//

// (callback called when action on menu File->New View)
static void mail_browser_view_do_new_view (MailBrowserView* self) {
	g_return_if_fail (IS_MAIL_BROWSER_VIEW (self));

	MailBrowserView* v = mail_browser_view_new (self->priv->_app);
	mail_browser_view_start(v, NULL); // See below

	if(v != NULL) g_object_unref (v);
}

void mail_browser_view_start (MailBrowserView* self, GError** error) {
	GError * inner_error = NULL;
	g_return_if_fail (IS_MAIL_BROWSER_VIEW (self));

	...

	mail_browser_view_setup (self, &inner_error); // See below
	if (inner_error != NULL) {
		g_propagate_error (error, inner_error);
		return;
	}

	gtk_widget_show_all (GTK_WIDGET (self->priv->main_window));
}

//
// Setup view
//

void mail_browser_view_setup (MailBrowserView* self, GError** error) {
	...

	// Vala doesn't generate that code but I simplified it so
	// anyone can read it
	if(self->priv->builder != NULL){
		g_object_unref (self->priv->builder);
		self->priv->builder = NULL;
	}
	self->priv->builder = gtk_builder_new ();

	gtk_builder_add_from_file (
		self->priv->builder,
		mail_browser_get_cfg (self->priv->_app)->file_mail_browser_ui,
		&inner_error);
	if (inner_error != NULL) {
		...
	}

	...

	// works
	g_signal_connect (menu_file_quit, "activate",
		((GCallback) (_gtk_main_quit_gtk_action_activate)),
		NULL);

	// doesn't work
	g_signal_connect_object (menu_help_about, "activate",
		((GCallback)
		(_mail_browser_view_do_about_gtk_action_activate)), self, 0);
	...
}

//
// Closures
//

static void _gtk_main_quit_gtk_action_activate (GtkAction* _sender, gpointer self) {
	gtk_main_quit ();
}

static void _mail_browser_view_do_about_gtk_action_activate (GtkAction* _sender, gpointer self) {
	mail_browser_view_do_about (self);
}







What could be the problem?

Thanks.

Mildred

-- 
Mildred Ki'Lya
╭───────── mildred593@online.fr ──────────
│ Jabber, GoogleTalk: <mildred jabber fr>
│ Site: <http://ki.lya.online.fr>              GPG ID: 9A7D 2E2B
│ Fingerprint: 197C A7E6 645B 4299 6D37 684B 6F9D A8D6 9A7D 2E2B


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]