Bug at TextArea's lv_ta_get_placeholder_text()


TextArea’s lv_ta_get_placeholder_text() return mistake text.

What MCU/Processor/Board and compiler are you using?

  • ESP32
  • lvgl6.0.2 master

What do you experience?

What do you expect?


const char * lv_ta_get_placeholder_text(lv_obj_t * ta)
    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
    const char * txt = NULL;
    if(ext->placeholder) txt = lv_label_get_text(ext->label);
    return txt;


const char * lv_ta_get_placeholder_text(lv_obj_t * ta)
    lv_ta_ext_t * ext = lv_obj_get_ext_attr(ta);
    const char * txt = NULL;
    if(ext->placeholder) txt = lv_label_get_text(ext->placeholder);
    return txt;

Code to reproduce

Screenshot and/or video

Thanks for reporting this; I’ve fixed it in the master branch, and I will merge that branch into dev-6.1 soon so the fix will be there as well.

1 Like

Merged master into dev-6.1. The bug should be fixed now.

1 Like

( Another issue: … )


When a textarea’s text is set by utf8 upper than 1 byte
such as the textarea is set by 2 chars like this.

lv_ta_set_text( ta, “柔道” );

and then when changing the textarea to password mode by

lv_ta_set_pwd_mode(ta, true);

The textarea will change the text to a string of * for hiding password-text automatically.
However, on the textarea displays mistake length of the string of *
It is shown by ****** ( 6 chars of * ), not by ** (2 chars of *).

What MCU/Processor/Board and compiler are you using?

  • ESP32
  • lvgl 6.0.2 mater

What do you experience?

What do you expect?

After call lv_ta_set_pwd_mode(ta, true);

The text “柔道” should be transformed to ** : 2chars (not ****** : 6 chars).

Code to reproduce

The len at line 655 should come from utf16's strlen() , not from normal strlen() that is utf8’s strlen().

Normal strlen() will return “柔道” to 6 chars.
If transform by utf16's strlen() will return “柔道” to 2 chars.

Maybe should transform by lv_txt_get_encoded_length() ?

Can you send a pull request with the change that you think fixes the issue?

I’ve merged it to ta_placeholder_copy.
I’ve also fixed the copy of ext->pwd_tmp. Can you test it? IF all work we can merge it to master.

1 Like

The last ta_placeholder_copy,
I tried by the following code for creating by copying password-mode textarea.

  lv_obj_t *password_ta = lv_ta_create(lv_scr_act(), NULL);
    lv_ta_set_pwd_mode(password_ta, true);
    lv_ta_set_text(password_ta, "1234567890");
    lv_ta_set_placeholder_text(password_ta, "Password");
    lv_ta_set_one_line(password_ta, true);
    lv_ta_set_cursor_type(password_ta, LV_CURSOR_NONE);
    lv_obj_set_width(password_ta, 240-12);
    lv_obj_align(password_ta, NULL, LV_ALIGN_CENTER,0,0);

  lv_obj_t *password_ta2 = lv_ta_create(lv_scr_act(), password_ta);
    lv_obj_align(password_ta2, password_ta, LV_ALIGN_OUT_BOTTOM_MID, 0,20);

It occurs runtime-error.

When Checking the runtime-error by ESP Exception Decoder tool.

Error at lv_ta.c line 175.

I’ve fixed it. Now it’s working with your code.

1 Like

The lastest ta_placeholder_copy is OK.
Now it’s working, can copying password-mode textarea to another.

Thank you very mush.

Great! I’ve merged it to master and dev-6.1.

I copied the fixes manually because the bugfix branch was based on dev-6.1

I tried to set a copied textarea to a keyboard,
the keyboard can type well, however when touching for changing cursor position , the texterea is freezed.
Can’t type anymore without any error occurs.

As the following video. ( the copied-textarea is freezed at 0:25 )

