Browse Source

Fixed forum-7725: A zombie caret stays visible when closing a code completion dropdown with Esc.

The caret was sometimes updated in OnPaint, which is invalid (Windows temporarily disables carets during WM_PAINT)

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3054 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
9cdbc0f174
  1. 4
      src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlEditorControl.cs
  2. 84
      src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/Caret.cs
  3. 12
      src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs
  4. 3
      src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs

4
src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlEditorControl.cs

@ -321,7 +321,7 @@ namespace ICSharpCode.XmlEditor @@ -321,7 +321,7 @@ namespace ICSharpCode.XmlEditor
/// </remarks>
void InsertCharacter(char ch)
{
ActiveTextAreaControl.TextArea.MotherTextEditorControl.BeginUpdate();
ActiveTextAreaControl.TextArea.BeginUpdate();
Document.UndoStack.StartUndoGroup();
switch (ActiveTextAreaControl.TextArea.Caret.CaretMode)
@ -336,7 +336,7 @@ namespace ICSharpCode.XmlEditor @@ -336,7 +336,7 @@ namespace ICSharpCode.XmlEditor
int currentLineNr = ActiveTextAreaControl.TextArea.Caret.Line;
Document.FormattingStrategy.FormatLine(ActiveTextAreaControl.TextArea, currentLineNr, Document.PositionToOffset(ActiveTextAreaControl.TextArea.Caret.Position), ch);
ActiveTextAreaControl.TextArea.MotherTextEditorControl.EndUpdate();
ActiveTextAreaControl.TextArea.EndUpdate();
Document.UndoStack.EndUndoGroup();
}

84
src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/Caret.cs

