I’m currently writing an application on the ESP32 and using LVGL to drive a display. One feature of the application is to have a button press cause the application to cycle between two modes and the screen updates to reflect a different positioning of objects/values based on the mode. The way I structured the application was to create all of my objects at the start of the application and store them in an array and then when cycling between modes, call lv_obj_set_hidden() for every object in the array before drawing new values on the screen. For some reason, this doesn’t work consistently.
Say you’re going from mode 1 to mode 2. A loop sets all objects in the array to hidden. Objects that are displayed in mode 1 and have now been set to hidden are still shown on the screen in mode 2. Just to make sure that there wasn’t some weird race condition occurring in my application, as new values were being displayed in the new mode, I manually called lv_obj_set_hidden() on one of the objects that doesn’t disappear. It remained on the screen.
Going back to mode 1 will then “un-hide” this object because new values are being printed with it and if I go back to mode 2, there’s a 50/50 chance that it will actually become hidden or just stay there again. This effect is observable with objects from either mode remaining on the new mode’s screen (ie. mode 1 → mode 2 or mode 2 → mode 1).
My best guess here is that when lv_obj_set_hidden is called, LVGL somehow misses it but still marks it as hidden? Without knowing how the invalidation process works, that assumption might make no sense. I’m struggling to find anything wrong with the actual application however.
If this isn’t enough information to do anything useful with, let me know. Unfortunately this isn’t a project that I can disclose much information on.
EDIT: I was able to confirm the following behavior:
- I press the button to go from mode 1 to mode 2
- All values are set to hidden in the object array
- When values are shown in mode 2, I manually set one value from mode 1 to not be hidden again and then re-hide it ~25ms later. This value is reliably hidden.
Switching back to manually hiding it in mode 2 and not attempting to “unhide” it first, results in the value remaining in the background. So for some reason LVGL believes this value is hidden without actually removing it from the screen. Manually un-hiding it and then hiding it again seems to trigger a proper invalidation. This isn’t a workaround I can use in production however.