From 1d9b75b1c21de16454063ad86da9e906980f9b49 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 15 Dec 2015 15:51:29 +0800 Subject: [PATCH 1/7] fix std numeric conversions errors for GCC 5.1 --- include/nana/config.hpp | 18 +++++++++++++++--- include/nana/deploy.hpp | 13 +++++++++---- source/deploy.cpp | 7 +++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/nana/config.hpp b/include/nana/config.hpp index e97c70f6..0fead174 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -81,24 +81,36 @@ #define STD_CODECVT_NOT_SUPPORTED #endif + #if (__GNUC__ == 4) #if ((__GNUC_MINOR__ < 8) || (__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ < 1)) #define STD_THREAD_NOT_SUPPORTED - + //boost.thread is preferred //but if USE_github_com_meganz_mingw_std_threads is enabled, //boost.thread will be replaced with meganz's mingw-std-threads. // https://github.com/meganz/mingw-std-threads //#define USE_github_com_meganz_mingw_std_threads + + #define STD_TO_STRING_NOT_SUPPORTED #endif - + + //_GLIBCXX_HAVE_BROKEN_VSWPRINTF is enabled to turn off all numeric conversions on MinGW(GCC 4) + #if defined(NANA_MINGW) - //It's a known issue under MinGW + //It's a knonwn issue under MinGW #define STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED #endif #if ((__GNUC_MINOR__ < 8) || defined(NANA_MINGW)) #define STD_TO_STRING_NOT_SUPPORTED + #define STD_TO_WSTRING_NOT_SUPPORTED + #endif + #elif (__GNUC__ == 5) + #if defined(NANA_MINGW) + //The _GLIBCXX_HAVE_BROKEN_VSWPRINTF only applies to wide string + //It's a knonwn issue under MinGW + #define STD_TO_WSTRING_NOT_SUPPORTED #endif #endif #endif diff --git a/include/nana/deploy.hpp b/include/nana/deploy.hpp index 30d87935..802e6335 100644 --- a/include/nana/deploy.hpp +++ b/include/nana/deploy.hpp @@ -1,10 +1,10 @@ /* * The Deploy Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * @file: nana/deploy.hpp @@ -72,7 +72,12 @@ namespace std std::string to_string(long long); std::string to_string(unsigned long long); std::string to_string(float); - +} +#endif + +#ifdef STD_TO_WSTRING_NOT_SUPPORTED +namespace std +{ std::wstring to_wstring(long double); std::wstring to_wstring(double); std::wstring to_wstring(unsigned); diff --git a/source/deploy.cpp b/source/deploy.cpp index ce92982a..0f751352 100644 --- a/source/deploy.cpp +++ b/source/deploy.cpp @@ -298,6 +298,7 @@ namespace std #endif //STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED #ifdef STD_TO_STRING_NOT_SUPPORTED +#include namespace std { std::string to_string(double v) @@ -362,7 +363,13 @@ namespace std ss << v; return ss.str(); } +} +#endif // STD_TO_STRING_NOT_SUPPORTED +#ifdef STD_TO_WSTRING_NOT_SUPPORTED +#include +namespace std +{ std::wstring to_wstring(double v) { std::wstringstream ss; From 54ca38d575bb0f7d52b140cd2e083f0692589401 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Thu, 17 Dec 2015 00:07:44 +0800 Subject: [PATCH 2/7] improve support of MinGW-w64 --- include/nana/config.hpp | 44 ++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/include/nana/config.hpp b/include/nana/config.hpp index 0fead174..975e44c0 100644 --- a/include/nana/config.hpp +++ b/include/nana/config.hpp @@ -67,50 +67,58 @@ // google: That's a known issue, tracked by an active bug (DevDiv#1060849). We were able to update the STL's headers in response to char16_t/char32_t, but we still need to update the separately compiled sources. #define STD_CODECVT_NOT_SUPPORTED #endif // _MSC_VER == 1900 -#endif // _MSVC -#if defined(__clang__) +#elif defined(__clang__) //Clang + + #include //Introduces some implement-specific flags of ISO C++ Library #if defined(__GLIBCPP__) || defined(__GLIBCXX__) // is a known issue on libstdc++, it works on libc++ #define STD_CODECVT_NOT_SUPPORTED #endif #elif defined(__GNUC__) //GCC + + #include //Introduces some implement-specific flags of ISO C++ Library #if defined(__GLIBCPP__) || defined(__GLIBCXX__) // is a known issue on libstdc++, it works on libc++ #define STD_CODECVT_NOT_SUPPORTED - #endif + //It's a known issue of libstdc++ on MinGW + //introduce to_string/to_wstring workarounds for disabled capacity of stdlib + #ifdef _GLIBCXX_HAVE_BROKEN_VSWPRINTF + #if (__GNUC__ < 5) + # define STD_TO_STRING_NOT_SUPPORTED + #endif + + #define STD_TO_WSTRING_NOT_SUPPORTED + #endif + #endif #if (__GNUC__ == 4) #if ((__GNUC_MINOR__ < 8) || (__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ < 1)) #define STD_THREAD_NOT_SUPPORTED - + //boost.thread is preferred //but if USE_github_com_meganz_mingw_std_threads is enabled, //boost.thread will be replaced with meganz's mingw-std-threads. // https://github.com/meganz/mingw-std-threads //#define USE_github_com_meganz_mingw_std_threads - - #define STD_TO_STRING_NOT_SUPPORTED #endif - - //_GLIBCXX_HAVE_BROKEN_VSWPRINTF is enabled to turn off all numeric conversions on MinGW(GCC 4) - + #if defined(NANA_MINGW) //It's a knonwn issue under MinGW #define STD_NUMERIC_CONVERSIONS_NOT_SUPPORTED #endif - #if ((__GNUC_MINOR__ < 8) || defined(NANA_MINGW)) - #define STD_TO_STRING_NOT_SUPPORTED - #define STD_TO_WSTRING_NOT_SUPPORTED - #endif - #elif (__GNUC__ == 5) - #if defined(NANA_MINGW) - //The _GLIBCXX_HAVE_BROKEN_VSWPRINTF only applies to wide string - //It's a knonwn issue under MinGW - #define STD_TO_WSTRING_NOT_SUPPORTED + #if (__GNUC_MINOR__ < 8) + //introduce to_string/to_wstring workaround for lack of stdlib definitions + #ifndef STD_TO_STRING_NOT_SUPPORTED + # define STD_TO_STRING_NOT_SUPPORTED + #endif + + #ifndef STD_TO_WSTRING_NOT_SUPPORTED + # define STD_TO_WSTRING_NOT_SUPPORTED + #endif #endif #endif #endif From 25743b14a97cc66fec963f92ce889af3198b44e0 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 18 Dec 2015 00:57:46 +0800 Subject: [PATCH 3/7] add native_interface::set_parent --- include/nana/gui/detail/native_window_interface.hpp | 1 + source/gui/detail/native_window_interface.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/include/nana/gui/detail/native_window_interface.hpp b/include/nana/gui/detail/native_window_interface.hpp index 5db4a645..fa935799 100644 --- a/include/nana/gui/detail/native_window_interface.hpp +++ b/include/nana/gui/detail/native_window_interface.hpp @@ -70,6 +70,7 @@ namespace detail static void capture_window(native_window_type, bool); static nana::point cursor_position(); static native_window_type get_owner_window(native_window_type); + static native_window_type set_parent(native_window_type child, native_window_type new_parent); //For Caret static void caret_create(native_window_type, const ::nana::size&); static void caret_destroy(native_window_type); diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index 202a76d3..7059e118 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -1199,6 +1199,17 @@ namespace nana{ return reinterpret_cast(::GetWindow(reinterpret_cast(wd), GW_OWNER)); #elif defined(NANA_X11) return restrict::spec.get_owner(wd); +#endif + } + + native_window_type native_interface::set_parent(native_window_type child, native_window_type new_parent) + { +#ifdef NANA_WINDOWS + return reinterpret_cast( + ::SetParent(reinterpret_cast(child), reinterpret_cast(new_parent)) + ); +#elif defined(NANA_X11) + #endif } From 14468494541f2432530df7d90f107be9d7112e14 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Fri, 18 Dec 2015 01:00:33 +0800 Subject: [PATCH 4/7] 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; } From 75800b2e78bee157f040b8120f522bd3cd46d2cc Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 20 Dec 2015 03:00:33 +0800 Subject: [PATCH 5/7] fix a crash when setting focus if prev is null --- source/gui/detail/window_manager.cpp | 45 +++++++++++++++------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index e0d50056..207e2f19 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -927,34 +927,37 @@ namespace detail arg.receiver = wd->root; brock.emit(event_code::focus, prev_focus, arg, true, brock.get_thread_context()); } + + //Check the prev_focus again, because it may be closed in focus event + if (!impl_->wd_register.available(prev_focus)) + prev_focus = nullptr; } else if(wd->root == native_interface::get_focus_window()) - wd = nullptr; //no new focus_window + return prev_focus; //no new focus_window - if(wd) - { - if(wd->together.caret) - wd->together.caret->set_active(true); - arg.window_handle = reinterpret_cast(wd); - arg.getting = true; - arg.receiver = wd->root; - brock.emit(event_code::focus, wd, arg, true, brock.get_thread_context()); + if(wd->together.caret) + wd->together.caret->set_active(true); - if (!root_has_been_focused) - native_interface::set_focus(root_wd->root); + arg.window_handle = reinterpret_cast(wd); + arg.getting = true; + arg.receiver = wd->root; + brock.emit(event_code::focus, wd, arg, true, brock.get_thread_context()); - //A fix by Katsuhisa Yuasa - //The menubar token window will be redirected to the prev focus window when the new - //focus window is a menubar. - //The focus window will be restore to the prev focus which losts the focus becuase of - //memberbar. - if (wd == wd->root_widget->other.attribute.root->menubar) - wd = prev_focus; + if (!root_has_been_focused) + native_interface::set_focus(root_wd->root); + + //A fix by Katsuhisa Yuasa + //The menubar token window will be redirected to the prev focus window when the new + //focus window is a menubar. + //The focus window will be restore to the prev focus which losts the focus becuase of + //memberbar. + if (prev_focus && (wd == wd->root_widget->other.attribute.root->menubar)) + wd = prev_focus; + + if (wd != wd->root_widget->other.attribute.root->menubar) + brock.set_menubar_taken(wd); - if (wd != wd->root_widget->other.attribute.root->menubar) - brock.set_menubar_taken(wd); - } return prev_focus; } From 9bb0e8eb3444f1e6162fe04188cc9d0fd45b7074 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 22 Dec 2015 00:41:58 +0800 Subject: [PATCH 6/7] fix an issue of child root window(nested_form) --- .../gui/detail/native_window_interface.hpp | 7 +- source/gui/detail/native_window_interface.cpp | 70 +++++++++++++++---- source/gui/detail/window_manager.cpp | 60 ++++++++++++---- 3 files changed, 109 insertions(+), 28 deletions(-) diff --git a/include/nana/gui/detail/native_window_interface.hpp b/include/nana/gui/detail/native_window_interface.hpp index fa935799..6a88c0a7 100644 --- a/include/nana/gui/detail/native_window_interface.hpp +++ b/include/nana/gui/detail/native_window_interface.hpp @@ -70,11 +70,12 @@ namespace detail static void capture_window(native_window_type, bool); static nana::point cursor_position(); static native_window_type get_owner_window(native_window_type); - static native_window_type set_parent(native_window_type child, native_window_type new_parent); + static native_window_type parent_window(native_window_type); + static native_window_type parent_window(native_window_type child, native_window_type new_parent, bool returns_previous); //For Caret - static void caret_create(native_window_type, const ::nana::size&); + static void caret_create(native_window_type, const ::nana::size&); static void caret_destroy(native_window_type); - static void caret_pos(native_window_type, const ::nana::point&); + static void caret_pos(native_window_type, const ::nana::point&); static void caret_visible(native_window_type, bool); static void set_focus(native_window_type); diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index 7059e118..ed95415f 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -281,7 +281,8 @@ namespace nana{ attr_mask, &win_attr); if(handle) { - if(owner) + //make owner if it is a popup window + if((!nested) && owner) restrict::spec.make_owner(owner, reinterpret_cast(handle)); XTextProperty name; @@ -417,8 +418,6 @@ namespace nana{ if(handle) { - restrict::spec.make_owner(parent, reinterpret_cast(handle)); - XTextProperty name; char text[] = "Nana Child Window"; char * str = text; @@ -786,21 +785,30 @@ namespace nana{ #if defined(NANA_WINDOWS) ::RECT r; ::GetWindowRect(reinterpret_cast(wd), & r); - HWND owner = ::GetWindow(reinterpret_cast(wd), GW_OWNER); - if(owner) + HWND coord_wd = ::GetWindow(reinterpret_cast(wd), GW_OWNER); + + if (!coord_wd) + coord_wd = ::GetParent(reinterpret_cast(wd)); + + if (coord_wd) { ::POINT pos = {r.left, r.top}; - ::ScreenToClient(owner, &pos); + ::ScreenToClient(coord_wd, &pos); return nana::point(pos.x, pos.y); } return nana::point(r.left, r.top); #elif defined(NANA_X11) int x, y; nana::detail::platform_scope_guard psg; - Window root = reinterpret_cast(restrict::spec.get_owner(wd)); - if(root == 0) root = restrict::spec.root_window(); + Window coord_wd = reinterpret_cast(restrict::spec.get_owner(wd)); + if(!coord_wd) + { + coord_wd = reinterpret_cast(parent_window(wd)); + if(!coord_wd) + coord_wd = restrict::spec.root_window(); + } Window child; - if(True == ::XTranslateCoordinates(restrict::spec.open_display(), reinterpret_cast(wd), root, 0, 0, &x, &y, &child)) + if(True == ::XTranslateCoordinates(restrict::spec.open_display(), reinterpret_cast(wd), coord_wd, 0, 0, &x, &y, &child)) return nana::point(x, y); return nana::point(0, 0); #endif @@ -1202,14 +1210,50 @@ namespace nana{ #endif } - native_window_type native_interface::set_parent(native_window_type child, native_window_type new_parent) + native_window_type native_interface::parent_window(native_window_type wd) { #ifdef NANA_WINDOWS - return reinterpret_cast( - ::SetParent(reinterpret_cast(child), reinterpret_cast(new_parent)) - ); + return reinterpret_cast(::GetParent(reinterpret_cast(wd))); #elif defined(NANA_X11) + Window root; + Window parent; + Window * children; + unsigned size; + + platform_scope_guard lock; + + if(0 != ::XQueryTree(restrict::spec.open_display(), reinterpret_cast(wd), + &root, &parent, &children, &size)) + { + ::XFree(children); + return reinterpret_cast(parent); + } + return nullptr; +#endif + } + native_window_type native_interface::parent_window(native_window_type child, native_window_type new_parent, bool returns_previous) + { +#ifdef NANA_WINDOWS + auto prev = reinterpret_cast( + ::SetParent(reinterpret_cast(child), reinterpret_cast(new_parent)) + ); + + ::SetWindowPos(reinterpret_cast(child), NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); + + return (returns_previous ? prev : nullptr); +#elif defined(NANA_X11) + native_window_type prev = nullptr; + + platform_scope_guard lock; + + if(returns_previous) + prev = parent_window(child); + + ::XReparentWindow(restrict::spec.open_display(), + reinterpret_cast(child), reinterpret_cast(new_parent), + 0, 0); + return prev; #endif } diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 207e2f19..4aa19757 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -550,10 +550,10 @@ namespace detail std::lock_guard lock(mutex_); if (impl_->wd_register.available(wd)) { - if(wd->other.category != category::root_tag::value) + if (category::flags::root != wd->other.category) { //Move child widgets - if(x != wd->pos_owner.x || y != wd->pos_owner.y) + if (x != wd->pos_owner.x || y != wd->pos_owner.y) { point delta{ x - wd->pos_owner.x, y - wd->pos_owner.y }; @@ -570,8 +570,20 @@ namespace detail return true; } } - else if(false == passive) + else if (!passive) + { + //Check if this root is a nested + if (wd->parent && (category::flags::root != wd->parent->other.category)) + { + //The parent of the window is not a root, the position should + //be transformed to a position based on its parent. + + x += wd->parent->pos_root.x; + y += wd->parent->pos_root.y; + } + native_interface::move_window(wd->root, x, y); + } } return false; @@ -610,22 +622,36 @@ namespace detail } else { + ::nana::rectangle root_r = r; + //Move event should not get called here, + //because the window is a root, the event will get called by system event handler. + + //Check if this root is a nested + if (wd->parent && (category::flags::root != wd->parent->other.category)) + { + //The parent of the window is not a root, the position should + //be transformed to a position based on its parent. + + root_r.x += wd->parent->pos_root.x; + root_r.y += wd->parent->pos_root.y; + } + if(size_changed) { - wd->dimension.width = r.width; - wd->dimension.height = r.height; + wd->dimension.width = root_r.width; + wd->dimension.height = root_r.height; wd->drawer.graphics.make(wd->dimension); wd->root_graph->make(wd->dimension); - native_interface::move_window(wd->root, r); + native_interface::move_window(wd->root, root_r); arg_resized arg; arg.window_handle = reinterpret_cast(wd); - arg.width = r.width; - arg.height = r.height; + arg.width = root_r.width; + arg.height = root_r.height; brock.emit(event_code::resized, wd, arg, true, brock.get_thread_context()); } else - native_interface::move_window(wd->root, r.x, r.y); + native_interface::move_window(wd->root, root_r.x, root_r.y); } return (moved || size_changed); @@ -1456,12 +1482,15 @@ namespace detail std::function set_pos_root; set_pos_root = [&set_pos_root](core_window_t* wd, const nana::point& delta_pos) { - wd->pos_root -= delta_pos; for (auto child : wd->children) { if (category::flags::root == child->other.category) { - native_interface::set_parent(child->root, wd->root); + auto pos = native_interface::window_position(child->root); + native_interface::parent_window(child->root, wd->root, false); + + pos -= delta_pos; + native_interface::move_window(child->root, pos.x, pos.y); } else { @@ -1471,6 +1500,8 @@ namespace detail set_pos_root(child, delta_pos); } } + + wd->pos_root -= delta_pos; }; set_pos_root(wd, delta_pos); @@ -1550,7 +1581,7 @@ namespace detail void window_manager::_m_move_core(core_window_t* wd, const point& delta) { - if(wd->other.category != category::root_tag::value) //A root widget always starts at (0, 0) and its childs are not to be changed + if(category::flags::root != wd->other.category) //A root widget always starts at (0, 0) and its childs are not to be changed { wd->pos_root += delta; if (category::flags::frame != wd->other.category) @@ -1567,6 +1598,11 @@ namespace detail for (auto child : wd->children) _m_move_core(child, delta); } + else + { + auto pos = native_interface::window_position(wd->root) + delta; + native_interface::move_window(wd->root, pos.x, pos.y); + } } //_m_find From 3856543dafcfb34b20411e165b8bba8911912ae3 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Tue, 22 Dec 2015 23:47:56 +0800 Subject: [PATCH 7/7] fix wrong position of sub menu --- source/gui/detail/native_window_interface.cpp | 9 +++++---- source/gui/widgets/menu.cpp | 7 +++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/gui/detail/native_window_interface.cpp b/source/gui/detail/native_window_interface.cpp index ed95415f..786a5df2 100644 --- a/source/gui/detail/native_window_interface.cpp +++ b/source/gui/detail/native_window_interface.cpp @@ -1235,13 +1235,14 @@ namespace nana{ native_window_type native_interface::parent_window(native_window_type child, native_window_type new_parent, bool returns_previous) { #ifdef NANA_WINDOWS - auto prev = reinterpret_cast( - ::SetParent(reinterpret_cast(child), reinterpret_cast(new_parent)) - ); + auto prev = ::SetParent(reinterpret_cast(child), reinterpret_cast(new_parent)); + + if (prev) + ::PostMessage(prev, WM_CHANGEUISTATE, UIS_INITIALIZE, NULL); ::SetWindowPos(reinterpret_cast(child), NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED); - return (returns_previous ? prev : nullptr); + return reinterpret_cast(returns_previous ? prev : nullptr); #elif defined(NANA_X11) native_window_type prev = nullptr; diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index fd206764..3e1159a5 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -526,17 +526,16 @@ namespace nana auto index = state_.active; for (auto & m : menu_->items) { + if (0 == index--) + break; + if (m.flags.splitter) { pos.y += 2; continue; } - if (0 == index) - break; - pos.y += _m_item_height() + 1; - --index; } tmstamp = state_.active_timestamp;