Skip to content

Commit

Permalink
Disable quickinfo on new inline rename (#63907)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryzngard authored Sep 26, 2022
1 parent 3df66d1 commit 2a9812e
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Utilities;

namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename
{
Expand All @@ -21,15 +25,23 @@ internal partial class RenameFlyout : InlineRenameAdornment
{
private readonly RenameFlyoutViewModel _viewModel;
private readonly IWpfTextView _textView;

public RenameFlyout(RenameFlyoutViewModel viewModel, IWpfTextView textView, IWpfThemeService? themeService)
private readonly IAsyncQuickInfoBroker _asyncQuickInfoBroker;
private readonly IAsynchronousOperationListener _listener;

public RenameFlyout(
RenameFlyoutViewModel viewModel,
IWpfTextView textView,
IWpfThemeService? themeService,
IAsyncQuickInfoBroker asyncQuickInfoBroker,
IAsynchronousOperationListenerProvider listenerProvider)
{
DataContext = _viewModel = viewModel;
_textView = textView;

_asyncQuickInfoBroker = asyncQuickInfoBroker;
_textView.LayoutChanged += TextView_LayoutChanged;
_textView.ViewportHeightChanged += TextView_ViewPortChanged;
_textView.ViewportWidthChanged += TextView_ViewPortChanged;
_listener = listenerProvider.GetListener(FeatureAttribute.InlineRenameFlyout);

// On load focus the first tab target
Loaded += (s, e) =>
Expand All @@ -50,6 +62,24 @@ public RenameFlyout(RenameFlyoutViewModel viewModel, IWpfTextView textView, IWpf
Outline.BorderBrush = new SolidColorBrush(themeService.GetThemeColor(EnvironmentColors.AccentBorderColorKey));
Background = new SolidColorBrush(themeService.GetThemeColor(EnvironmentColors.ToolWindowBackgroundColorKey));
}

// Dismiss any current tooltips. Note that this does not disable tooltips
// from showing up again, so if a user has the mouse unmoved another
// tooltip will pop up. https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1611398
// tracks when we can handle this with IFeaturesService in VS
var token = _listener.BeginAsyncOperation(nameof(DismissToolTipsAsync));
_ = DismissToolTipsAsync().CompletesAsyncOperation(token);
}

private async Task DismissToolTipsAsync()
{
var infoSession = _asyncQuickInfoBroker.GetSession(_textView);
if (infoSession is null)
{
return;
}

await infoSession.DismissAsync().ConfigureAwait(false);
}

#pragma warning disable CA1822 // Mark members as static - used in xaml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.InlineRename;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;

Expand All @@ -20,6 +22,8 @@ internal class InlineRenameAdornmentManager : IDisposable
private readonly IWpfTextView _textView;
private readonly IGlobalOptionService _globalOptionService;
private readonly IWpfThemeService? _themeService;
private readonly IAsyncQuickInfoBroker _asyncQuickInfoBroker;
private readonly IAsynchronousOperationListenerProvider _listenerProvider;
private readonly InlineRenameService _renameService;
private readonly IEditorFormatMapService _editorFormatMapService;
private readonly IInlineRenameColorUpdater? _dashboardColorUpdater;
Expand All @@ -35,14 +39,18 @@ public InlineRenameAdornmentManager(
IInlineRenameColorUpdater? dashboardColorUpdater,
IWpfTextView textView,
IGlobalOptionService globalOptionService,
IWpfThemeService? themeService)
IWpfThemeService? themeService,
IAsyncQuickInfoBroker asyncQuickInfoBroker,
IAsynchronousOperationListenerProvider listenerProvider)
{
_renameService = renameService;
_editorFormatMapService = editorFormatMapService;
_dashboardColorUpdater = dashboardColorUpdater;
_textView = textView;
_globalOptionService = globalOptionService;
_themeService = themeService;
_asyncQuickInfoBroker = asyncQuickInfoBroker;
_listenerProvider = listenerProvider;
_adornmentLayer = textView.GetAdornmentLayer(InlineRenameAdornmentProvider.AdornmentLayerName);

_renameService.ActiveSessionChanged += OnActiveSessionChanged;
Expand Down Expand Up @@ -124,7 +132,9 @@ private void UpdateAdornments()
var adornment = new RenameFlyout(
(RenameFlyoutViewModel)s_createdViewModels.GetValue(_renameService.ActiveSession, session => new RenameFlyoutViewModel(session, identifierSelection, registerOleComponent: true, _globalOptionService)),
_textView,
_themeService);
_themeService,
_asyncQuickInfoBroker,
_listenerProvider);

return adornment;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
Expand All @@ -27,6 +29,8 @@ internal class InlineRenameAdornmentProvider : IWpfTextViewConnectionListener
private readonly IInlineRenameColorUpdater? _dashboardColorUpdater;
private readonly IWpfThemeService? _themeingService;
private readonly IGlobalOptionService _globalOptionService;
private readonly IAsyncQuickInfoBroker _asyncQuickInfoBroker;
private readonly IAsynchronousOperationListenerProvider _listenerProvider;
public const string AdornmentLayerName = "RoslynRenameDashboard";

[Export]
Expand All @@ -47,19 +51,23 @@ public InlineRenameAdornmentProvider(
IEditorFormatMapService editorFormatMapService,
[Import(AllowDefault = true)] IInlineRenameColorUpdater? dashboardColorUpdater,
[Import(AllowDefault = true)] IWpfThemeService? themeingService,
IGlobalOptionService globalOptionService)
IGlobalOptionService globalOptionService,
IAsyncQuickInfoBroker asyncQuickInfoBroker,
IAsynchronousOperationListenerProvider listenerProvider)
{
_renameService = renameService;
_editorFormatMapService = editorFormatMapService;
_dashboardColorUpdater = dashboardColorUpdater;
_themeingService = themeingService;
_globalOptionService = globalOptionService;
_asyncQuickInfoBroker = asyncQuickInfoBroker;
_listenerProvider = listenerProvider;
}

public void SubjectBuffersConnected(IWpfTextView textView, ConnectionReason reason, Collection<ITextBuffer> subjectBuffers)
{
// Create it for the view if we don't already have one
textView.GetOrCreateAutoClosingProperty(v => new InlineRenameAdornmentManager(_renameService, _editorFormatMapService, _dashboardColorUpdater, v, _globalOptionService, _themeingService));
textView.GetOrCreateAutoClosingProperty(v => new InlineRenameAdornmentManager(_renameService, _editorFormatMapService, _dashboardColorUpdater, v, _globalOptionService, _themeingService, _asyncQuickInfoBroker, _listenerProvider));
}

public void SubjectBuffersDisconnected(IWpfTextView textView, ConnectionReason reason, Collection<ITextBuffer> subjectBuffers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using Roslyn.Utilities;

using IntellisenseQuickInfoItem = Microsoft.VisualStudio.Language.Intellisense.QuickInfoItem;
using Microsoft.CodeAnalysis.Editor.InlineRename;

namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.QuickInfo
{
Expand All @@ -37,25 +38,34 @@ private sealed class QuickInfoSource : IAsyncQuickInfoSource
private readonly IAsynchronousOperationListener _asyncListener;
private readonly Lazy<IStreamingFindUsagesPresenter> _streamingPresenter;
private readonly IGlobalOptionService _globalOptions;
private readonly IInlineRenameService _inlineRenameService;

public QuickInfoSource(
ITextBuffer subjectBuffer,
IThreadingContext threadingContext,
IUIThreadOperationExecutor operationExecutor,
IAsynchronousOperationListener asyncListener,
Lazy<IStreamingFindUsagesPresenter> streamingPresenter,
IGlobalOptionService globalOptions)
IGlobalOptionService globalOptions,
IInlineRenameService inlineRenameService)
{
_subjectBuffer = subjectBuffer;
_threadingContext = threadingContext;
_operationExecutor = operationExecutor;
_asyncListener = asyncListener;
_streamingPresenter = streamingPresenter;
_globalOptions = globalOptions;
_inlineRenameService = inlineRenameService;
}

public async Task<IntellisenseQuickInfoItem> GetQuickInfoItemAsync(IAsyncQuickInfoSession session, CancellationToken cancellationToken)
{
// Until https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1611398 is resolved we can't disable
// quickinfo in InlineRename. Instead, we return no quickinfo information while the adornment
// is being shown. This can be removed after IFeaturesService supports disabling quickinfo
if (_globalOptions.GetOption(InlineRenameUIOptions.UseInlineAdornment) && _inlineRenameService.ActiveSession is not null)
return null;

var triggerPoint = session.GetTriggerPoint(_subjectBuffer.CurrentSnapshot);
if (!triggerPoint.HasValue)
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System;
using System.ComponentModel.Composition;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.InlineRename;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Host.Mef;
Expand All @@ -28,6 +29,7 @@ internal partial class QuickInfoSourceProvider : IAsyncQuickInfoSourceProvider
private readonly Lazy<IStreamingFindUsagesPresenter> _streamingPresenter;
private readonly IAsynchronousOperationListener _listener;
private readonly IGlobalOptionService _globalOptions;
private readonly IInlineRenameService _inlineRenameService;

[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
Expand All @@ -36,13 +38,15 @@ public QuickInfoSourceProvider(
IUIThreadOperationExecutor operationExecutor,
IAsynchronousOperationListenerProvider listenerProvider,
Lazy<IStreamingFindUsagesPresenter> streamingPresenter,
IGlobalOptionService globalOptions)
IGlobalOptionService globalOptions,
IInlineRenameService inlineRenameService)
{
_threadingContext = threadingContext;
_operationExecutor = operationExecutor;
_streamingPresenter = streamingPresenter;
_listener = listenerProvider.GetListener(FeatureAttribute.QuickInfo);
_globalOptions = globalOptions;
_inlineRenameService = inlineRenameService;
}

public IAsyncQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer)
Expand All @@ -51,7 +55,7 @@ public IAsyncQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer)
return null;

return new QuickInfoSource(
textBuffer, _threadingContext, _operationExecutor, _listener, _streamingPresenter, _globalOptions);
textBuffer, _threadingContext, _operationExecutor, _listener, _streamingPresenter, _globalOptions, _inlineRenameService);
}
}
}
102 changes: 101 additions & 1 deletion src/EditorFeatures/Test2/Rename/RenameViewModelTests.vb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Imports Microsoft.CodeAnalysis.Editor.InlineRename
Imports Microsoft.CodeAnalysis.InlineRename
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.Rename
Imports Microsoft.CodeAnalysis.[Shared].TestHooks
Imports Microsoft.VisualStudio.Language.Intellisense
Imports Microsoft.VisualStudio.Utilities

Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename
<[UseExportProvider]>
Expand Down Expand Up @@ -614,10 +617,15 @@ class D : B
Assert.Equal(severity, model.Severity)
End Using

