diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaClipboardHandler.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaClipboardHandler.cs index 5b035388cf..47e1c9af9d 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaClipboardHandler.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaClipboardHandler.cs @@ -32,14 +32,33 @@ namespace ICSharpCode.TextEditor } } + public delegate bool ClipboardContainsTextDelegate(); + + /// + /// Is called when CachedClipboardContainsText should be updated. + /// If this property is null (the default value), the text editor uses + /// System.Windows.Forms.Clipboard.ContainsText. + /// + /// + /// This property is useful if you want to prevent the default Clipboard.ContainsText + /// behaviour that waits for the clipboard to be available - the clipboard might + /// never become available if it is owned by a process that is paused by the debugger. + /// + public static ClipboardContainsTextDelegate GetClipboardContainsText; + public bool EnablePaste { get { if (!textArea.EnableCutOrPaste) return false; - try { - return Clipboard.ContainsText(); - } catch (ExternalException) { - return false; + ClipboardContainsTextDelegate d = GetClipboardContainsText; + if (d != null) { + return d(); + } else { + try { + return Clipboard.ContainsText(); + } catch (ExternalException) { + return false; + } } } } diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 8d5bf9644d..00cebf1b63 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -473,6 +473,7 @@ + diff --git a/src/Main/Base/Project/Src/Commands/EditCommands.cs b/src/Main/Base/Project/Src/Commands/EditCommands.cs index 8ff4b2906f..6c9ae8279e 100644 --- a/src/Main/Base/Project/Src/Commands/EditCommands.cs +++ b/src/Main/Base/Project/Src/Commands/EditCommands.cs @@ -5,6 +5,7 @@ // $Revision$ // +using ICSharpCode.SharpDevelop.DefaultEditor; using System; using System.Windows.Forms; using ICSharpCode.Core; @@ -122,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Commands get { return comboBox.SelectionLength > 0; } } public bool EnablePaste { - get { return ClipboardWrapper.ContainsText; } + get { return ClipboardHandling.GetClipboardContainsText(); } } public bool EnableDelete { get { return true; } diff --git a/src/Main/Base/Project/Src/TextEditor/ClipboardHandling.cs b/src/Main/Base/Project/Src/TextEditor/ClipboardHandling.cs new file mode 100644 index 0000000000..401125ed27 --- /dev/null +++ b/src/Main/Base/Project/Src/TextEditor/ClipboardHandling.cs @@ -0,0 +1,67 @@ +// +// +// +// +// $Revision$ +// + +using ICSharpCode.Core.WinForms; +using System; +using System.Threading; +using ICSharpCode.SharpDevelop.Gui; + +namespace ICSharpCode.SharpDevelop.DefaultEditor +{ + /// + /// This class fixes SD2-1466: SharpDevelop freezes when debugged application sets clipboard text. + /// The problem is that Clipboard.ContainsText may wait for the application owning the clipboard, + /// which in turn may currently wait for SharpDevelop (through the debugger) + /// + static class ClipboardHandling + { + public static void Initialize() + { + ICSharpCode.TextEditor.TextAreaClipboardHandler.GetClipboardContainsText = GetClipboardContainsText; + WorkbenchSingleton.MainForm.Activated += WorkbenchSingleton_MainForm_Activated; + } + + static void WorkbenchSingleton_MainForm_Activated(object sender, EventArgs e) + { + UpdateClipboardContainsText(); + } + + static bool clipboardContainsText; + + public static bool GetClipboardContainsText() + { + WorkbenchSingleton.DebugAssertMainThread(); + if (WorkbenchSingleton.Workbench.IsActiveWindow) { + UpdateClipboardContainsText(); + } + return clipboardContainsText; + } + + static Thread updateThread; + + static void UpdateClipboardContainsText() + { + if (updateThread != null) + return; + Thread t = new Thread(new ThreadStart(DoUpdate)); + t.SetApartmentState(ApartmentState.STA); + t.IsBackground = true; + updateThread = t; + t.Start(); + t.Join(50); // wait a few ms in case the clipboard can be accessed without problems + } + + static void DoUpdate() + { + try { + clipboardContainsText = ClipboardWrapper.ContainsText; + } finally { + updateThread = null; + } + } + } +} diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs index ff8a0e0cca..371a881b76 100644 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs @@ -33,6 +33,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor HighlightingManager.Manager.AddSyntaxModeFileProvider(new ICSharpCode.SharpDevelop.DefaultEditor.Codons.AddInTreeSyntaxModeProvider()); HighlightingManager.Manager.AddSyntaxModeFileProvider(new FileSyntaxModeProvider(Path.Combine(PropertyService.DataDirectory, "modes"))); HighlightingManager.Manager.AddSyntaxModeFileProvider(new FileSyntaxModeProvider(modeDir)); + ClipboardHandling.Initialize(); } ///