From 3bd5433f4145a61bb1cf59de1e021ae9dd1d126c Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 5 Nov 2009 22:19:32 +0000 Subject: [PATCH] Avoid stack overflow in custom command routing (r5213), e.g. when scrolling in the quick class browser dropdown. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5219 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Gui/Workbench/Layouts/AvalonDockLayout.cs | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs index 2ef9eaf48f..fc3a74b50c 100644 --- a/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs +++ b/src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs @@ -129,7 +129,9 @@ namespace ICSharpCode.SharpDevelop.Gui CommandManager.RemoveCanExecuteHandler(this.workbench, OnCanExecuteRoutedCommand); CommandManager.RemoveExecutedHandler(this.workbench, OnExecuteRoutedCommand); } - + + bool isInNestedCanExecute; + // Custom command routing: // if the command isn't handled on the current focus, try to execute it on the focus inside the active workbench window void OnCanExecuteRoutedCommand(object sender, CanExecuteRoutedEventArgs e) @@ -137,24 +139,36 @@ namespace ICSharpCode.SharpDevelop.Gui workbench.VerifyAccess(); RoutedCommand routedCommand = e.Command as RoutedCommand; AvalonWorkbenchWindow workbenchWindow = ActiveWorkbenchWindow as AvalonWorkbenchWindow; - if (!e.Handled && routedCommand != null && workbenchWindow != null) { + if (!e.Handled && routedCommand != null && workbenchWindow != null && !isInNestedCanExecute) { IInputElement target = CustomFocusManager.GetFocusedChild(workbenchWindow); if (target != null && target != e.OriginalSource) { - e.CanExecute = routedCommand.CanExecute(e.Parameter, target); + isInNestedCanExecute = true; + try { + e.CanExecute = routedCommand.CanExecute(e.Parameter, target); + } finally { + isInNestedCanExecute = false; + } e.Handled = true; } } } + + bool isInNestedExecute; void OnExecuteRoutedCommand(object sender, ExecutedRoutedEventArgs e) { workbench.VerifyAccess(); RoutedCommand routedCommand = e.Command as RoutedCommand; AvalonWorkbenchWindow workbenchWindow = ActiveWorkbenchWindow as AvalonWorkbenchWindow; - if (!e.Handled && routedCommand != null && workbenchWindow != null) { + if (!e.Handled && routedCommand != null && workbenchWindow != null && !isInNestedExecute) { IInputElement target = CustomFocusManager.GetFocusedChild(workbenchWindow); if (target != null && target != e.OriginalSource) { - routedCommand.Execute(e.Parameter, target); + isInNestedExecute = true; + try { + routedCommand.Execute(e.Parameter, target); + } finally { + isInNestedExecute = false; + } e.Handled = true; } }