Dim TestQuickInfoBroker = New TestQuickInfoBroker()
Dim listenerProvider = workspace.ExportProvider.GetExport(Of IAsynchronousOperationListenerProvider)().Value

Using flyout = New RenameFlyout(
New RenameFlyoutViewModel(DirectCast(sessionInfo.Session, InlineRenameSession), selectionSpan:=Nothing, registerOleComponent:=False, globalOptions), ' Don't registerOleComponent in tests, it requires OleComponentManagers that don't exist in our host
textView:=cursorDocument.GetTextView(),
themeService:=Nothing)
themeService:=Nothing,
TestQuickInfoBroker,
listenerProvider)

Await WaitForRename(workspace)

Expand All @@ -629,6 +637,12 @@ class D : B
If Not isRenameOverloadsEditable Then
Assert.True(model.RenameOverloadsFlag)
End If

Dim waiter = listenerProvider.GetWaiter(FeatureAttribute.InlineRenameFlyout)
Await waiter.ExpeditedWaitAsync()

Dim QuickInfoSession = DirectCast(TestQuickInfoBroker.GetSession(cursorDocument.GetTextView()), TestQuickInfoBroker.TestSession)
Assert.True(QuickInfoSession.Dismissed)
End Using

sessionInfo.Session.Cancel()
Expand Down Expand Up @@ -704,4 +718,90 @@ class D : B
End Using
End Sub
End Class

