It all seemed to work fine, however I notice that the lv_roller elements in my application are really unresponsive after the LV_OBJ_FLAG_CLICKABLE has been cleared and then added again.
The rollers become “stiff” and do not respond to touches like they should.
Is there something I’m missing here with how the flags function? Please let me know.
I have tried this issue in my side and it works well (in V8.3.2), update version may help you solve this problem. Or you could check the commits between 2 version, I think there’re not many commits since only 2 minor version update.
Turns out this is my own fault, I had created a function to loop through all objects on screen and clear/set all clickable flags, so I could disable background input for a message box. However, it seems that all lv_roller objects also have (at least) 1 child.
Sorry for not properly testing before asking this question.
Setting this CLICKABLE flag on the rollers themselves is fine, but also setting it for the child of every roller seems to break them: it seems this child is in reality responsible for displaying the roller, as hiding it with the HIDDEN flag breaks the roller object in its entirety.
I think this child is of the type lv_roller_label, which is not supposed to have the CLICKABLE flag enabled, I suppose being able to click the label causes the roller to not work properly but I am not certain. Perhaps @kisvegabor can confirm?
For now I have fixed this by checking the object type with lv_obj_check_type(), if that object happens to be of type lv_rolller, I just do not change any flags. This works fine.
How about this for a solution. This is what I call “thinking outside the box”
When you are going to make a message box create an object that is the entire size of the display. set it as the top most object. clear the clickable flag and set all colors to have an opacity of 0. then create the message box on top of that object.
The “transparent” display sized object will consume all clicks except for the clicks that need to be seen by the message box. When the message box gets closed you can delete the object. Another option depending on how often message boxes appear is create the transparent object on program startup and set the hidden flag. when you want to put a message box up clear the hidden flag and set it as the topmost object and then create you message box and set it as the top most object. when box is closed reset the hidden flag. This will keep from creating and deleting objects a bunch of times if you use message boxes a lot in your code.
Just because it cannot be seen with the eyes doesn’t mean it doesn’t exist. I believe this will solve your issue and it does it in a graceful way. Iterating over all of the objects clearing a flag is not ideal as stated above.
I believe because it is completely transparent LVGL is not going to redraw the entire display because of it being added. @kisvegabor would be able to answer that question.
This does indeed also stop inputs from being registered: however, it will still attempt to draw the whole screen (even though the only visible change is the messagebox showing up) when using this method. This means the messagebox (or dialog) takes more than a second to show up. This is quite a bit slower than just disabling all input.
Do I need to change other opacity settings outside of the background?
Maybe that is the issue, if it is, I’ll change that. Otherwise, could you show me the hacky solution?
@kisvegabor said there is a way to stop it from rendering the screen when the transparent object is added. You may have to add the transparent object and stop the rendering from taking place and then add the message box and allow the render to take place.
Your other option which might be an even easier way to go about it is when a message box gets displayed to store the area of the message box in a global and set a flag and in the caallback that handles the touch portion of the display only report touch to LVGL if the touch is inside of that area. That would add the least invasive code to LVGL. It would be instant and you would not need to to do anything special in LVGL to handle this…
There is a callback that exists that gets set to the indev driver. If that caallback is being provided by a library then you can store the callback into a global and create a new callback and set that to the indev. Call the stored callback in the one you created to get the touch data and modify that touch data as needed to handle a message box being displayed.