[Gtk-sharp-list] bug: Removing event handlers
Gonzalo Paniagua Javier
gonzalo@ximian.com
05 Feb 2003 15:16:20 +0100
--=-nR+iQKdSLyZ7TZD0Retu
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
El mié, 05-02-2003 a las 15:40, Lee Mallabone escribió:
> Greetings,
>
> I've found what I think is a bug with removing event handlers in
> Gtk#/mono.
>
> When I use:
>
> button.Clicked -= new EventHandler(handler1);
>
> the handler is not actually removed, and still receives events from the
> button.
>
> I've attached a small test case that demonstrates this behaviour - after
> switching event handlers on a button, both the old and the new handlers
> are fired rather than just the new handler.
>
> Could anyone please comment on whether they can reproduce this? I'm
> using RedHat 8.0 with mono 0.19 and Gtk# 0.7.
>
> I've opened a bug on bugzilla.ximian.com to track this, (bug #37635),
> but thought I'd post here in case there's some magic quick fix I'm just
> not seeing. :)
Here's the magic quick fix ;-).
The patch attached adds a couple of methods in SignalCallback.cs to
add/remove a delegate from the _handle.
Also modifies Signal.cs in the generator to make use of the above
methods when adding/removing a handler for a signal.
Ok to commit?
-Gonzalo
P.S.: the generated code for signals now looks like:
[GLib.Signal("clicked")]
public event EventHandler Clicked {
add {
if (EventList["clicked"] == null)
Signals["clicked"] = new GtkSharp.voidObjectSignal(this, Handle,
"clicked", value, System.Type.GetType("System.EventArgs"));
else
((GtkSharp.SignalCallback) Signals ["clicked"]).AddDelegate (value);
EventList.AddHandler("clicked", value);
}
remove {
EventList.RemoveHandler("clicked", value);
if (EventList["clicked"] == null)
Signals.Remove("clicked");
else
((GtkSharp.SignalCallback) Signals ["clicked"]).RemoveDelegate
(value);
}
}
P.S.2: ah! I also changed MulticastDelegate to be just Delegate to avoid
casting :-) (all delegates are MulticastDelegates)
--=-nR+iQKdSLyZ7TZD0Retu
Content-Disposition: attachment; filename=signals.patch
Content-Type: text/x-patch; name=signals.patch; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Index: generator/Signal.cs
===================================================================
RCS file: /cvs/public/gtk-sharp/generator/Signal.cs,v
retrieving revision 1.11
diff -u -r1.11 Signal.cs
--- generator/Signal.cs 9 Dec 2002 23:36:18 -0000 1.11
+++ generator/Signal.cs 5 Feb 2003 13:58:47 -0000
@@ -163,13 +163,16 @@
sw.Write("(this, Handle, " + cname + ", value, System.Type.GetType(\"" + argsname);
if (argsname != "System.EventArgs")
sw.Write("," + container_type.NS.ToLower() + "-sharp");
- sw.WriteLine("\"));");
+ sw.WriteLine("\"));\n\t\t\t\telse");
+ sw.WriteLine("\t\t\t\t\t((GtkSharp.SignalCallback) Signals [{0}]).AddDelegate (value);", cname);
sw.WriteLine("\t\t\t\tEventList.AddHandler(" + cname + ", value);");
sw.WriteLine("\t\t\t}");
sw.WriteLine("\t\t\tremove {");
sw.WriteLine("\t\t\t\tEventList.RemoveHandler(" + cname + ", value);");
sw.WriteLine("\t\t\t\tif (EventList[" + cname + "] == null)");
sw.WriteLine("\t\t\t\t\tSignals.Remove(" + cname + ");");
+ sw.WriteLine("\t\t\t\telse");
+ sw.WriteLine("\t\t\t\t\t((GtkSharp.SignalCallback) Signals [{0}]).RemoveDelegate (value);", cname);
sw.WriteLine("\t\t\t}");
sw.WriteLine("\t\t}");
sw.WriteLine();
Index: generator/SignalHandler.cs
===================================================================
RCS file: /cvs/public/gtk-sharp/generator/SignalHandler.cs,v
retrieving revision 1.18
diff -u -r1.18 SignalHandler.cs
--- generator/SignalHandler.cs 10 Nov 2002 10:03:50 -0000 1.18
+++ generator/SignalHandler.cs 5 Feb 2003 13:58:47 -0000
@@ -168,7 +168,7 @@
sw.WriteLine(" int flags);");
sw.WriteLine();
sw.Write("\t\tpublic " + sname + "(GLib.Object obj, IntPtr raw, ");
- sw.WriteLine("String name, MulticastDelegate eh, Type argstype) : base(obj, eh, argstype)");
+ sw.WriteLine("String name, Delegate eh, Type argstype) : base(obj, eh, argstype)");
sw.WriteLine("\t\t{");
sw.WriteLine("\t\t\tif (_Delegate == null) {");
sw.WriteLine("\t\t\t\t_Delegate = new " + dname + "(" + cbname + ");");
Index: glib/SignalCallback.cs
===================================================================
RCS file: /cvs/public/gtk-sharp/glib/SignalCallback.cs,v
retrieving revision 1.3
diff -u -r1.3 SignalCallback.cs
--- glib/SignalCallback.cs 16 Jul 2002 23:14:35 -0000 1.3
+++ glib/SignalCallback.cs 5 Feb 2003 13:58:47 -0000
@@ -28,7 +28,7 @@
// protected instance members
protected GLib.Object _obj;
- protected MulticastDelegate _handler;
+ protected Delegate _handler;
protected int _key;
protected Type _argstype;
@@ -40,7 +40,7 @@
/// Initializes instance data.
/// </remarks>
- public SignalCallback (GLib.Object obj, MulticastDelegate eh, Type argstype)
+ public SignalCallback (GLib.Object obj, Delegate eh, Type argstype)
{
_key = _NextKey++;
_obj = obj;
@@ -49,5 +49,14 @@
_Instances [_key] = this;
}
+ public void AddDelegate (Delegate d)
+ {
+ _handler = Delegate.Combine (_handler, d);
+ }
+
+ public void RemoveDelegate (Delegate d)
+ {
+ _handler = Delegate.Remove (_handler, d);
+ }
}
}
--=-nR+iQKdSLyZ7TZD0Retu--