@@ -180,6 +180,7 @@ internal sealed class GoToDefMouseHandlerProvider : IMouseProcessorProvider
180180 public IMouseProcessor GetAssociatedProcessor ( IWpfTextView view )
181181 {
182182 var buffer = view . TextBuffer ;
183+ IVsUIShell vsUIShell = GetVsUIShell ( ) ;
183184
184185 IOleCommandTarget shellCommandDispatcher = GetShellCommandDispatcher ( view ) ;
185186
@@ -196,6 +197,7 @@ public IMouseProcessor GetAssociatedProcessor(IWpfTextView view)
196197
197198 return new GoToDefMouseHandler ( view ,
198199 shellCommandDispatcher ,
200+ vsUIShell ,
199201 _aggregatorFactory . GetClassifier ( buffer ) ,
200202 _navigatorService . GetTextStructureNavigator ( buffer ) ,
201203 CtrlKeyState . GetStateForView ( view ) ) ;
@@ -211,26 +213,36 @@ private IOleCommandTarget GetShellCommandDispatcher(ITextView view)
211213 return _globalServiceProvider . GetService ( typeof ( SUIHostCommandDispatcher ) ) as IOleCommandTarget ;
212214 }
213215
216+ /// <summary>
217+ /// Get the SVsUIShell from the global service provider.
218+ /// </summary>
219+ private IVsUIShell GetVsUIShell ( )
220+ {
221+ return _globalServiceProvider . GetService ( typeof ( SVsUIShell ) ) as IVsUIShell ;
222+ }
223+
214224 #endregion
215225 }
216226
217- /// <summary>
218- /// Handle ctrl+click on valid elements to send GoToDefinition to the shell. Also handle mouse moves
219- /// (when control is pressed) to highlight references for which GoToDefinition will (likely) be valid.
220- /// </summary>
221- internal sealed class GoToDefMouseHandler : MouseProcessorBase
227+ /// <summary>
228+ /// Handle ctrl+click on valid elements to send GoToDefinition to the shell. Also handle mouse moves
229+ /// (when control is pressed) to highlight references for which GoToDefinition will (likely) be valid.
230+ /// </summary>
231+ internal sealed class GoToDefMouseHandler : MouseProcessorBase
222232 {
223233 private IWpfTextView _view ;
224234 private CtrlKeyState _state ;
225235 private IClassifier _aggregator ;
226236 private ITextStructureNavigator _navigator ;
227237 private IOleCommandTarget _commandTarget ;
238+ private IVsUIShell _vsUIShell ;
228239
229- public GoToDefMouseHandler ( IWpfTextView view , IOleCommandTarget commandTarget ,
240+ public GoToDefMouseHandler ( IWpfTextView view , IOleCommandTarget commandTarget , IVsUIShell vsUIShell ,
230241 IClassifier aggregator , ITextStructureNavigator navigator , CtrlKeyState state )
231242 {
232243 _view = view ;
233244 _commandTarget = commandTarget ;
245+ _vsUIShell = vsUIShell ;
234246 _state = state ;
235247 _aggregator = aggregator ;
236248 _navigator = navigator ;
@@ -315,12 +327,34 @@ public override void PreprocessMouseUp(MouseButtonEventArgs e)
315327 _mouseDownAnchorPoint = null ;
316328 }
317329
330+ // Support backward/forward navigation via extended mouse buttons.
331+ // Derived from https://github.com/tunnelvisionlabs/MouseNavigation/blob/master/Tvl.VisualStudio.MouseNavigation/MouseNavigationProcessor.cs.
332+ public override void PostprocessMouseUp ( MouseButtonEventArgs e )
333+ {
334+ if ( _vsUIShell == null )
335+ return ;
336+
337+ uint cmdId ;
338+ if ( e . ChangedButton == MouseButton . XButton1 )
339+ cmdId = ( uint ) VSConstants . VSStd97CmdID . ShellNavBackward ;
340+ else if ( e . ChangedButton == MouseButton . XButton2 )
341+ cmdId = ( uint ) VSConstants . VSStd97CmdID . ShellNavForward ;
342+ else
343+ return ;
344+
345+ object obj = null ;
346+ _vsUIShell . PostExecCommand ( VSConstants . GUID_VSStandardCommandSet97 , cmdId ,
347+ ( uint ) OLECMDEXECOPT . OLECMDEXECOPT_DONTPROMPTUSER , ref obj ) ;
348+
349+ e . Handled = true ;
350+ }
351+
318352
319- #endregion
353+ #endregion
320354
321- #region Private helpers
355+ #region Private helpers
322356
323- private Point RelativeToView ( Point position )
357+ private Point RelativeToView ( Point position )
324358 {
325359 return new Point ( position . X + _view . ViewportLeft , position . Y + _view . ViewportTop ) ;
326360 }
0 commit comments