Skip to content

打开多个modal_dialog,使用dialog_quit关闭最先打开的modal_dialog,实际关闭的时最后打开的modal_dialog #956

@ab19nohikaru

Description

@ab19nohikaru

例如

  1. 调用dialog_modal(winA)
  2. 在winA的回调中调用dialog_modal(winB)
  3. 在winB的回调中调用dialog_quit(winA)
  4. 实际关闭的是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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions