CudaText
CudaText copied to clipboard
macOS caret glitches
As we can see in #4249 videos, caret is not blinking properly - half of caret line is not erased. seems Lazarus issue. need to find small repro for @skalogryz.
https://user-images.githubusercontent.com/5806694/181679466-68afce4e-e47e-4134-8ca9-9089eb588ccc.mov
I think this bug is not present in a regular SynEdit.
@veksha @jairomartineza
I will be on Mac in two weeks.
maybe try this fix-- file atsynedit/atsynedit.pas,
in the procedure TATSynEdit.DoPaintCarets we have 2 places of
if AWithInvalidate then
InvalidateRect(Handle, @R, false);
try to change it to
if AWithInvalidate then
begin
InflateRect(R, 1, 1);
InvalidateRect(Handle, @R, false);
end;
- try to change last 'false' to 'true'.
InflateRect(R, 1, 1);
this helps with blinking!
but now default caret_view = 2,-100 looks like 3,-100. same. (minor issue)
also I found another bug :+1: :smile:
(it happens with or without InflateRect)
In Options Editor Lite Filter field has no caret until you change focus to another control and back.
the video was made before the InflateRect change, yes?
yes. I have executed old binary to check. blinking with InflateRect is fine. (only caret width is weird)
Okay. let's try another change. file atflatcontrols/atcanvasprimitives.pas,
{$else}
procedure CanvasInvertRect(C: TCanvas; const R: TRect; AColor: TColor);
(2nd variant of procedure!)
change line
C.Pen.Width:= R.Width;
to
C.Pen.Width:= R.Width {$ifdef darwin} -1 {$endif};
on linux it grows by pixel every time. on mac, as you can see, only on even numbers
So "-1" did not help with caret shape.
applied the "InflateRect" change (atsynedit) - it least it blinks better?
yes. it blinks OK. but caret width has some calculation error on Mac.

turned on antialiasing just for fun. and now i see difference between 2 px caret and 3 px caret. (without AA there was no difference)
so maybe calculation is OK, but there is something wrong with pen and canvas interaction.
Tks, I added IFNDEF for the AntiAliasing line.
wait. this is not a real fix. antialiased caret just showed us that pen width is different indeed. it must work without antialiasing too.
i've found your issue: https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/39416 maybe it's related.
I'm trying to reproduce with empty project and standard controls (TPaintBox.Canvas?) but i have little experience, can't draw a single line still. how to paint on PaintBox?? can you teach me?
I can paint only in OnPaint event, hmm..
- new project
- on 'Aditional' tab of IDE, click PaintBox to put it on form
- in Object Inspector for new PaintBox1, find OnPaint, 2-click it
- created new event. fill its handler
{ TForm1 }
procedure TForm1.PaintBox1Paint(Sender: TObject);
var c: TCanvas;
begin
c:= paintbox1.canvas;
c.pen.color:= clred;
c.line(10, 10, 50, 10);
c.brush.color:= clgreen;
c.FillRect(20, 20, 60, 50);
end;
test project: canvaspen.zip
PaintBox1.Canvas.AntialiasingMode:= amOff;
PaintBox1.Canvas.Pen.Width:= w;
PaintBox1.Canvas.MoveTo(100,100);
PaintBox1.Canvas.LineTo(100,200)
button is increasing Pen width by 1.
Mac:
Linux:
I see the difference in growing sides of the line. on Mac sides of the line are growing together on every other click. on Linux they are growning alternately one by one.
Maybe you should use rectangle, not pen for caret?
Maybe you should use rectangle, not pen for caret?
I had problems with it, tried it long time ago.
- pls add
C.Pen.EndCap:= pecFlat; - pls add button to set Pen.Width to some big value (eg 20) and compare results in mac/linux. only then we can see - width is too big or not.
(Rectangle paints as fixed filled area. we need inversion of old area!)
pls add button to set Pen.Width to some big value (eg 20) and compare results in mac/linux. only then we can see - width is too big or not
width are (almost) the same for linux and mac, they are just growing differently. on mac it takes two steps to make pen width grow. to me it seems like a Lazarus bug or something.
If user specifies width = n pixels, he expects to get correct width. exactly n. this is not the case with pen width on mac. you get width 1 for n=1, but you get width 3 for n = 2 and n = 3, you will get width 5 for n = 4 and n = 5. and so on...
Linux:
Mac:
Pls post this message (with the attached demo src) to the Laz bugtracker, it is small issue in Cocoa widgetset https://gitlab.com/groups/freepascal.org/lazarus/-/issues
done: https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/39841
@skalogryz, please see? Thanks. ~~@veksha Need to specify the 'widgetset' - old one (unused now) is Carbon, new - Cocoa~~
@veksha the related Cud issue about macOS caret was closed, do we need this one?
i'm not using macos, if no one notices caret width problem on their monitors then we don't need to fix this.