diff options
author | Greg Munn <greg@sgmunn.com> | 2017-12-07 18:42:11 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-07 18:42:11 +0300 |
commit | d203af94011a0bfba0685a67e73281a53c25e393 (patch) | |
tree | 1b005f877242d85a2c77d2ee086d47bc697178f7 | |
parent | 52b6d708c9a803a58ba632f7f4d549d1ccee2db3 (diff) | |
parent | 086388af65489804c26db80cfd90ce41a164a610 (diff) |
Merge pull request #3430 from mono/d15-5-leak-fixes
D15 5 leak fixes
9 files changed, 139 insertions, 23 deletions
diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs index 76a357193a..7d7c66dc2e 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs @@ -130,7 +130,7 @@ namespace Mono.TextEditor get { return charWidth; } } - class TextViewMarginAccessibilityProxy + class TextViewMarginAccessibilityProxy : IDisposable { public AccessibilityElementProxy Accessible { get; private set; } public TextViewMargin Margin { get; set; } @@ -151,6 +151,23 @@ namespace Mono.TextEditor Accessible.GetVisibleCharacterRange = GetVisibleCharacterRange; } + public void Dispose () + { + Accessible.Contents = null; + Accessible.InsertionPointLineNumber = null; + Accessible.NumberOfCharacters = null; + Accessible.FrameForRange = null; + Accessible.LineForIndex = null; + Accessible.RangeForLine = null; + Accessible.StringForRange = null; + Accessible.RangeForIndex = null; + Accessible.StyleRangeForIndex = null; + Accessible.RangeForPosition = null; + Accessible.GetVisibleCharacterRange = null; + Accessible = null; + Margin = null; + } + int GetInsertionPointLineNumber () { return Margin.Caret.Line; @@ -692,6 +709,8 @@ namespace Mono.TextEditor DisposeLayoutDict (); if (tabArray != null) tabArray.Dispose (); + accessible?.Dispose (); + accessible = null; base.Dispose (); } diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs index b7e2a2c53d..0399334e74 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs @@ -199,6 +199,7 @@ namespace MonoDevelop.SourceEditor.QuickTasks protected override void OnDestroyed () { + DisposeProxies(); DestroyBackgroundSurface (); RemoveIndicatorIdleHandler (); DestroyIndicatorSwapSurface (); @@ -1411,24 +1412,39 @@ namespace MonoDevelop.SourceEditor.QuickTasks } #region Accessibility + List<IQuickTaskAccessible> allyChildren; + void DisposeProxies () + { + if (allyChildren != null) { + foreach (var child in allyChildren) + child.Dispose (); + } + allyChildren = null; + } + public AccessibilityElementProxy[] UpdateAccessibility () { - List<AccessibilityElementProxy> allyChildren = new List<AccessibilityElementProxy> (); - allyChildren.Add (new QuickTaskOverviewAccessible (parentStrip, this).Accessible); + DisposeProxies (); + allyChildren = new List<IQuickTaskAccessible>(); + allyChildren.Add (new QuickTaskOverviewAccessible (parentStrip, this)); foreach (var t in AllTasks) { - allyChildren.Add (new QuickTaskAccessible (parentStrip, this, t).Accessible); + allyChildren.Add (new QuickTaskAccessible (parentStrip, this, t)); } foreach (var u in AllUsages) { - allyChildren.Add (new QuickTaskAccessible (parentStrip, this, u).Accessible); + allyChildren.Add (new QuickTaskAccessible (parentStrip, this, u)); } - return allyChildren.ToArray (); + return allyChildren.Select (x => x.Accessible).ToArray (); } + interface IQuickTaskAccessible : IDisposable + { + AccessibilityElementProxy Accessible { get; } + } - class QuickTaskOverviewAccessible + class QuickTaskOverviewAccessible : IQuickTaskAccessible { public AccessibilityElementProxy Accessible { get; private set; } @@ -1473,9 +1489,14 @@ namespace MonoDevelop.SourceEditor.QuickTasks Accessible.Help = description; } } + + public void Dispose () + { + Accessible.PerformPress -= PerformPress; + } } - class QuickTaskAccessible + class QuickTaskAccessible : IQuickTaskAccessible { public AccessibilityElementProxy Accessible { get; private set; } QuickTaskStrip strip; @@ -1543,6 +1564,11 @@ namespace MonoDevelop.SourceEditor.QuickTasks strip.GotoUsage (usage); } } + + public void Dispose () + { + Accessible.PerformPress -= PerformPress; + } } #endregion } diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskStrip.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskStrip.cs index cfef8d4174..cf897d6d40 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskStrip.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskStrip.cs @@ -155,8 +155,12 @@ namespace MonoDevelop.SourceEditor.QuickTasks if (mapMode != null) { mapMode.Destroy (); mapMode = null; + } + if (overviewMode != null) { + overviewMode.Destroy (); overviewMode = null; } + if (EnableFancyFeatures) { switch (ScrollBarMode) { case ScrollBarMode.Overview: diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperMac.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperMac.cs index 72db6ed405..6c50981a07 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperMac.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AtkCocoaHelper/AtkCocoaHelperMac.cs @@ -1059,8 +1059,7 @@ namespace MonoDevelop.Components.AtkCocoaHelper } } - protected Gtk.Widget parent; - INSAccessibility parentElement; + protected WeakReference<Gtk.Widget> parentRef = new WeakReference<Gtk.Widget> (null); Rectangle realFrame; void UpdateActions () @@ -1084,11 +1083,11 @@ namespace MonoDevelop.Components.AtkCocoaHelper // It is used to convert the frame public Gtk.Widget GtkParent { get { + parentRef.TryGetTarget (out var parent); return parent; } set { - parent = value; - parentElement = AtkCocoaMacExtensions.GetNSAccessibilityElement (parent.Accessible); + parentRef.SetTarget (value); } } @@ -1227,6 +1226,11 @@ namespace MonoDevelop.Components.AtkCocoaHelper [Export ("accessibilityHitTest:")] public virtual NSObject GetAccessibilityHitTest (CGPoint pointOnScreen) { + parentRef.TryGetTarget (out var parent); + if (parent == null) { + return null; + } + var gdkWindow = parent.GdkWindow; if (gdkWindow == null) { @@ -1343,9 +1347,17 @@ namespace MonoDevelop.Components.AtkCocoaHelper public override bool AccessibilityFocused { get { + parentRef.TryGetTarget (out var parent); + if (parent == null) { + return false; + } return parent.HasFocus; } set { + parentRef.TryGetTarget (out var parent); + if (parent == null) { + return; + } parent.HasFocus = value; } } @@ -1472,6 +1484,11 @@ namespace MonoDevelop.Components.AtkCocoaHelper [Export ("accessibilityFrameForRange:")] CGRect AccessibilityFrameForRange (NSRange range) { + parentRef.TryGetTarget (out var parent); + if (parent == null) { + return CGRect.Empty; + } + var realRange = new AtkCocoa.Range { Location = (int)range.Location, Length = (int)range.Length }; var frame = GetFrameForRange (realRange); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebookTab.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebookTab.cs index 61874358fd..76b46eae19 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebookTab.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebookTab.cs @@ -33,7 +33,7 @@ using MonoDevelop.Components.AtkCocoaHelper; namespace MonoDevelop.Components.DockNotebook { - class DockNotebookTab: IAnimatable + class DockNotebookTab: IAnimatable, IDisposable { DockNotebook notebook; readonly TabStrip strip; @@ -223,7 +223,7 @@ namespace MonoDevelop.Components.DockNotebook CloseButtonAccessible.PerformPress += OnPressCloseButton; CloseButtonAccessible.SetRole (AtkCocoa.Roles.AXButton); CloseButtonAccessible.GtkParent = strip; - CloseButtonAccessible.PerformShowMenu += OnShowMenu; + CloseButtonAccessible.PerformShowMenu += OnCloseButtonShowMenu; CloseButtonAccessible.Title = Core.GettextCatalog.GetString ("Close document"); CloseButtonAccessible.Identifier = "DockNotebook.Tab.CloseButton"; Accessible.AddAccessibleChild (CloseButtonAccessible); @@ -268,5 +268,13 @@ namespace MonoDevelop.Components.DockNotebook { AccessibilityShowMenu?.Invoke (this, args); } + + public void Dispose () + { + Accessible.PerformPress -= OnPressTab; + Accessible.PerformShowMenu -= OnShowMenu; + CloseButtonAccessible.PerformShowMenu -= OnCloseButtonShowMenu; + CloseButtonAccessible.PerformPress -= OnPressCloseButton; + } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/TabStrip.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/TabStrip.cs index 6e142c9a75..b6da1da6ca 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/TabStrip.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/TabStrip.cs @@ -268,6 +268,8 @@ namespace MonoDevelop.Components.DockNotebook Accessible.RemoveAccessibleElement (tab.Accessible); + tab.Dispose (); + QueueResize (); UpdateAccessibilityTabs (); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/DropDownBoxListWindow.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/DropDownBoxListWindow.cs index 0f737e6764..8befd91b8f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/DropDownBoxListWindow.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/DropDownBoxListWindow.cs @@ -110,7 +110,8 @@ namespace MonoDevelop.Components public void SelectItem (object item) { - for (int i = 0; i < DataProvider.IconCount; i++) { + int count = DataProvider.IconCount; + for (int i = 0; i < count; i++) { if (DataProvider.GetTag (i) == item) { list.Selection = i; vScrollbar.Vadjustment.Value = Math.Max (0, i * list.RowHeight - vScrollbar.Vadjustment.PageSize / 2); @@ -122,7 +123,8 @@ namespace MonoDevelop.Components void SwitchToSeletedWord () { string selection = list.WordSelection.ToString (); - for (int i = 0; i < DataProvider.IconCount; i++) { + int count = DataProvider.IconCount; + for (int i = 0; i < count; i++) { if (DataProvider.GetMarkup (i).StartsWith (selection, StringComparison.OrdinalIgnoreCase)) { list.Selection = i; list.WordSelection.Append (selection); @@ -257,6 +259,7 @@ namespace MonoDevelop.Components } } + TextElement[] textElements; void CalcAccessibility () { var columnElement = new AtkCocoaHelper.AccessibilityElementProxy (); @@ -264,7 +267,9 @@ namespace MonoDevelop.Components columnElement.SetRole (AtkCocoa.Roles.AXColumn); Accessible.AddAccessibleElement (columnElement); - for (int i = 0; i < win.DataProvider.IconCount; i++) { + int count = win.DataProvider.IconCount; + textElements = new TextElement[count]; + for (int i = 0; i < count; i++) { var rowElement = new AtkCocoaHelper.AccessibilityElementProxy (); rowElement.GtkParent = this; rowElement.SetRole (AtkCocoa.Roles.AXRow); @@ -276,7 +281,7 @@ namespace MonoDevelop.Components columnElement.AddAccessibleChild (cellElement); rowElement.AddAccessibleChild (cellElement); - var textElement = new TextElement (); + var textElement = textElements[i] = new TextElement (); textElement.RowIndex = i; textElement.PerformPress += PerformPress; textElement.GtkParent = this; @@ -287,7 +292,7 @@ namespace MonoDevelop.Components void PerformPress (object sender, EventArgs args) { - var element = sender as TextElement; + var element = (TextElement)sender; win.DataProvider.ActivateItem (element.RowIndex); } @@ -313,6 +318,13 @@ namespace MonoDevelop.Components protected override void OnDestroyed () { + if (textElements != null) { + foreach (var textElement in textElements) { + textElement.PerformPress -= PerformPress; + } + textElements = null; + } + if (layout != null) { layout.Dispose (); layout = null; @@ -527,8 +539,9 @@ namespace MonoDevelop.Components return 0; int longest = 0; string longestText = win.DataProvider.GetMarkup (0) ?? ""; - - for (int i = 1; i < win.DataProvider.IconCount; i++) { + + int count = win.DataProvider.IconCount; + for (int i = 1; i < count; i++) { string curText = win.DataProvider.GetMarkup (i) ?? ""; if (curText.Length > longestText.Length) { longestText = curText; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/PathBar.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/PathBar.cs index 58e65dba0a..b807c8a7f5 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/PathBar.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/PathBar.cs @@ -44,7 +44,7 @@ namespace MonoDevelop.Components Right } - public class PathEntry + public class PathEntry : IDisposable { Xwt.Drawing.Image darkIcon; @@ -136,6 +136,14 @@ namespace MonoDevelop.Components { PerformShowMenu?.Invoke (this, EventArgs.Empty); } + + public void Dispose () + { + if (accessible != null) { + accessible.PerformPress -= OnPerformShowMenu; + accessible = null; + } + } } class PathBar : Gtk.DrawingArea @@ -233,11 +241,23 @@ namespace MonoDevelop.Components Accessible.ReplaceAccessibilityElements (elements); } + void DisposeProxies() + { + if (Path == null) + return; + + foreach (var entry in Path) { + entry.PerformShowMenu -= PerformShowMenu; + entry.Dispose (); + } + } + public void SetPath (PathEntry[] path) { if (ArrSame (this.leftPath, path)) return; + DisposeProxies (); HideMenu (); this.Path = path ?? new PathEntry[0]; @@ -814,6 +834,8 @@ namespace MonoDevelop.Components protected override void OnDestroyed () { base.OnDestroyed (); + + DisposeProxies (); styleButton.Destroy (); KillLayout (); this.boldAtts.Dispose (); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs index 4cc6db7bac..4457dbd400 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs @@ -383,8 +383,13 @@ namespace MonoDevelop.Components public void Dispose () { + if (Accessible != null) { + Accessible.PerformPress -= OnTabPressed; + Accessible = null; + } + if (layout != null) - layout.Dispose (); + layout.Dispose(); } public AtkCocoaHelper.AccessibilityElementProxy Accessible { get; private set; } |