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; }