After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 538901 - Calling base method from overridden signal handler causes endless loop
Calling base method from overridden signal handler causes endless loop
Status: RESOLVED FIXED
Product: vala
Classification: Core
Component: Code Generator
0.3.x
Other All
: Normal normal
: ---
Assigned To: Jürg Billeter
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2008-06-18 07:49 UTC by Frederik Zipp
Modified: 2008-11-20 20:56 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Frederik Zipp 2008-06-18 07:49:16 UTC
using GLib;
using Gtk;

public class ExposeTest : Button {

	construct {
		this.label = "ExposeTest";
	}

	public override bool expose_event (Gdk.EventExpose event) {
		debug ("expose_event");
		return base.expose_event (event);	// endless loop
	}

	static int main (string[] args) {
		Gtk.init (ref args);
		var win = new Window (WindowType.TOPLEVEL);
		win.add (new ExposeTest ());
		win.destroy += Gtk.main_quit;
		win.show_all ();
		Gtk.main ();
		return 0;
	}
}

It seems that a new signal gets emitted instead of only calling the base method.
Comment 1 Abderrahim Kitouni 2008-06-18 11:34:36 UTC
No, the "base method" is being called. However, you are overriding expose_event, so base.expose_event is the same as expose_event, you are recursively calling expose_event you defined.

I don't know if it's possible to do what you mean : override a method and still calling it from the overriden method.

What your program does makes sense, however it is counter-intuitive.
Comment 2 Frederik Zipp 2008-06-18 14:06:30 UTC
(In reply to comment #1)
> No, the "base method" is being called. However, you are overriding
> expose_event, so base.expose_event is the same as expose_event, you are
> recursively calling expose_event you defined.
> 
> I don't know if it's possible to do what you mean : override a method and still
> calling it from the overriden method.
> 
> What your program does makes sense, however it is counter-intuitive.

The usual behaviour of base.method () in an overridden method is to call the original method of the base class (the method it was before it got overridden). But in this case it doesn't work because expose_event is a signal. I think Vala should distinguish between a signal and its handler method.
Comment 3 Frederik Zipp 2008-06-18 14:12:49 UTC
using GLib;

public class SuperClass : Object {
	public virtual void method () {
		message ("base method");
	}
}

public class DerivedClass : SuperClass {
	public override void method () {
		base.method ();
		message ("child method");
	}
}

static int main (string[] args) {
	var test = new DerivedClass ();
	test.method ();
	return 0;
}

Output:

** Message: override.vala:5: base method
** Message: override.vala:12: child method
Comment 4 Abderrahim Kitouni 2008-06-18 14:25:59 UTC
Yes, you're right.
Comment 5 Jürg Billeter 2008-10-26 07:39:37 UTC
2008-10-26  Jürg Billeter  <j@bitron.ch>

	* gobject/valaccodeinvocationexpressionmodule.vala:
	* gobject/valaccodememberaccessmodule.vala:

	Support calling base method of virtual signal handler,
	fixes bug 538901

Fixed in r1932.
Comment 6 Frederik Zipp 2008-10-26 20:34:45 UTC
For me the test case still isn't working:

$ valac --pkg gtk+-2.0 exposetest.vala
exposetest.c: In function 'expose_test_real_expose_event':
exposetest.c:25: error: too many arguments to function '((struct GtkWidgetClass *)g_type_check_class_cast((struct GTypeClass *)expose_test_parent_class,  gtk_widget_get_type()))->expose_event'
error: cc exited with status 256
Compilation failed: 1 error(s), 0 warning(s)
Comment 7 Frederik Zipp 2008-11-14 23:50:03 UTC
It does work for signals without return value but not for signals with non-void return value like 'expose_event'. The generated C code is:

gboolean _tmp0;
...
return (GTK_WIDGET_CLASS (expose_test_parent_class)->expose_event (((GtkWidget*) (GTK_BUTTON (self))), &(*event), &_tmp0), _tmp0);

but it should be:

return GTK_WIDGET_CLASS (expose_test_parent_class)->expose_event (((GtkWidget*) (GTK_BUTTON (self))), &(*event));
Comment 8 Jürg Billeter 2008-11-20 20:56:53 UTC
2008-11-20  Jürg Billeter  <j@bitron.ch>

	* gobject/valaccodemethodcallmodule.vala:

	Fix base access to virtual signal handlers with return values,
	fixes bug 538901

Fixed in r2040.