How to delete a screen with a modal msgbox active

Description

I have followed the example in the modal msgbox, but when I delete the screen directly, there is a segmentation fault

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

Simulator in CodeBlocks v7-dev

What do you want to achieve?

I would like to be able to delete the a screen in which a modal msgbox has been created an is active

What have you tried so far?

I have copied the example msgbox_2, in which a modal msgbox is created, and then modified it so after activating the modal msgbox a new screen is created, loaded, and the previous is deleted. Then the program asserts a segmentation fault.

I think that the problem is with the lv_obj_del_async, which tries to delete the page in which the msgbox is created. When the msgbox is deleted, then the msgbox delete event deletes the page, but when the screen is deleted, I think that the page is deleted first, and then the delayed deleted is failing. That’s my assumption, but I don’t know a way to overcome this problem.

Code to reproduce

void lv_ex_msgbox_2(void)
{
    lv_style_init(&style_modal);
    lv_style_set_bg_color(&style_modal, LV_STATE_DEFAULT, LV_COLOR_BLACK);

    /* Create a button, then set its position and event callback */
    lv_obj_t *btn = lv_btn_create(lv_scr_act(), NULL);
    lv_obj_set_size(btn, 200, 60);
    lv_obj_set_event_cb(btn, btn_event_cb);
    lv_obj_align(btn, NULL, LV_ALIGN_IN_TOP_LEFT, 20, 20);

    /* Create a label on the button */
    lv_obj_t *label = lv_label_create(btn, NULL);
    lv_label_set_text(label, "Display a message box!");

    /* Create an informative label on the screen */
    info = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_text(info, welcome_info);
    lv_label_set_long_mode(info, LV_LABEL_LONG_BREAK); /* Make sure text will wrap */
    lv_obj_set_width(info, LV_HOR_RES - 10);
    lv_obj_align(info, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 5, -5);

        /* Create a base object for the modal background */
        lv_obj_t *obj = lv_obj_create(lv_scr_act(), NULL);
        lv_obj_reset_style_list(obj, LV_OBJ_PART_MAIN);
        lv_obj_add_style(obj, LV_OBJ_PART_MAIN, &style_modal);
        lv_obj_set_pos(obj, 0, 0);
        lv_obj_set_size(obj, LV_HOR_RES, LV_VER_RES);

        static const char * btns2[] = {"Ok", "Cancel", ""};

        /* Create the message box as a child of the modal background */
        mbox = lv_msgbox_create(obj, NULL);
        lv_msgbox_add_btns(mbox, btns2);
        lv_msgbox_set_text(mbox, "Hello world!");
        lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0);
        lv_obj_set_event_cb(mbox, mbox_event_cb);

        /* Fade the message box in with an animation */
        lv_anim_t a;
        lv_anim_init(&a);
        lv_anim_set_var(&a, obj);
        lv_anim_set_time(&a, 500);
        lv_anim_set_values(&a, LV_OPA_TRANSP, LV_OPA_50);
        lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)opa_anim);
        lv_anim_start(&a);

        lv_label_set_text(info, in_msg_info);
        lv_obj_align(info, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 5, -5);

/* Here I create another screen, load it and delete the old one */
    lv_obj_t *scrAct = lv_scr_act();
    lv_obj_t *newScr = lv_obj_create(NULL, NULL);
    btn = lv_btn_create(newScr, NULL);
    lv_disp_load_scr(newScr);
    lv_obj_del(scrAct);

}

/* The rest of the code is the same as in the example */

I suspect that the delayed delete is the responsible of the fail, but I don’t know how to do it in another way, because other parts of the code have to have the possibility to change the current screen at any time.

Alex

The example code was written based on the assumption that the message box can only be deleted by itself. Since you are deleting the screen (page’s parent) from another spot, the message box gets LV_EVENT_DELETE, assumes that the event means it was just closed, and tries to delete the page. That obviously fails, because the page was deleted at the same time that the screen was.

Hopefully you can understand all that. :slightly_smiling_face:

Hi,

yes I understand that. It was what I thought it was happening. My doubt is how program it in order to be able to delete the msgbox and parent holder thorugh the msgbox dialogue, and that also works when deleting the screen.

Do you have any idea how to do it? any guideline?

Alex

Try this:

static void mbox_event_cb(lv_obj_t *obj, lv_event_t evt)
{
	if(evt == LV_EVENT_VALUE_CHANGED && obj == mbox) {
		/* Delete the parent modal background */
		lv_obj_del_async(lv_obj_get_parent(mbox));
		mbox = NULL; /* happens before object is actually deleted! */
		lv_label_set_text(info, welcome_info);
	}
}

LV_EVENT_VALUE_CHANGED shouldn’t get run if the screen is deleted.

Thank you

I was doing something similar… instead of doing lv_obj_del_async in the OBJ_DELETE event, doing it when the button is pressed.

One question about your solution… obj shouldn’t always be equal to mbox? At least the first time, before doing mbox = NULL.

Is this a way to ensure that no other LV_EVENT_VALUE_CHANGED are triggered before the obj is deleted? Could it happen?

Thanks

Alex

Alex

I wrote the original example quite a while ago, but I vaguely recall there being an issue where button matrix events got forwarded to the message box event handler (and obj pointed to the button matrix instead of the message box). It may no longer be an issue in 7.0; I’m not sure.

1 Like

Thanks for clarifying!

Alex