Friend Class TestQuickInfoBroker
Implements IAsyncQuickInfoBroker

Private ReadOnly Session As TestSession = New TestSession()

Public Function IsQuickInfoActive(textView As VisualStudio.Text.Editor.ITextView) As Boolean Implements IAsyncQuickInfoBroker.IsQuickInfoActive
Return False
End Function

Public Function TriggerQuickInfoAsync(textView As VisualStudio.Text.Editor.ITextView, Optional triggerPoint As VisualStudio.Text.ITrackingPoint = Nothing, Optional options As QuickInfoSessionOptions = QuickInfoSessionOptions.None, Optional cancellationToken As CancellationToken = Nothing) As Task(Of IAsyncQuickInfoSession) Implements IAsyncQuickInfoBroker.TriggerQuickInfoAsync
Throw New NotImplementedException()
End Function

Public Function GetQuickInfoItemsAsync(textView As VisualStudio.Text.Editor.ITextView, triggerPoint As VisualStudio.Text.ITrackingPoint, cancellationToken As CancellationToken) As Task(Of QuickInfoItemsCollection) Implements IAsyncQuickInfoBroker.GetQuickInfoItemsAsync
Throw New NotImplementedException()
End Function

Public Function GetSession(textView As VisualStudio.Text.Editor.ITextView) As IAsyncQuickInfoSession Implements IAsyncQuickInfoBroker.GetSession
Return Session
End Function

