Top Layer Not rendering completely

I’m having difficulty to get a lv_obj that is in the top_layer, to render properly every time it’s flag changes from hidden to visible.
Environment: ESP-IDF, ESP32S3, VSCodeInsiders, lvgl 8.3.0 via idf_components.yml
The object is set up as follows.

   * @brief Modal trays container
  trays_cont = lv_obj_create(lv_layer_top());
  lv_obj_add_flag(trays_cont, LV_OBJ_FLAG_HIDDEN); /* set invisible till required.*/
  lv_obj_set_size(trays_cont, LV_HOR_RES, LV_VER_RES);
  lv_obj_set_scrollbar_mode(trays_cont, LV_SCROLLBAR_MODE_OFF);

  lv_obj_t *trays_label = lv_label_create(trays_cont);
  lv_label_set_text(trays_label, "Enter Nr of Trays");
  lv_obj_align(trays_label, LV_ALIGN_TOP_MID, 0, 0);

  /*trays_ta */
  trays_ta = lv_textarea_create(trays_cont);
  lv_textarea_set_one_line(trays_ta, true);
  lv_textarea_set_text(trays_ta, itoa(packhouse_scale_data->ph_scale_last_units_packaging, trays, 10));
  lv_obj_align_to(trays_ta, trays_label, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
  /*bmatrix */
  lv_obj_t *bmatrix = lv_btnmatrix_create(trays_cont);
  lv_btnmatrix_set_map(bmatrix, btnm_map);
  lv_obj_set_size(bmatrix, 230, 230);
  lv_obj_align_to(bmatrix, trays_ta, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
  lv_btnmatrix_set_btn_ctrl(bmatrix, 12, LV_BTNMATRIX_CTRL_CHECKED);
  lv_obj_add_event_cb(bmatrix, mb_event_cb, LV_EVENT_ALL, NULL);

So when I have the need for this modal keypad (top layer screen), I set the flag to invisible.

lv_obj_clear_flag(trays_cont, LV_OBJ_FLAG_HIDDEN); /* make visible now */

50% of the time it renders properly, with the entire screen taken up with the modal screen.
Other times, it is only partially rendered, and the main screen still visible in the background, with only part of the keypad rendered. It’s as if LVGL doesn’t finish rendering the entire screen.

It also allows you to scroll the top layer screen in spite of the flag being set for no scroll, with this line of code:

 lv_obj_set_scrollbar_mode(trays_cont, LV_SCROLLBAR_MODE_OFF);

I will appreciate any advice on how to fix this reliably.


I added this to your code to reproduce the issue, but works well for me:

void tray_hide_timer(lv_timer_t * t)
    lv_obj_t * cont = t->user_data;

    if(lv_obj_has_flag(cont, LV_OBJ_FLAG_HIDDEN)) lv_obj_clear_flag(cont, LV_OBJ_FLAG_HIDDEN);
    else lv_obj_add_flag(cont, LV_OBJ_FLAG_HIDDEN);

   ...your code...
    lv_timer_create(tray_hide_timer, 500, trays_cont);

Can you send a screenshot about the broken state?

@kisvegabor Here follows the image.

Thx for looking into the problem

This is what I was expecting.

This screen is also scrollable, and I thought it wouldn’t be.

lv_obj_set_scrollbar_mode(trays_cont, LV_SCROLLBAR_MODE_OFF);


lv_obj_set_scrollbar_mode(lv_layer_top(), LV_SCROLLBAR_MODE_OFF);

Apologies for the poor image quality.

Does it make any difference if you call lv_obj_invalidate(lv_scr_act()) after changing the hidden flag?

I will try that, but cannot for the next few hours.

1 Like

Sorry for taking so long to get back on this one.
I had to move my entire code to ESP-IDF master, so V5
This resulted in many compiler errors and low level changes, all very positive, so quite happy with the end result.

I was getting issues again, so I applied your recommended fix, and can confirm that it works most of the time, but I still get an incomplete draw every once in a while. I’m also getting a new error that crashes the device

assert failed: panel_io_i80_tx_color esp_lcd_panel_io_i80.c:434 (color_size <= (bus->num_dma_nodes * DMA_DESCRIPTOR_BUFFER_MAX_SIZE) && “color bytes too long, enlarge max_transfer_bytes”)

every once in a while after closing the ‘modal screen’

It seems like an ESP related issue . :frowning: