Chromium Code Reviews| Index: services/ui/ws/window_finder.cc |
| diff --git a/services/ui/ws/window_finder.cc b/services/ui/ws/window_finder.cc |
| index c687378dabe3abbf1e04e7447e34587c411bf8ba..4a75999a6fffcb3e303fe7c1bc7e078479e2136d 100644 |
| --- a/services/ui/ws/window_finder.cc |
| +++ b/services/ui/ws/window_finder.cc |
| @@ -6,7 +6,6 @@ |
| #include "base/containers/adapters.h" |
| #include "services/ui/ws/server_window.h" |
| -#include "services/ui/ws/server_window_compositor_frame_sink_manager.h" |
| #include "services/ui/ws/server_window_delegate.h" |
| #include "services/ui/ws/window_coordinate_conversions.h" |
| #include "ui/gfx/geometry/point.h" |
| @@ -17,19 +16,9 @@ namespace ui { |
| namespace ws { |
| namespace { |
| -bool IsValidWindowForEvents(ServerWindow* window) { |
| - ServerWindowCompositorFrameSinkManager* compositor_frame_sink_manager = |
| - window->compositor_frame_sink_manager(); |
| - // Valid windows have at least one of the two surface types. Only an underlay |
| - // is valid as we assume the window manager will likely get the event in this |
| - // case. |
| - return compositor_frame_sink_manager && |
| - compositor_frame_sink_manager->HasCompositorFrameSink(); |
| -} |
| - |
| bool IsLocationInNonclientArea(const ServerWindow* target, |
| const gfx::Point& location) { |
| - if (!target->parent()) |
| + if (!target->parent() || target->bounds().size().IsEmpty()) |
| return false; |
| gfx::Rect client_area(target->bounds().size()); |
| @@ -48,47 +37,54 @@ bool IsLocationInNonclientArea(const ServerWindow* target, |
| bool FindDeepestVisibleWindowForEventsImpl(ServerWindow* window, |
| const gfx::Point& location, |
| DeepestWindow* deepest_window) { |
| - if (!window->can_accept_events()) { |
| - if (!IsLocationInNonclientArea(window, location) || |
| - !IsValidWindowForEvents(window)) { |
| - return false; |
| - } |
| + // The non-client area takes precedence over descendants, as otherwise the |
| + // user would likely not be able to hit the non-client area as it's common |
| + // for descendants to go into the non-client area. |
| + if (IsLocationInNonclientArea(window, location)) { |
| deepest_window->window = window; |
| deepest_window->in_non_client_area = true; |
| return true; |
| } |
| + const mojom::EventTargetingPolicy event_targeting_policy = |
| + window->event_targeting_policy(); |
| - const ServerWindow::Windows& children = window->children(); |
| - for (ServerWindow* child : base::Reversed(children)) { |
| - if (!child->visible()) |
| - continue; |
| - |
| - // TODO(sky): support transform. |
| - 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(), |
| - -child->extended_hit_test_region().right(), |
| - -child->extended_hit_test_region().bottom()); |
| - if (!child_bounds.Contains(location_in_child) || |
| - (child->hit_test_mask() && |
| - !child->hit_test_mask()->Contains(location_in_child))) { |
| - continue; |
| - } |
| + if (event_targeting_policy == ui::mojom::EventTargetingPolicy::NONE) |
| + return false; |
|
sadrul
2017/02/01 20:42:00
Should this go first? I see that that would be dif
sky
2017/02/01 21:13:50
This needs to be after the non-client area hit tes
sadrul
2017/02/01 21:28:29
Ah, of course.
|
| - if (FindDeepestVisibleWindowForEventsImpl(child, location_in_child, |
| - deepest_window)) { |
| - return true; |
| + if (event_targeting_policy == |
| + mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS || |
| + event_targeting_policy == mojom::EventTargetingPolicy::DESCENDANTS_ONLY) { |
| + const ServerWindow::Windows& children = window->children(); |
| + for (ServerWindow* child : base::Reversed(children)) { |
| + if (!child->visible()) |
| + continue; |
| + |
| + // TODO(sky): support transform. |
| + 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(), |
| + -child->extended_hit_test_region().right(), |
| + -child->extended_hit_test_region().bottom()); |
| + if (!child_bounds.Contains(location_in_child) || |
| + (child->hit_test_mask() && |
| + !child->hit_test_mask()->Contains(location_in_child))) { |
| + continue; |
| + } |
| + |
| + if (FindDeepestVisibleWindowForEventsImpl(child, location_in_child, |
| + deepest_window)) { |
| + return true; |
| + } |
| } |
| } |
| - if (!IsValidWindowForEvents(window)) |
| + if (event_targeting_policy == mojom::EventTargetingPolicy::DESCENDANTS_ONLY) |
| return false; |
| deepest_window->window = window; |
| - deepest_window->in_non_client_area = |
| - IsLocationInNonclientArea(window, location); |
| + deepest_window->in_non_client_area = false; |
| return true; |
| } |