Code for 2 textareas.

  lv_obj_t* login_ta = lv_ta_create(lv_scr_act(), NULL);
    lv_obj_set_event_cb(login_ta, ta_event_cb);
    lv_obj_align(login_ta, NULL, LV_ALIGN_CENTER, 0, -40);
    lv_ta_set_one_line(login_ta, true);
    lv_ta_set_cursor_type(login_ta, LV_CURSOR_NONE);
    lv_ta_set_text(login_ta, "");
    lv_ta_set_placeholder_text(login_ta, "Login");

  lv_obj_t* pass_ta = lv_ta_create(lv_scr_act(), NULL);
    lv_obj_set_event_cb(pass_ta, ta_event_cb);
    lv_obj_align(pass_ta, login_ta, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
    lv_ta_set_cursor_type(pass_ta, LV_CURSOR_NONE);
    lv_ta_set_text(pass_ta, "");
    lv_ta_set_placeholder_text(pass_ta, "Password");

Code for event_cb

lv_obj_t* kbd_frame        = NULL;    /* keyboard frame  by lv_obj_create() */
lv_obj_t* kbd_kb           = NULL;    /* keyboard's kb   by lv_kb_create() */
lv_obj_t* kbd_ta           = NULL;    /* keyboard's ta   by copying from outside ta */
lv_obj_t* kbd_ta_outside   = NULL;    /* outside-ta that request to edit */

/* event_cb for kbd_kb . Handle for LV_EVENT_APPLY and LV_EVENT_CANCEL only*/
void kbd_kb_event_cb(lv_obj_t* kbd_kb, lv_event_t ev){
  /* by default kb event_cb first */
  lv_kb_def_event_cb(kbd_kb, ev);

  if(ev == LV_EVENT_APPLY){
    Serial.println("On Apply");
    /* set text to outside-ta from kbd_ta's text */
    if( kbd_ta_outside != NULL) 
      lv_ta_set_text( kbd_ta_outside, lv_ta_get_text( lv_kb_get_ta(kbd_kb) ));

    lv_obj_set_hidden(kbd_frame, true);
    lv_kb_set_ta(kbd_kb, NULL);
    kbd_ta_outside = NULL;
  if(ev == LV_EVENT_CANCEL){
    Serial.println("On Cancel");
    lv_obj_set_hidden(kbd_frame, true);
    lv_kb_set_ta(kbd_kb, NULL);
    kbd_ta_outside = NULL;

/* event_cb for outside-ta. Handle for LV_EVENT_CLICK only*/
void ta_event_cb(lv_obj_t* ta, lv_event_t ev ){
  if(ev != LV_EVENT_CLICKED) return;

  /* create keyboard */  
  if( kbd_frame == NULL) {
    kbd_frame = lv_obj_create(lv_scr_act(), NULL);
      lv_obj_set_size(kbd_frame, 240,240);
      kbd_kb = lv_kb_create(kbd_frame, NULL);
        lv_obj_set_size(kbd_kb, 240,180);
        lv_obj_align(kbd_kb, NULL, LV_ALIGN_IN_BOTTOM_MID,0,0);
        lv_obj_set_event_cb(kbd_kb, kbd_kb_event_cb);

  kbd_ta_outside = ta;

  /* delete old kbd_ta */
  if( kbd_ta != NULL) lv_obj_del(kbd_ta); 
  /* create kbd_ta by copying from kbd_ta_outside */
  kbd_ta = lv_ta_create(kbd_frame, kbd_ta_outside);
    lv_ta_set_cursor_type(kbd_ta, LV_CURSOR_LINE);
    lv_obj_align(kbd_ta, NULL, LV_ALIGN_IN_TOP_LEFT, 6,6);
    lv_obj_set_width(kbd_ta, 240-12);

  /* set kbd_ta to kbd_kb */
  lv_kb_set_ta(kbd_kb, kbd_ta);

  /* move to forground and unhide */
  lv_obj_set_hidden(kbd_frame, false);

I’ll check it later today.

I haven’t fully traced issue but it seems the problem is that when you copy the “outside ta” the event callback is also copied. So when you click the copied “inside ta” ta_event_cb is called which messes things up.

This modification in ta_event_cb solved the issue here:

    /* create kbd_ta by copying from kbd_ta_outside */
    kbd_ta = lv_ta_create(kbd_frame, kbd_ta_outside);
    lv_obj_set_event_cb(kbd_ta, NULL);     //Clear the copied event callback
1 Like

Oh, I tried to find the solution many many tests, it doesn’t work.

But by set event_cb to null , it’s work now.
Thank you very much.

You’re welcome!

1 Like