Skip to content
This repository was archived by the owner on Oct 4, 2021. It is now read-only.

Commit 392e5dc

Browse files
authored
Merge pull request #7706 from mono/pr-david-fix822175
Fix 822175: Exception adornment scrolled outside of view
2 parents 899a87b + bb85e62 commit 392e5dc

File tree

1 file changed

+41
-12
lines changed

1 file changed

+41
-12
lines changed

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/ExceptionCaught/ExceptionCaughtAdornmentManager.cs

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class ExceptionCaughtAdornmentManager : IDisposable
4343
private readonly string filePath;
4444
readonly IXPlatAdornmentLayer _exceptionCaughtLayer;
4545
FileLineExtension extension;
46+
NSPanel exceptionCaughtButtonWindow;
4647

4748
public ExceptionCaughtAdornmentManager (ICocoaViewFactory cocoaViewFactory, ICocoaTextView textView)
4849
{
@@ -68,6 +69,10 @@ private void FileExtensionRemoved (object sender, FileExtensionEventArgs e)
6869
if (e.Extension == extension) {
6970
extension = null;
7071
_exceptionCaughtLayer.RemoveAllAdornments ();
72+
if (exceptionCaughtButtonWindow != null) {
73+
exceptionCaughtButtonWindow.Close ();
74+
exceptionCaughtButtonWindow = null;
75+
}
7176
}
7277
}
7378

@@ -81,11 +86,14 @@ private void FileExtensionAdded (object sender, FileExtensionEventArgs e)
8186
private void RenderAdornment (FileLineExtension fileLineExtension)
8287
{
8388
NSView view;
84-
if (fileLineExtension is ExceptionCaughtButton button)
89+
bool mini;
90+
if (fileLineExtension is ExceptionCaughtButton button) {
91+
mini = false;
8592
view = CreateButton (cocoaViewFactory, button);
86-
else if (fileLineExtension is ExceptionCaughtMiniButton miniButton)
93+
} else if (fileLineExtension is ExceptionCaughtMiniButton miniButton) {
94+
mini = true;
8795
view = CreateMiniButton (cocoaViewFactory, miniButton);
88-
else
96+
} else
8997
return;
9098
if (extension != fileLineExtension) {
9199
extension = fileLineExtension;
@@ -97,17 +105,38 @@ private void RenderAdornment (FileLineExtension fileLineExtension)
97105
return;
98106
if (!textView.TextViewLines.FormattedSpan.Contains (span.End))
99107
return;
100-
try {
101-
var charBound = textView.TextViewLines.GetCharacterBounds (span.End);
102-
view.SetFrameOrigin (new CGPoint (
108+
_exceptionCaughtLayer.RemoveAllAdornments ();
109+
if (exceptionCaughtButtonWindow != null) {
110+
exceptionCaughtButtonWindow.Close ();
111+
exceptionCaughtButtonWindow = null;
112+
}
113+
var charBound = textView.TextViewLines.GetCharacterBounds (span.End);
114+
if (mini) {
115+
try {
116+
view.SetFrameOrigin (new CGPoint (
103117
Math.Round (charBound.Left),
104-
Math.Round (charBound.TextTop + charBound.TextHeight / 2 - view.Frame.Height / 2)));
105-
} catch (Exception e) {
106-
view.SetFrameOrigin (default);
107-
LoggingService.LogInternalError ("https://vsmac.dev/923058", e);
118+
Math.Round (charBound.TextTop - charBound.TextHeight / 2 - view.Frame.Height / 2)));
119+
} catch (Exception e) {
120+
view.SetFrameOrigin (default);
121+
LoggingService.LogInternalError ("https://vsmac.dev/923058", e);
122+
}
123+
_exceptionCaughtLayer.AddAdornment (XPlatAdornmentPositioningBehavior.TextRelative, span, null, view, null);
124+
} else {
125+
var editorWindow = textView.VisualElement.Window;
126+
var pointOnScreen = editorWindow.ConvertPointToScreen (textView.VisualElement.ConvertPointToView (new CGPoint (charBound.Left, charBound.TextTop), null));
127+
exceptionCaughtButtonWindow = new NSPanel (CGRect.Empty, NSWindowStyle.Borderless, NSBackingStore.Buffered, false);
128+
exceptionCaughtButtonWindow.AccessibilityRole = NSAccessibilityRoles.PopoverRole;
129+
editorWindow.AddChildWindow (exceptionCaughtButtonWindow, NSWindowOrderingMode.Above);
130+
exceptionCaughtButtonWindow.IsOpaque = false;
131+
exceptionCaughtButtonWindow.BackgroundColor = NSColor.Clear;
132+
exceptionCaughtButtonWindow.HasShadow = true;
133+
exceptionCaughtButtonWindow.ContentView = view;
134+
var fittingSize = view.FittingSize;
135+
var x = Math.Min (editorWindow.Screen.VisibleFrame.Width - fittingSize.Width, pointOnScreen.X);
136+
var y = Math.Max (0, pointOnScreen.Y - fittingSize.Height / 2);
137+
exceptionCaughtButtonWindow.SetFrame (new CGRect (x, y, fittingSize.Width, fittingSize.Height), true);
138+
exceptionCaughtButtonWindow.MakeKeyAndOrderFront (null);
108139
}
109-
_exceptionCaughtLayer.RemoveAllAdornments ();
110-
_exceptionCaughtLayer.AddAdornment (XPlatAdornmentPositioningBehavior.TextRelative, span, null, view, null);
111140
}
112141

113142
private void TextView_LayoutChanged (object sender, TextViewLayoutChangedEventArgs e)

0 commit comments

Comments
 (0)