Chromium Code Reviews| Index: ui/aura/window_targeter.cc |
| diff --git a/ui/aura/window_targeter.cc b/ui/aura/window_targeter.cc |
| index 9853585d3cda3a6a0dddb1503f668abb4b34c7d5..c7661b382926572aba0aa1dca3ea5c5362ca4878 100644 |
| --- a/ui/aura/window_targeter.cc |
| +++ b/ui/aura/window_targeter.cc |
| @@ -4,6 +4,8 @@ |
| #include "ui/aura/window_targeter.h" |
| +#include <memory> |
| + |
| #include "ui/aura/client/capture_client.h" |
| #include "ui/aura/client/event_client.h" |
| #include "ui/aura/client/focus_client.h" |
| @@ -15,6 +17,7 @@ |
| #include "ui/events/event_target_iterator.h" |
| namespace aura { |
| +const char kHasIndependentBoundsKey[] = "__INDEPENDENT_BOUNDS__"; |
| WindowTargeter::WindowTargeter() {} |
| WindowTargeter::~WindowTargeter() {} |
| @@ -59,6 +62,47 @@ bool WindowTargeter::EventLocationInsideBounds( |
| return gfx::Rect(window->bounds().size()).Contains(point); |
| } |
| +bool WindowTargeter::ChildHasBoundsOutsideParent(Window* parent, |
| + Window* child) { |
| + if (!parent || !child) |
| + return false; |
| + return child->GetNativeWindowProperty(aura::kHasIndependentBoundsKey) != NULL; |
|
Lei Zhang
2016/08/18 20:30:57
nit: no NULLs in new code, use nullptr.
rbpotter
2016/08/19 01:59:09
Done.
|
| +} |
| + |
| +bool WindowTargeter::HasIndependentChildWithEvent(Window* window, |
| + gfx::Point point, |
| + bool in_parent_coordinates) { |
| + Window* parent = window->parent(); |
| + bool canAccept = true; |
|
Lei Zhang
2016/08/18 20:30:57
nit: can_accept, in_bounds below.
rbpotter
2016/08/19 01:59:09
Done.
|
| + if (parent) { |
| + if (!in_parent_coordinates) |
| + Window::ConvertPointToTarget(window, parent, &point); |
| + if (parent->delegate_ && |
| + !parent->delegate_->ShouldDescendIntoChildForEventHandling(window, |
| + point)) { |
| + canAccept = false; |
| + } |
| + Window::ConvertPointToTarget(parent, window, &point); |
| + } |
| + bool inBounds = gfx::Rect(window->bounds().size()).Contains(point); |
| + canAccept = canAccept && (window->IsVisible() && !window->ignore_events()); |
| + client::EventClient* client = client::GetEventClient(window->GetRootWindow()); |
| + if (client && !client->CanProcessEventsWithinSubtree(window)) |
| + canAccept = false; |
| + if (inBounds && canAccept && ChildHasBoundsOutsideParent(parent, window)) |
| + return true; |
| + std::unique_ptr<ui::EventTargetIterator> iter = window->GetChildIterator(); |
| + if (iter) { |
| + for (ui::EventTarget* child = iter->GetNextTarget(); child; |
| + child = iter->GetNextTarget()) { |
| + if (HasIndependentChildWithEvent(static_cast<Window*>(child), point, |
| + true)) |
| + return true; |
| + } |
| + } |
| + return false; |
| +} |
| + |
| ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root, |
| ui::Event* event) { |
| Window* window = static_cast<Window*>(root); |
| @@ -99,8 +143,9 @@ ui::EventTarget* WindowTargeter::FindNextBestTarget( |
| bool WindowTargeter::SubtreeShouldBeExploredForEvent( |
| Window* window, |
| const ui::LocatedEvent& event) { |
| - return SubtreeCanAcceptEvent(window, event) && |
| - EventLocationInsideBounds(window, event); |
| + return (SubtreeCanAcceptEvent(window, event) && |
| + EventLocationInsideBounds(window, event)) || |
| + HasIndependentChildWithEvent(window, event.location(), true); |
| } |
| Window* WindowTargeter::FindTargetForKeyEvent(Window* window, |