Skip to content

LVGL stalls when trying to resolve circular dependencies between parent with LV_SIZE_CONTENT and child with LV_PCT() #10253

@thofaict

Description

@thofaict

LVGL version

v9.5.0

Platform

  • Embedded Linux platform (ARM) using DRM driver
  • CLI-only Debian VM (x86) using DRM driver

What happened?

Problem statement

In our project, we use a complex combination of different widgets, in which a lot of dependencies between the sizes are defined. When upgrading from LVGL v9.4.0 to v9.5.0, we observed that not all windows in our application could be opened. More specifically, LVGL seemed to be stuck in an endless loop trying to calculate the correct size of certain widgets.

Root-cause

We investigated this issue, and traced back the issue to following commit on the master branch: 2e8b9d0. Before this commit, everything still functions correctly. After this commit, the issue pops up.

Example

I tried to condense the issue to a simple example in the attached code. This example application does not do anything useful except clarifying the issue. The widget that triggers the issue is a textarea widget.

In the example, the issue can be resolved by adding following statement: lv_obj_set_style_min_width(lv_textarea_get_label(ta), 0, 0);, E.G. on line 19. This, however, is contradictory with following statements in lv_textarea_set_one_line():

int32_t min_width_value = en ? lv_pct(100) : 0;
...
lv_obj_set_style_min_width(ta->label, min_width_value, 0);

Expectations

Given the fact that our application, and the example, functions correctly in LVGL v9.4.0, and the fact that #9243 does not mention backwards compatibility being broken, we expected to have the same behavior in LVGL v9.5.0.

How to reproduce?

#include <stdbool.h>
#include <unistd.h>

#include "lvgl/lvgl.h"

int main(void)
{
    lv_init();

    lv_display_t * display = lv_linux_drm_create();
    lv_linux_drm_set_file(display, "/dev/dri/card0", -1);

    lv_obj_t * cont = lv_obj_create(lv_screen_active());
    lv_obj_set_size(cont, LV_SIZE_CONTENT, LV_SIZE_CONTENT);

    lv_obj_t * ta = lv_textarea_create(cont);
    lv_obj_set_width(ta, LV_SIZE_CONTENT);
    lv_textarea_set_one_line(ta, true);
    /**
     * Following function call will never return.  In this specific case,
     * lv_textarea_set_text will execute lv_textarea_set_cursor_pos, which in
     * its turn will execute lv_obj_update_layout.  Here, the execution stalls.
     */
    lv_textarea_set_text(ta, "some random text");

    while(1) {
        lv_timer_handler();
        usleep(5000);
    }

    lv_display_delete(display);
    lv_deinit();

    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions