-
Notifications
You must be signed in to change notification settings - Fork 784
Open
Description
例如
- 调用dialog_modal(winA)
- 在winA的回调中调用dialog_modal(winB)
- 在winB的回调中调用dialog_quit(winA)
- 实际关闭的是winB
看了下dialog_modal的原理是新起一个main_loop阻塞代码,因此退出顺序必须遵循栈结构。
我想到的一个修复方案是
当dialog_quit不是最顶层的modal_dialog如winA时,利用winA上一层的modal_dialog如winB的quit_num记录,并在winB退出时一起退出。
具体代码如下
static widget_t* get_next_top_modal_dialog(widget_t* widget)
{
return_value_if_fail(widget != NULL, NULL);
widget_t* wm = window_manager();
int win_num = widget_count_children(wm);
int32_t widget_index = darray_find_index(wm->children, widget);
return_value_if_fail(widget_index >= 0 && widget_index < win_num, NULL);
widget_t* window = NULL;
int i = 0;
for (i = widget_index + 1; i < win_num; i++)
{
window = widget_get_child(wm, i);
if (widget_is_dialog(window) && dialog_is_modal(window) && !dialog_is_quited(window))
{
return window;
}
}
return NULL;
}
ret_t dialog_quit(widget_t* widget, uint32_t code) {
#ifdef WITHOUT_MODAL_DIALOG
log_debug("awtk web not support dialog_modal\n");
dialog_close(widget);
#else
main_loop_t* l = main_loop();
dialog_t* dialog = DIALOG(widget);
return_value_if_fail(dialog != NULL && !(dialog->quited), RET_BAD_PARAMS);
return_value_if_fail(is_dialog_opened(widget), RET_BAD_PARAMS);
dialog->quited = TRUE;
dialog->quit_code = (dialog_quit_code_t)code;
widget_t* next_widget = get_next_top_modal_dialog(widget);
if (NULL == next_widget) {
/* dialog就是最顶层,直接退出 */
l->quit_num += dialog->quit_num;
main_loop_quit(l);
}
else {
/* next_dialog退出时,顺便关闭dialog */
dialog_t* next_dialog = DIALOG(next_widget);
return_value_if_fail(next_dialog != NULL, RET_BAD_PARAMS);
next_dialog->quit_num += dialog->quit_num;
next_dialog->quit_num++;
}
if (widget->parent != NULL) {
widget->parent->target = NULL;
widget->parent->key_target = NULL;
}
#endif /*WITHOUT_MODAL_DIALOG*/
return RET_OK;
}
Metadata
Metadata
Assignees
Labels
No labels