Public Class TestSession
Implements IAsyncQuickInfoSession

Public Dismissed As Boolean = False

Public ReadOnly Property ApplicableToSpan As VisualStudio.Text.ITrackingSpan Implements IAsyncQuickInfoSession.ApplicableToSpan
Get
Throw New NotImplementedException()
End Get
End Property

Public ReadOnly Property Content As IEnumerable(Of Object) Implements IAsyncQuickInfoSession.Content
Get
Throw New NotImplementedException()
End Get
End Property

Public ReadOnly Property HasInteractiveContent As Boolean Implements IAsyncQuickInfoSession.HasInteractiveContent
Get
Throw New NotImplementedException()
End Get
End Property

Public ReadOnly Property Options As QuickInfoSessionOptions Implements IAsyncQuickInfoSession.Options
Get
Throw New NotImplementedException()
End Get
End Property

Public ReadOnly Property State As QuickInfoSessionState Implements IAsyncQuickInfoSession.State
Get
Throw New NotImplementedException()
End Get
End Property

Public ReadOnly Property TextView As VisualStudio.Text.Editor.ITextView Implements IAsyncQuickInfoSession.TextView
Get
Throw New NotImplementedException()
End Get
End Property

Public ReadOnly Property Properties As PropertyCollection Implements IPropertyOwner.Properties
Get
Throw New NotImplementedException()
End Get
End Property

Public Event StateChanged As EventHandler(Of QuickInfoSessionStateChangedEventArgs) Implements IAsyncQuickInfoSession.StateChanged

Public Function GetTriggerPoint(textBuffer As VisualStudio.Text.ITextBuffer) As VisualStudio.Text.ITrackingPoint Implements IAsyncQuickInfoSession.GetTriggerPoint
Throw New NotImplementedException()
End Function

Public Function GetTriggerPoint(snapshot As VisualStudio.Text.ITextSnapshot) As VisualStudio.Text.SnapshotPoint? Implements IAsyncQuickInfoSession.GetTriggerPoint
Throw New NotImplementedException()
End Function

Public Function DismissAsync() As Task Implements IAsyncQuickInfoSession.DismissAsync
Dismissed = True

Return Task.CompletedTask
End Function
End Class
End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ internal static class FeatureAttribute
public const string InlineDiagnostics = nameof(InlineDiagnostics);
public const string InheritanceMargin = nameof(InheritanceMargin);
public const string InlineHints = nameof(InlineHints);
public const string InlineRenameFlyout = nameof(InlineRenameFlyout);
public const string InteractiveEvaluator = nameof(InteractiveEvaluator);
public const string KeywordHighlighting = nameof(KeywordHighlighting);
public const string LibraryManager = nameof(LibraryManager);
Expand Down

0 comments on commit 2a9812e

Please sign in to comment.