private async Task EvaluateAndShowTooltipAsync(IAsyncQuickInfoSession session, ITextView view, SnapshotPoint point, DataTipInfo debugInfo, CancellationToken cancellationToken)
        {
            var options = DebuggingService.DebuggerSession.EvaluationOptions.Clone();

            options.AllowMethodEvaluation = true;
            options.AllowTargetInvoke     = true;

            var val = DebuggingService.CurrentFrame.GetExpressionValue(debugInfo.Text, options);

            if (val.IsEvaluating)
            {
                await WaitOneAsync(val.WaitHandle, cancellationToken);
            }

            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            if (val == null || val.IsUnknown || val.IsNotSupported)
            {
                return;
            }

            if (!view.Properties.TryGetProperty(typeof(Gtk.Widget), out Gtk.Widget gtkParent))
            {
                return;
            }

            provider.textDocumentFactoryService.TryGetTextDocument(view.TextDataModel.DocumentBuffer, out var textDocument);

            // This is a bit hacky, since AsyncQuickInfo is designed to display multiple elements if multiple sources
            // return value, we don't want that for debugger value hovering, hence we dismiss AsyncQuickInfo
            // and do our own thing, notice VS does same thing
            await session.DismissAsync();

            await provider.joinableTaskContext.Factory.SwitchToMainThreadAsync();

            this.lastView = view;
            val.Name      = debugInfo.Text;
            window        = new DebugValueWindow((Gtk.Window)gtkParent.Toplevel, textDocument?.FilePath, textBuffer.CurrentSnapshot.GetLineNumberFromPosition(debugInfo.Span.GetStartPoint(textBuffer.CurrentSnapshot)), DebuggingService.CurrentFrame, val, null);
            Ide.IdeApp.CommandService.RegisterTopWindow(window);
            var bounds = view.TextViewLines.GetCharacterBounds(point);

            view.LayoutChanged += LayoutChanged;
#if CLOSE_ON_FOCUS_LOST
            view.LostAggregateFocus += View_LostAggregateFocus;
#endif
            RegisterForHiddenAsync(view).Ignore();
            window.LeaveNotifyEvent += LeaveNotifyEvent;
#if MAC
            var cocoaView = ((ICocoaTextView)view);
            var cgPoint   = cocoaView.VisualElement.ConvertPointToView(new CoreGraphics.CGPoint(bounds.Left - view.ViewportLeft, bounds.Top - view.ViewportTop), cocoaView.VisualElement.Superview);
            cgPoint.Y = cocoaView.VisualElement.Superview.Frame.Height - cgPoint.Y;
            window.ShowPopup(gtkParent, new Gdk.Rectangle((int)cgPoint.X, (int)cgPoint.Y, (int)bounds.Width, (int)bounds.Height), Components.PopupPosition.TopLeft);
#else
            throw new NotImplementedException();
#endif
        }
예제 #2
0
 void CurrentFrameChanged(object sender, EventArgs e)
 {
     if (window != null)
     {
         window.Destroy();
         window = null;
     }
 }
예제 #3
0
        void TargetProcessExited(object sender, EventArgs e)
        {
            if (window == null)
            {
                return;
            }
            var debuggerSession = window.Tree.Frame?.DebuggerSession;

            if (debuggerSession == null || debuggerSession == sender)
            {
                window.Destroy();
                window = null;
            }
        }
예제 #4
0
 void DestroyWindow()
 {
     Runtime.AssertMainThread();
     if (window != null)
     {
         window.Destroy();
         window.LeaveNotifyEvent -= LeaveNotifyEvent;
         window = null;
     }
     if (lastView != null)
     {
         lastView.LayoutChanged -= LayoutChanged;
         lastView = null;
     }
 }
        void DestroyWindow()
        {
            Runtime.AssertMainThread();
            if (window != null)
            {
                window.Destroy();
                window.LeaveNotifyEvent -= LeaveNotifyEvent;
                window = null;
            }
            if (lastView != null)
            {
                lastView.LayoutChanged -= LayoutChanged;
#if CLOSE_ON_FOCUS_LOST
                lastView.LostAggregateFocus -= View_LostAggregateFocus;
#endif
                lastView = null;
            }
            if (lastDocumentView != null)
            {
                lastDocumentView.ContentHidden -= DocumentView_ContentHidden;
                lastDocumentView = null;
            }
        }
