| Index: services/ui/ws/window_finder.cc
|
| diff --git a/services/ui/ws/window_finder.cc b/services/ui/ws/window_finder.cc
|
| index b9792c2a38b458f6a85ddeac974deff9ef9db653..c687378dabe3abbf1e04e7447e34587c411bf8ba 100644
|
| --- a/services/ui/ws/window_finder.cc
|
| +++ b/services/ui/ws/window_finder.cc
|
| @@ -15,6 +15,7 @@
|
|
|
| namespace ui {
|
| namespace ws {
|
| +namespace {
|
|
|
| bool IsValidWindowForEvents(ServerWindow* window) {
|
| ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager =
|
| @@ -26,20 +27,45 @@ bool IsValidWindowForEvents(ServerWindow* window) {
|
| compositor_frame_sink_manager->HasCompositorFrameSink();
|
| }
|
|
|
| -ServerWindow* FindDeepestVisibleWindowForEvents(ServerWindow* window,
|
| - gfx::Point* location) {
|
| - if (!window->can_accept_events())
|
| - return nullptr;
|
| +bool IsLocationInNonclientArea(const ServerWindow* target,
|
| + const gfx::Point& location) {
|
| + if (!target->parent())
|
| + return false;
|
| +
|
| + gfx::Rect client_area(target->bounds().size());
|
| + client_area.Inset(target->client_area());
|
| + if (client_area.Contains(location))
|
| + return false;
|
| +
|
| + for (const auto& rect : target->additional_client_areas()) {
|
| + if (rect.Contains(location))
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool FindDeepestVisibleWindowForEventsImpl(ServerWindow* window,
|
| + const gfx::Point& location,
|
| + DeepestWindow* deepest_window) {
|
| + if (!window->can_accept_events()) {
|
| + if (!IsLocationInNonclientArea(window, location) ||
|
| + !IsValidWindowForEvents(window)) {
|
| + return false;
|
| + }
|
| + deepest_window->window = window;
|
| + deepest_window->in_non_client_area = true;
|
| + return true;
|
| + }
|
|
|
| const ServerWindow::Windows& children = window->children();
|
| - const gfx::Point original_location = *location;
|
| for (ServerWindow* child : base::Reversed(children)) {
|
| - if (!child->visible() || !child->can_accept_events())
|
| + if (!child->visible())
|
| continue;
|
|
|
| // TODO(sky): support transform.
|
| - gfx::Point location_in_child(original_location.x() - child->bounds().x(),
|
| - original_location.y() - child->bounds().y());
|
| + gfx::Point location_in_child(location.x() - child->bounds().x(),
|
| + location.y() - child->bounds().y());
|
| gfx::Rect child_bounds(child->bounds().size());
|
| child_bounds.Inset(-child->extended_hit_test_region().left(),
|
| -child->extended_hit_test_region().top(),
|
| @@ -51,12 +77,28 @@ ServerWindow* FindDeepestVisibleWindowForEvents(ServerWindow* window,
|
| continue;
|
| }
|
|
|
| - *location = location_in_child;
|
| - ServerWindow* result = FindDeepestVisibleWindowForEvents(child, location);
|
| - if (result)
|
| - return result;
|
| + if (FindDeepestVisibleWindowForEventsImpl(child, location_in_child,
|
| + deepest_window)) {
|
| + return true;
|
| + }
|
| }
|
| - return IsValidWindowForEvents(window) ? window : nullptr;
|
| +
|
| + if (!IsValidWindowForEvents(window))
|
| + return false;
|
| +
|
| + deepest_window->window = window;
|
| + deepest_window->in_non_client_area =
|
| + IsLocationInNonclientArea(window, location);
|
| + return true;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +DeepestWindow FindDeepestVisibleWindowForEvents(ServerWindow* root_window,
|
| + const gfx::Point& location) {
|
| + DeepestWindow result;
|
| + FindDeepestVisibleWindowForEventsImpl(root_window, location, &result);
|
| + return result;
|
| }
|
|
|
| gfx::Transform GetTransformToWindow(ServerWindow* window) {
|
|
|