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