Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Ungureanu <teromario@yahoo.com>2017-04-28 13:01:09 +0300
committerGitHub <noreply@github.com>2017-04-28 13:01:09 +0300
commit072d0b47edd511c176e557b267f81f6a031e4637 (patch)
tree5b76b3526058bc0af8cbe29dccf273777effb6fd /main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper
parent9f377413161fbd093cd48d6fa2387e8021da07ce (diff)
[Atk] Fix leak caused by circular referencing in Atk code. (#2293)
The action code was creating a circular ref between the accessible and the object via the signals. Break all the refs.
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper')
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelper.cs58
1 files changed, 33 insertions, 25 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelper.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelper.cs
index 443255181a..cfb35700cc 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelper.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelper.cs
@@ -113,34 +113,39 @@ namespace MonoDevelop.Components.AtkCocoaHelper
return;
}
- var signal = GLib.Signal.Lookup (owner, "request-actions", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (RequestActionsHandler));
-
- signal = GLib.Signal.Lookup (owner, "perform-cancel", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (PerformCancelHandler));
- signal = GLib.Signal.Lookup (owner, "perform-confirm", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (PerformConfirmHandler));
- signal = GLib.Signal.Lookup (owner, "perform-decrement", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (PerformDecrementHandler));
- signal = GLib.Signal.Lookup (owner, "perform-delete", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (PerformDeleteHandler));
- signal = GLib.Signal.Lookup (owner, "perform-increment", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (PerformIncrementHandler));
- signal = GLib.Signal.Lookup (owner, "perform-pick", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (PerformPickHandler));
- signal = GLib.Signal.Lookup (owner, "perform-press", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (PerformPressHandler));
- signal = GLib.Signal.Lookup (owner, "perform-raise", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (PerformRaiseHandler));
- signal = GLib.Signal.Lookup (owner, "perform-show-alternate-ui", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (PerformShowAlternateUIHandler));
- signal = GLib.Signal.Lookup (owner, "perform-show-default-ui", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (PerformShowDefaultUIHandler));
- signal = GLib.Signal.Lookup (owner, "perform-show-menu", typeof (GLib.SignalArgs));
- signal.AddDelegate (new EventHandler<GLib.SignalArgs> (PerformShowMenuHandler));
+ HandleSignalAttachment (owner, (signal, handler) => signal.AddDelegate (handler));
}
}
+ void HandleSignalAttachment (Atk.Object owner, Action<GLib.Signal, EventHandler<GLib.SignalArgs>> action)
+ {
+ var signal = GLib.Signal.Lookup (owner, "request-actions", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (RequestActionsHandler));
+
+ signal = GLib.Signal.Lookup (owner, "perform-cancel", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (PerformCancelHandler));
+ signal = GLib.Signal.Lookup (owner, "perform-confirm", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (PerformConfirmHandler));
+ signal = GLib.Signal.Lookup (owner, "perform-decrement", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (PerformDecrementHandler));
+ signal = GLib.Signal.Lookup (owner, "perform-delete", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (PerformDeleteHandler));
+ signal = GLib.Signal.Lookup (owner, "perform-increment", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (PerformIncrementHandler));
+ signal = GLib.Signal.Lookup (owner, "perform-pick", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (PerformPickHandler));
+ signal = GLib.Signal.Lookup (owner, "perform-press", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (PerformPressHandler));
+ signal = GLib.Signal.Lookup (owner, "perform-raise", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (PerformRaiseHandler));
+ signal = GLib.Signal.Lookup (owner, "perform-show-alternate-ui", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (PerformShowAlternateUIHandler));
+ signal = GLib.Signal.Lookup (owner, "perform-show-default-ui", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (PerformShowDefaultUIHandler));
+ signal = GLib.Signal.Lookup (owner, "perform-show-menu", typeof (GLib.SignalArgs));
+ action (signal, new EventHandler<GLib.SignalArgs> (PerformShowMenuHandler));
+ }
+
public ActionDelegate (Gtk.Widget widget)
{
widget.Destroyed += WidgetDestroyed;
@@ -150,6 +155,9 @@ namespace MonoDevelop.Components.AtkCocoaHelper
void WidgetDestroyed (object sender, EventArgs e)
{
FreeActions ();
+
+ HandleSignalAttachment (owner, (signal, handler) => signal.RemoveDelegate (handler));
+ owner = null;
}
// Because the allocated memory is passed to unmanaged code where it cannot be freed