예제 #6
0
        public async Task <QuickInfoItem> GetQuickInfoItemAsync(IAsyncQuickInfoSession session, CancellationToken cancellationToken)
        {
            if (DebuggingService.CurrentFrame == null)
            {
                return(null);
            }
            if (window != null)
            {
                await Runtime.RunInMainThread(DestroyWindow);
            }
            var view = session.TextView;

            var textViewLines = view.TextViewLines;
            var snapshot      = textViewLines.FormattedSpan.Snapshot;
            var triggerPoint  = session.GetTriggerPoint(textBuffer);
            var point         = triggerPoint.GetPoint(snapshot);

            foreach (var debugInfoProvider in provider.debugInfoProviders)
            {
                var debugInfo = await debugInfoProvider.Value.GetDebugInfoAsync(point, cancellationToken);

                if (debugInfo.Text == null)
                {
                    continue;
                }

                var options = DebuggingService.DebuggerSession.EvaluationOptions.Clone();
                options.AllowMethodEvaluation = true;
                options.AllowTargetInvoke     = true;

                var val = DebuggingService.CurrentFrame.GetExpressionValue(debugInfo.Text, options);

                if (val.IsEvaluating)
                {
                    await WaitOneAsync(val.WaitHandle, cancellationToken);
                }
                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }
                if (val == null || val.IsUnknown || val.IsNotSupported || val.IsError)
                {
                    return(null);
                }

                if (!view.Properties.TryGetProperty(typeof(Gtk.Widget), out Gtk.Widget gtkParent))
                {
                    return(null);
                }
                provider.textDocumentFactoryService.TryGetTextDocument(textBuffer, out var textDocument);

                // This is a bit hacky, since AsyncQuickInfo is designed to display multiple elements if multiple sources
                // return value, we don't want that for debugger value hovering, hence we dismiss AsyncQuickInfo
                // and do our own thing, notice VS does same thing
                await session.DismissAsync();

                await provider.joinableTaskContext.Factory.SwitchToMainThreadAsync();

                this.lastView = view;
                val.Name      = debugInfo.Text;
                window        = new DebugValueWindow((Gtk.Window)gtkParent.Toplevel, textDocument?.FilePath, textBuffer.CurrentSnapshot.GetLineNumberFromPosition(debugInfo.Span.GetStartPoint(textBuffer.CurrentSnapshot)), DebuggingService.CurrentFrame, val, null);
                Ide.IdeApp.CommandService.RegisterTopWindow(window);
                var bounds = view.TextViewLines.GetCharacterBounds(point);
                view.LayoutChanged      += LayoutChanged;
                window.LeaveNotifyEvent += LeaveNotifyEvent;
#if MAC
                var cocoaView = ((ICocoaTextView)view);
                var cgPoint   = cocoaView.VisualElement.ConvertPointToView(new CoreGraphics.CGPoint(bounds.Left - view.ViewportLeft, bounds.Top - view.ViewportTop), cocoaView.VisualElement.Superview);
                cgPoint.Y = cocoaView.VisualElement.Superview.Frame.Height - cgPoint.Y;
                window.ShowPopup(gtkParent, new Gdk.Rectangle((int)cgPoint.X, (int)cgPoint.Y, (int)bounds.Width, (int)bounds.Height), Components.PopupPosition.TopLeft);
#else
                throw new NotImplementedException();
#endif
                return(null);
            }
            return(null);
        }