From 14468494541f2432530df7d90f107be9d7112e14 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 18 Dec 2015 01:00:33 +0800 Subject: [PATCH] fix non-popup root window(nested_form) issues --- source/gui/detail/window_layout.cpp | 10 ++++-- source/gui/detail/window_manager.cpp | 53 ++++++++++++++++++++++++---- source/gui/programming_interface.cpp | 4 +-- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/source/gui/detail/window_layout.cpp b/source/gui/detail/window_layout.cpp index 9f0e779e..f44be0a6 100644 --- a/source/gui/detail/window_layout.cpp +++ b/source/gui/detail/window_layout.cpp @@ -140,7 +140,7 @@ namespace nana for (++i; i < end; ++i) { core_window_t* cover = *i; - if (cover->visible && (nullptr == cover->effect.bground)) + if ((category::flags::root != cover->other.category) && cover->visible && (nullptr == cover->effect.bground)) { if (overlap(vis_rect, rectangle{ cover->pos_root, cover->dimension }, block.r)) { @@ -271,9 +271,15 @@ namespace nana for (auto child : wd->children) { //it will not past children if no drawer and visible is false. - if ((false == child->visible) || ((child->other.category != category::lite_widget_tag::value) && child->drawer.graphics.empty())) + if ((false == child->visible) || ((category::flags::lite_widget != child->other.category) && child->drawer.graphics.empty())) continue; + if (category::flags::root == child->other.category) + { + paint(child, is_child_refreshed, is_child_refreshed); + continue; + } + if (nullptr == child->effect.bground) { if (overlap(nana::rectangle{ child->pos_root, child->dimension }, parent_rect, rect)) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 909cf193..e0d50056 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -291,6 +291,14 @@ namespace detail if (result.native_handle) { core_window_t* wd = new core_window_t(owner, widget_notifier_interface::get_notifier(wdg), (category::root_tag**)nullptr); + if (nested) + { + wd->owner = nullptr; + wd->parent = owner; + wd->index = static_cast(owner->children.size()); + owner->children.push_back(wd); + } + wd->flags.take_active = !app.no_activate; wd->title = native_interface::window_caption(result.native_handle); @@ -1301,7 +1309,9 @@ namespace detail void window_manager::_m_disengage(core_window_t* wd, core_window_t* for_new) { auto * const wdpa = wd->parent; - bool established = (for_new && wdpa != for_new); + + + bool established = (for_new && (wdpa != for_new)); decltype(for_new->root_widget->other.attribute.root) pa_root_attr = nullptr; if (established) @@ -1446,10 +1456,17 @@ namespace detail wd->pos_root -= delta_pos; for (auto child : wd->children) { - child->root = wd->root; - child->root_graph = wd->root_graph; - child->root_widget = wd->root_widget; - set_pos_root(child, delta_pos); + if (category::flags::root == child->other.category) + { + native_interface::set_parent(child->root, wd->root); + } + else + { + child->root = wd->root; + child->root_graph = wd->root_graph; + child->root_widget = wd->root_widget; + set_pos_root(child, delta_pos); + } } }; @@ -1481,8 +1498,30 @@ namespace detail brock.emit(event_code::destroy, wd, arg, true, brock.get_thread_context()); //Delete the children widgets. - for (auto i = wd->children.rbegin(), end = wd->children.rend(); i != end; ++i) - _m_destroy(*i); + for (auto i = wd->children.rbegin(), end = wd->children.rend(); i != end;) + { + auto child = *i; + + if (category::flags::root == child->other.category) + { + //closing a child root window erases itself from wd->children, + //to make sure the iterator is valid, it must be reloaded. + + auto offset = std::distance(wd->children.rbegin(), i); + + //!!! + //a potential issue is that if the calling thread is not same with child's thread, + //the child root window may not be erased from wd->children now. + native_interface::close_window(child->root); + + i = wd->children.rbegin(); + std::advance(i, offset); + end = wd->children.rend(); + continue; + } + _m_destroy(child); + ++i; + } wd->children.clear(); diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index fdd4522c..2d731b77 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -542,8 +542,8 @@ namespace API { auto iwd = reinterpret_cast(wd); internal_scope_guard lock; - if(restrict::wd_manager().available(iwd)) - return reinterpret_cast(iwd->other.category == category::flags::root ? iwd->owner : iwd->parent); + if (restrict::wd_manager().available(iwd)) + return reinterpret_cast(iwd->parent); return nullptr; }