@ -179,6 +179,7 @@ namespace ICSharpCode.TextEditor @@ -179,6 +179,7 @@ namespace ICSharpCode.TextEditor
public void RecreateCaret()
{
Log("RecreateCaret");
DisposeCaret();
if (!hidden) {
CreateCaret();
@ -187,13 +188,16 @@ namespace ICSharpCode.TextEditor @@ -187,13 +188,16 @@ namespace ICSharpCode.TextEditor
void DisposeCaret()
{
caretCreated = false;
HideCaret(textArea.Handle);
DestroyCaret();
if (caretCreated) {
caretCreated = false;
HideCaret(textArea.Handle);
DestroyCaret();
}
}
void GotFocus(object sender, EventArgs e)
{
Log("GotFocus, IsInUpdate=" + textArea.MotherTextEditorControl.IsInUpdate);
hidden = false;
if (!textArea.MotherTextEditorControl.IsInUpdate) {
CreateCaret();
@ -203,7 +207,8 @@ namespace ICSharpCode.TextEditor @@ -203,7 +207,8 @@ namespace ICSharpCode.TextEditor
void LostFocus(object sender, EventArgs e)
{
hidden = true;
Log("LostFocus");
hidden = true;
DisposeCaret();
}
@ -217,8 +222,18 @@ namespace ICSharpCode.TextEditor @@ -217,8 +222,18 @@ namespace ICSharpCode.TextEditor
}
}
int oldLine = -1;
bool outstandingUpdate;
internal void OnEndUpdate()
{
if (outstandingUpdate)
UpdateCaretPosition();
}
public void UpdateCaretPosition()
{
Log("UpdateCaretPosition");
if (textArea.MotherTextAreaControl.TextEditorProperties.LineViewerStyle == LineViewerStyle.FullRow && oldLine != line) {
textArea.UpdateLine(oldLine);
textArea.UpdateLine(line);
@ -227,7 +242,10 @@ namespace ICSharpCode.TextEditor @@ -227,7 +242,10 @@ namespace ICSharpCode.TextEditor
if (hidden || textArea.MotherTextEditorControl.IsInUpdate) {
outstandingUpdate = true;
return;
} else {
outstandingUpdate = false;
}
if (!caretCreated) {
CreateCaret();
@ -260,20 +278,58 @@ namespace ICSharpCode.TextEditor @@ -260,20 +278,58 @@ namespace ICSharpCode.TextEditor
}
#region Native caret functions
[DllImport("User32.dll")]
static extern bool CreateCaret(IntPtr hWnd, int hBitmap, int nWidth, int nHeight);
static bool CreateCaret(IntPtr hWnd, int hBitmap, int nWidth, int nHeight)
{
Log("CreateCaret(...)");
return NativeMethods.CreateCaret(hWnd, hBitmap, nWidth, nHeight);
}
static bool SetCaretPos(int x, int y)
{
Log("SetCaretPos(x=" + x + ", y=" + y + ")");
return NativeMethods.SetCaretPos(x, y);
}
[DllImport("User32.dll")]
static extern bool SetCaretPos(int x, int y);
static bool DestroyCaret()
{
Log("DestroyCaret()");
return NativeMethods.DestroyCaret();
}
[DllImport("User32.dll")]
static extern bool DestroyCaret();
static bool ShowCaret(IntPtr hWnd)
{
Log("ShowCaret()");
return NativeMethods.ShowCaret(hWnd);
}
[DllImport("User32.dll")]
static extern bool ShowCaret(IntPtr hWnd);
static bool HideCaret(IntPtr hWnd)
{
Log("HideCaret()");
return NativeMethods.HideCaret(hWnd);
}
[DllImport("User32.dll")]
static extern bool HideCaret(IntPtr hWnd);
[System.Diagnostics.Conditional("DEBUG")]
static void Log(string text)
{
//Console.WriteLine("Caret: " + text);
}
static class NativeMethods {
[DllImport("User32.dll")]
internal static extern bool CreateCaret(IntPtr hWnd, int hBitmap, int nWidth, int nHeight);
[DllImport("User32.dll")]
internal static extern bool SetCaretPos(int x, int y);
[DllImport("User32.dll")]
internal static extern bool DestroyCaret();
[DllImport("User32.dll")]
internal static extern bool ShowCaret(IntPtr hWnd);
[DllImport("User32.dll")]
internal static extern bool HideCaret(IntPtr hWnd);
}
#endregion
bool firePositionChangedAfterUpdateEnd;

12
src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs

@ -542,7 +542,8 @@ namespace ICSharpCode.TextEditor @@ -542,7 +542,8 @@ namespace ICSharpCode.TextEditor
this.motherTextAreaControl.AdjustScrollBars();
}
Caret.UpdateCaretPosition();
// we cannot update the caret position here, it's not allowed to call the caret API inside WM_PAINT
//Caret.UpdateCaretPosition();
base.OnPaint(e);
}
@ -602,7 +603,7 @@ namespace ICSharpCode.TextEditor @@ -602,7 +603,7 @@ namespace ICSharpCode.TextEditor
}
CloseToolTip();
motherTextEditorControl.BeginUpdate();
BeginUpdate();
Document.UndoStack.StartUndoGroup();
try {
// INSERT char
@ -623,7 +624,7 @@ namespace ICSharpCode.TextEditor @@ -623,7 +624,7 @@ namespace ICSharpCode.TextEditor
int currentLineNr = Caret.Line;
Document.FormattingStrategy.FormatLine(this, currentLineNr, Document.PositionToOffset(Caret.Position), ch);
motherTextEditorControl.EndUpdate();
EndUpdate();
} finally {
Document.UndoStack.EndUndoGroup();
}
@ -673,7 +674,7 @@ namespace ICSharpCode.TextEditor @@ -673,7 +674,7 @@ namespace ICSharpCode.TextEditor
IEditAction action = motherTextEditorControl.GetEditAction(keyData);
AutoClearSelection = true;
if (action != null) {
motherTextEditorControl.BeginUpdate();
BeginUpdate();
try {
lock (Document) {
action.Execute(this);
@ -684,7 +685,7 @@ namespace ICSharpCode.TextEditor @@ -684,7 +685,7 @@ namespace ICSharpCode.TextEditor
}
}
} finally {
motherTextEditorControl.EndUpdate();
EndUpdate();
Caret.UpdateCaretPosition();
}
return true;
@ -716,6 +717,7 @@ namespace ICSharpCode.TextEditor @@ -716,6 +717,7 @@ namespace ICSharpCode.TextEditor
public void EndUpdate()
{
motherTextEditorControl.EndUpdate();
caret.OnEndUpdate();
}
public bool EnableCutOrPaste {

3
src/Main/Base/Project/Src/Services/LanguageBinding/LanguageBindingService.cs

@ -119,16 +119,19 @@ namespace ICSharpCode.SharpDevelop @@ -119,16 +119,19 @@ namespace ICSharpCode.SharpDevelop
try {
newProject = binding.LoadProject(provider, location, title);
} catch (XmlException ex) {
LoggingService.Warn("Project load error", ex);
if (progressMonitor != null) progressMonitor.ShowingDialog = true;
newProject = new UnknownProject(location, title, ex.Message, true);
newProject.TypeGuid = projectTypeGuid;
if (progressMonitor != null) progressMonitor.ShowingDialog = false;
} catch (Microsoft.Build.BuildEngine.InvalidProjectFileException ex) {
LoggingService.Warn("Project load error", ex);
if (progressMonitor != null) progressMonitor.ShowingDialog = true;
newProject = new UnknownProject(location, title, ex.Message, true);
newProject.TypeGuid = projectTypeGuid;
if (progressMonitor != null) progressMonitor.ShowingDialog = false;
} catch (UnauthorizedAccessException ex) {
LoggingService.Warn("Project load error", ex);
if (progressMonitor != null) progressMonitor.ShowingDialog = true;
newProject = new UnknownProject(location, title, ex.Message, true);
newProject.TypeGuid = projectTypeGuid;

Loading…
Cancel
Save