Open MewPurPur opened 4 months ago
I believe that to solve this, we need to make it so the caret drawing logic and the logic for this method are 100% unified. In fact, once we do this, we can get make it so caret blinking doesn't redraw the whole TextEdit, which would be a huge win for battery life.
It seems that TextEdit.get_caret_draw_pos()
is only updated when it is drawn.
Try using get_rect_at_line_column()
or get_pos_at_line_column()
with the caret position.
If that's intentional, it needs to be documented. If that's not intentional, welp.
Looks like it is intentional that it stays at the last visible position. It is used for code hint, IME, and some context menus, which need a valid position even if the caret gets clipped. We could probably change the behavior for empty lines and resizing, but the last visible position part should be documented.
What's IME or code hint? I don't follow. Anyway, I find this behavior very weird and unlikely to make sense for anything.
If you disable smooth scrolling, you can scroll 3 lines at a time by default, making the drawing position land several rows under. In fact, if you use the scrollbar to move to a completely different spot instantaneously, this doesn't update either, so it can be some random spot on the screen.
If you have a visible caret, then scroll to the left, clipping it, then scroll above it, then scroll to the right, the draw position reported will still be at the left edge, even though the caret is now below.
Whatever this function is supposed to achieve, it's very weird and messed up. Wouldn't it make more sense to fix this function like I suggested and clamp the draw position instead - perhaps even doing so in a dedicated method?
IME is Input Method Editor, something that's REQUIRED for people to input Chinese, Korean, Japanese and some other more complex writing systems.
Code hint I'm not certain what they refer to
It seems that
TextEdit.get_caret_draw_pos()
is only updated when it is drawn. Try usingget_rect_at_line_column()
orget_pos_at_line_column()
with the caret position.
By the way I tried this and it's good for my use case. Needs a bit of adjustment and it messes up with ligatures, but that's not so hard to workaround.
These methods have been much more reliable, but even they fail in some situations, see the caret in this screenshot. I have grievances especially with scrolling, which seems to update too late. I'll see if I can report this separately.
when the window is resized
I realized that it has to do with the TextEdit resizing while staying focused - and the workaround also has the issue
Tested versions
4.2.1
System information
Godot v4.2.1.stable - Pop!_OS 22.04 LTS - X11 - Vulkan (Forward+) - integrated Intel(R) Graphics (ADL GT2) () - 12th Gen Intel(R) Core(TM) i5-1235U (12 Threads)
Issue description
My expectation is that
TextEdit.get_caret_draw_pos()
is a function I can use to consistently predict where a caret should be drawn, and to draw my own things there. But it's entirely unreliable and fails when the draw position is clipped, when the window is resized, and for empty lines, and probably other things I've yet to discover.https://github.com/godotengine/godot/assets/85438892/17ef3714-5680-4334-8bc7-50c8ada3119d
Related: #65981
Steps to reproduce
There's a MRP. But basically, add a TextEdit, then add a script to make it draw a circle at the caret pos, then try all the stuff I showed in the video above.
Minimal reproduction project (MRP)
TextEdit bug.zip