GNOME Bugzilla – Bug 538901
Calling base method from overridden signal handler causes endless loop
Last modified: 2008-11-20 20:56:53 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.
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.
(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.
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
Yes, you're right.
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.
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)
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));
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.