SynEdit: Internal caret (multi caret / custom-color caret) wait for Paint event. Avoid moving/painting the internal caret onto outdated text.

This commit is contained in:
Martin 2022-03-29 14:50:48 +02:00
parent fed01f0513
commit f5e70a4f0b
2 changed files with 26 additions and 1 deletions

View File

@ -2979,6 +2979,7 @@ begin
{$IFDEF VerboseSynEditInvalidate}
DebugLnExit(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self)]);
{$ENDIF}
FScreenCaret.WaitForPaint;
end;
end;
@ -3005,6 +3006,7 @@ begin
{$IFDEF VerboseSynEditInvalidate}
DebugLnExit(['TCustomSynEdit.InvalidateTextLines ',DbgSName(self)]);
{$ENDIF}
FScreenCaret.WaitForPaint;
end;
end;

View File

@ -462,6 +462,7 @@ type
procedure FinishScroll(dx, dy: Integer; const rcScroll, rcClip: TRect; Success: Boolean); virtual;
procedure BeginPaint(rcClip: TRect); virtual;
procedure FinishPaint(rcClip: TRect); virtual;
procedure WaitForPaint; virtual;
public
constructor Create(AHandleOwner: TWinControl; AOwner: TSynEditScreenCaret);
function CreateCaret(w, h: Integer): Boolean; virtual;
@ -515,6 +516,7 @@ type
FState: TPainterStates;
FCanPaint: Boolean;
FInRect: TIsInRectState;
FWaitForPaint: Boolean;
function dbgsIRState(s: TIsInRectState): String;
procedure DoTimer(Sender: TObject);
@ -535,6 +537,7 @@ type
procedure FinishScroll(dx, dy: Integer; const rcScroll, rcClip: TRect; Success: Boolean); override;
procedure BeginPaint(rcClip: TRect); override;
procedure FinishPaint(rcClip: TRect); override;
procedure WaitForPaint; override;
public
destructor Destroy; override;
function CreateCaret(w, h: Integer): Boolean; override;
@ -616,6 +619,7 @@ type
procedure FinishScroll(dx, dy: Integer; const rcScroll, rcClip: TRect; Success: Boolean);
procedure BeginPaint(rcClip: TRect);
procedure FinishPaint(rcClip: TRect);
procedure WaitForPaint;
procedure Lock;
procedure UnLock;
procedure AfterPaintEvent; // next async
@ -3168,6 +3172,11 @@ begin
FInPaint := False;
end;
procedure TSynEditScreenCaretPainter.WaitForPaint;
begin
//
end;
{ TSynEditScreenCaretPainterSystem }
procedure TSynEditScreenCaretPainterSystem.BeginScroll(dx, dy: Integer;
@ -3271,7 +3280,9 @@ var
l: Integer;
am: TAntialiasingMode;
begin
if ForcePaintEvents and (not FInPaint) then begin
if (ForcePaintEvents and (not FInPaint)) or
FWaitForPaint
then begin
Invalidate;
exit;
end;
@ -3476,6 +3487,7 @@ begin
FInRect := IsInRect(rcClip);
FCanPaint := FInRect = irInside;
FWaitForPaint := False;
if (psCleanOld in FState) and not FCanPaint then begin
if IsInRect(rcClip, FOldX, FOldY, FOldW, FOldH) <> irInside then begin
@ -3514,6 +3526,12 @@ begin
FCanPaint := True;
end;
procedure TSynEditScreenCaretPainterInternal.WaitForPaint;
begin
inherited WaitForPaint;
FWaitForPaint := True;
end;
destructor TSynEditScreenCaretPainterInternal.Destroy;
begin
assert(not(FInPaint or FInScroll), 'TSynEditScreenCaretPainterInternal.Destroy: not(FInPaint or FInScroll)');
@ -3653,6 +3671,11 @@ begin
Painter.FinishPaint(rcClip);
end;
procedure TSynEditScreenCaret.WaitForPaint;
begin
FCaretPainter.WaitForPaint;
end;
procedure TSynEditScreenCaret.Hide;
begin
HideCaret;