From a4c3784efe2d30915ee3cbc6b5c1ebdfb323ebaf Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 3 Apr 2019 23:59:12 +0800 Subject: [PATCH] fix bug that wd.find_window unexpectedly returns wd.find_window unexpectedly returns a wrong handle if captured window ignores children windows. --- include/nana/gui/detail/window_manager.hpp | 6 ++++- source/gui/detail/window_manager.cpp | 29 +++++++++++++++++++--- source/gui/programming_interface.cpp | 2 +- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/include/nana/gui/detail/window_manager.hpp b/include/nana/gui/detail/window_manager.hpp index 82e3c57c..d3f36b27 100644 --- a/include/nana/gui/detail/window_manager.hpp +++ b/include/nana/gui/detail/window_manager.hpp @@ -99,7 +99,11 @@ namespace detail bool show(core_window_t* wd, bool visible); - core_window_t* find_window(native_window_type root, const point& pos); + //find a widget window at specified position + //@param root A root window + //@param pos Position + //@param ignore_captured A flag indicates whether to ignore redirecting the result to its captured window. If this paramter is true, it returns the window at the position, if the parameter is false, it returns the captured window if the captured window don't ignore children. + core_window_t* find_window(native_window_type root, const point& pos, bool ignore_captured = false); //move the wnd and its all children window, x and y is a relatively coordinate for wnd's parent window bool move(core_window_t*, int x, int y, bool passive); diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index e1510423..8a653939 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -701,19 +701,40 @@ namespace detail return true; } - window_manager::core_window_t* window_manager::find_window(native_window_type root, const point& pos) + window_manager::core_window_t* window_manager::find_window(native_window_type root, const point& pos, bool ignore_captured) { if (nullptr == root) return nullptr; - if((false == attr_.capture.ignore_children) || (nullptr == attr_.capture.window) || (attr_.capture.window->root != root)) + //Thread-Safe Required! + std::lock_guard lock(mutex_); + + if (ignore_captured || (nullptr == attr_.capture.window)) { - //Thread-Safe Required! - std::lock_guard lock(mutex_); auto rrt = root_runtime(root); if (rrt && _m_effective(rrt->window, pos)) return _m_find(rrt->window, pos); + + return nullptr; } + + if (attr_.capture.ignore_children) + return attr_.capture.window; + + auto rrt = root_runtime(root); + if (rrt && _m_effective(rrt->window, pos)) + { + auto target = _m_find(rrt->window, pos); + + auto p = target; + while (p) + { + if (p == attr_.capture.window) + return target; + p = p->parent; + } + } + return attr_.capture.window; } diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 148667ff..85d4d4c5 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -1403,7 +1403,7 @@ namespace API ::nana::point clipos{pos}; interface_type::calc_window_point(wd, clipos); return reinterpret_cast( - restrict::wd_manager().find_window(wd, clipos)); + restrict::wd_manager().find_window(wd, clipos, true)); } return nullptr; }