Merged revision(s) 59584 #e5a2420d88, 59596 #f435a9dc89 from trunk:

SynEdit: fix caret blinking during code-completion drop down, if persistent-caret-is-none-blinking
........
SynEdit: (Win10 issue only) fix for "ghost" images of text-caret on Windows 10, in certain conditions where part of the editor is outside the physical screen.
........

git-svn-id: branches/fixes_2_0@59629 -
This commit is contained in:
maxim 2018-11-22 22:21:36 +00:00
parent 50a5e72bfa
commit 99a67d1fdb
2 changed files with 43 additions and 4 deletions

View File

@ -264,7 +264,7 @@ type
private
FAutoUseSingleIdent: Boolean;
Form: TSynBaseCompletionForm;
FAddedPersistentCaret: boolean;
FAddedPersistentCaret, FChangedNoneBlink: boolean;
FOnExecute: TNotifyEvent;
FWidth: Integer;
function GetCaseSensitive: boolean;
@ -1458,6 +1458,7 @@ begin
//Todo: This is dangerous, if other plugins also change/changed the flag.
FAddedPersistentCaret := False;
FChangedNoneBlink := False;
CurrentString := s;
if Assigned(OnExecute) then
@ -1474,8 +1475,11 @@ begin
if (Form.CurrentEditor is TCustomSynEdit) then begin
CurSynEdit:=TCustomSynEdit(Form.CurrentEditor);
FAddedPersistentCaret := not(eoPersistentCaret in CurSynEdit.Options);
FChangedNoneBlink := (eoPersistentCaretStopBlink in CurSynEdit.Options2);
if FAddedPersistentCaret then
CurSynEdit.Options:=CurSynEdit.Options+[eoPersistentCaret];
if FChangedNoneBlink then
CurSynEdit.Options2:=CurSynEdit.Options2-[eoPersistentCaretStopBlink];
end;
Form.SetBounds(x,y,Form.Width,Form.Height);
Form.Show;
@ -1713,11 +1717,13 @@ procedure TSynBaseCompletion.Deactivate;
var
CurSynEdit: TCustomSynEdit;
begin
if FAddedPersistentCaret and
(Form<>nil) and (Form.CurrentEditor is TCustomSynEdit)
if (Form<>nil) and (Form.CurrentEditor is TCustomSynEdit)
then begin
CurSynEdit:=TCustomSynEdit(Form.CurrentEditor);
CurSynEdit.Options:=CurSynEdit.Options-[eoPersistentCaret];
if FAddedPersistentCaret then
CurSynEdit.Options:=CurSynEdit.Options-[eoPersistentCaret];
if FChangedNoneBlink then
CurSynEdit.Options2:=CurSynEdit.Options2+[eoPersistentCaretStopBlink];
end;
if Assigned(Form) then Form.Deactivate;
end;

View File

@ -61,6 +61,35 @@ unit SynEdit;
// gtk2.12 paints faster directly
{$ENDIF}
{$IFDEF Windows}
(* * On Windows 10 there is an issue, where under certain conditions a "ghost" of the text caret remains visible.
That is one or a series of vertical black lines remain on the screen.
* This can be reproduced, by moving part (eg bottom) of editor off screen (not just behind the taskbar, but
off screen). Then press caret down to scroll. Ghost carets will scroll in with the new text.
Similar move caret to a place off-screen, unfocus editor, and refocus by clicking into the editor (move caret
while setting focus).
To reproduce, the editor must have a visible gutter; and must not have "current line" highlight.
* The conditions to cause this:
- Caret must be in part of editor that is outside the screen.
- Carte must be destroyed (maybe only hidden?), or ScrollWindowEx must affect caret
- Caret must be in a part of the editor for which NO call to "invalidate" was made,
but which will be repainted.
E.g. the gutter, but not the line area received an invalidate, and another line above/below was invalidated
(can happen through ScrollWindowEx). -> In this case the paint message receives a rect, that contains the caret,
even though the part containing the caret was never explicitly invalidated.
If this happens, while the caret is on screen (even if hidden behind another window/taskbar) then all works ok.
But if the caret was off screen, a permanent image of the caret will remain (once scrolled/moved into the screen area).
It seem that in this case windows does not update the information, that the caret became "invisible" when paint did paint
over it. So if the already overpainted caret, is later (by Windows) attempted to be hidden by a final "xor", then it actually
is made permanently visible.
As a solution, in the above conditions, the full line (actually the text part with the caret) must be invalidated too.
Since this is hard to track, the workaround will invalidate the full line, in any case that potentially could meet the
conditions
*)
{$DEFINE Windows10GhostCaretIssue}
{$ENDIF}
interface
{ $DEFINE SYNSCROLLDEBUG}
@ -2823,6 +2852,10 @@ begin
{$IFDEF VerboseSynEditInvalidate}
DebugLnEnter(['TCustomSynEdit.InvalidateGutterLines ',DbgSName(self), ' FirstLine=',FirstLine, ' LastLine=',LastLine]);
{$ENDIF}
{$IFDEF Windows10GhostCaretIssue}
if (FLeftGutter.Visible or FRightGutter.Visible) and (sfCaretChanged in fStateFlags) then
InvalidateLines(FirstLine, LastLine);
{$ENDIF}
if (FirstLine = -1) and (LastLine = -1) then begin
FPaintArea.InvalidateGutterLines(-1, -1);
end else begin