CudaText icon indicating copy to clipboard operation
CudaText copied to clipboard

macOS caret glitches

Open Alexey-T opened this issue 3 years ago • 28 comments

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

Alexey-T avatar Jul 29 '22 11:07 Alexey-T

I think this bug is not present in a regular SynEdit.

veksha avatar Jul 30 '22 17:07 veksha

@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; 
  1. try to change last 'false' to 'true'.

Alexey-T avatar Jul 30 '22 19:07 Alexey-T

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.

veksha avatar Jul 31 '22 12:07 veksha

the video was made before the InflateRect change, yes?

Alexey-T avatar Jul 31 '22 12:07 Alexey-T

yes. I have executed old binary to check. blinking with InflateRect is fine. (only caret width is weird)

veksha avatar Jul 31 '22 12:07 veksha

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};

Alexey-T avatar Jul 31 '22 12:07 Alexey-T

 C.Pen.Width:= R.Width;

Peek 2022-07-31 16-24.webm

veksha avatar Jul 31 '22 13:07 veksha

C.Pen.Width:= R.Width {$ifdef darwin} -1 {$endif};

Peek 2022-07-31 16-30.webm

veksha avatar Jul 31 '22 13:07 veksha

on linux it grows by pixel every time. on mac, as you can see, only on even numbers

veksha avatar Jul 31 '22 13:07 veksha

So "-1" did not help with caret shape.

Alexey-T avatar Jul 31 '22 14:07 Alexey-T

applied the "InflateRect" change (atsynedit) - it least it blinks better?

Alexey-T avatar Jul 31 '22 14:07 Alexey-T

yes. it blinks OK. but caret width has some calculation error on Mac.

veksha avatar Jul 31 '22 15:07 veksha

image image image

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.

veksha avatar Jul 31 '22 15:07 veksha

Tks, I added IFNDEF for the AntiAliasing line.

Alexey-T avatar Jul 31 '22 15:07 Alexey-T

wait. this is not a real fix. antialiased caret just showed us that pen width is different indeed. it must work without antialiasing too.

veksha avatar Jul 31 '22 16:07 veksha

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?

veksha avatar Jul 31 '22 16:07 veksha

I can paint only in OnPaint event, hmm..

veksha avatar Jul 31 '22 16:07 veksha

  • 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;   

Alexey-T avatar Jul 31 '22 16:07 Alexey-T

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:

Peek 2022-07-31 19-51.webm

Linux:

Peek 2022-07-31 19-54.webm

veksha avatar Jul 31 '22 17:07 veksha

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.

veksha avatar Jul 31 '22 17:07 veksha

Maybe you should use rectangle, not pen for caret?

veksha avatar Jul 31 '22 17:07 veksha

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.

Alexey-T avatar Jul 31 '22 17:07 Alexey-T

(Rectangle paints as fixed filled area. we need inversion of old area!)

Alexey-T avatar Jul 31 '22 17:07 Alexey-T

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:

Peek 2022-07-31 20-20.webm

Mac:

Peek 2022-07-31 20-24.webm

veksha avatar Jul 31 '22 17:07 veksha

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

Alexey-T avatar Jul 31 '22 17:07 Alexey-T

done: https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/39841

veksha avatar Jul 31 '22 18:07 veksha

@skalogryz, please see? Thanks. ~~@veksha Need to specify the 'widgetset' - old one (unused now) is Carbon, new - Cocoa~~

Alexey-T avatar Jul 31 '22 18:07 Alexey-T

@veksha the related Cud issue about macOS caret was closed, do we need this one?

Alexey-T avatar Nov 24 '22 08:11 Alexey-T

i'm not using macos, if no one notices caret width problem on their monitors then we don't need to fix this.

veksha avatar Nov 24 '22 13:11 veksha