diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-26 05:31:43 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-26 05:31:43 +0000 |
commit | d05cf2f1ab93b70f152cb673a102ef2d0e125a72 (patch) | |
tree | db52c14fa05e9c39faefde5a0ad2eff52266221c /ui | |
parent | 1b71f74af8a09558576bba939c9726cc7b4b7c4d (diff) | |
download | chromium_src-d05cf2f1ab93b70f152cb673a102ef2d0e125a72.zip chromium_src-d05cf2f1ab93b70f152cb673a102ef2d0e125a72.tar.gz chromium_src-d05cf2f1ab93b70f152cb673a102ef2d0e125a72.tar.bz2 |
aura: Make sure WindowEventDispatcher only dipatches events to in it.
If an event arrives at a WindowEventDispatcher targeted to a Window not owned by
it, then stop the event-dispatch at this dispatcher, and dispatch the event from
the correct dispatcher instead.
To explain with an example:
* There are two WindowEventDispatchers A and B.
* Window W is in A.
* An event comes in (from the native platform) to dispatcher B.
* The event is targeted at W (because it has capture, or because it has focus
etc.)
* Instead of dispatching the event to W from B, stop the event-dispatch in B
and dispatch the event to W from A instead.
BUG=346808
R=oshima@chromium.org, sky@chromium.org
Review URL: https://codereview.chromium.org/180173004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253368 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/aura/window_event_dispatcher.cc | 4 | ||||
-rw-r--r-- | ui/aura/window_targeter.cc | 48 | ||||
-rw-r--r-- | ui/aura/window_targeter.h | 2 |
3 files changed, 38 insertions, 16 deletions
diff --git a/ui/aura/window_event_dispatcher.cc b/ui/aura/window_event_dispatcher.cc index fce9acc..3fbfdba 100644 --- a/ui/aura/window_event_dispatcher.cc +++ b/ui/aura/window_event_dispatcher.cc @@ -547,6 +547,9 @@ bool WindowEventDispatcher::CanDispatchToTarget(ui::EventTarget* target) { ui::EventDispatchDetails WindowEventDispatcher::PreDispatchEvent( ui::EventTarget* target, ui::Event* event) { + Window* target_window = static_cast<Window*>(target); + CHECK(window()->Contains(target_window)); + if (!dispatching_held_event_) { bool can_be_held = IsEventCandidateForHold(*event); if (!move_hold_count_ || !can_be_held) { @@ -558,7 +561,6 @@ ui::EventDispatchDetails WindowEventDispatcher::PreDispatchEvent( } } - Window* target_window = static_cast<Window*>(target); if (event->IsMouseEvent()) { PreDispatchMouseEvent(target_window, static_cast<ui::MouseEvent*>(event)); } else if (event->IsScrollEvent()) { diff --git a/ui/aura/window_targeter.cc b/ui/aura/window_targeter.cc index 5df06b0..a50f981 100644 --- a/ui/aura/window_targeter.cc +++ b/ui/aura/window_targeter.cc @@ -45,23 +45,22 @@ bool WindowTargeter::EventLocationInsideBounds( ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root, ui::Event* event) { - if (event->IsKeyEvent()) { - Window* window = static_cast<Window*>(root); - Window* root_window = window->GetRootWindow(); - const ui::KeyEvent& key = static_cast<const ui::KeyEvent&>(*event); - if (key.key_code() == ui::VKEY_UNKNOWN) - return NULL; - client::EventClient* event_client = client::GetEventClient(root_window); - client::FocusClient* focus_client = client::GetFocusClient(root_window); - Window* focused_window = focus_client->GetFocusedWindow(); - if (event_client && - !event_client->CanProcessEventsWithinSubtree(focused_window)) { - focus_client->FocusWindow(NULL); - return NULL; + Window* window = static_cast<Window*>(root); + Window* target = event->IsKeyEvent() ? + FindTargetForKeyEvent(window, *static_cast<ui::KeyEvent*>(event)) : + static_cast<Window*>(EventTargeter::FindTargetForEvent(root, event)); + if (target && !window->parent()) { + // |window| is the root window. + if (!window->Contains(target)) { + // |target| is not a descendent of |window|. So do not allow dispatching + // from here. Instead, dispatch the event through the + // WindowEventDispatcher that owns |target|. + ui::EventDispatchDetails details ALLOW_UNUSED = + target->GetDispatcher()->OnEventFromSource(event); + target = NULL; } - return focused_window ? focused_window : window; } - return EventTargeter::FindTargetForEvent(root, event); + return target; } bool WindowTargeter::SubtreeShouldBeExploredForEvent( @@ -88,6 +87,25 @@ ui::EventTarget* WindowTargeter::FindTargetForLocatedEvent( return EventTargeter::FindTargetForLocatedEvent(root, event); } +Window* WindowTargeter::FindTargetForKeyEvent(Window* window, + const ui::KeyEvent& key) { + Window* root_window = window->GetRootWindow(); + if (key.key_code() == ui::VKEY_UNKNOWN) + return NULL; + client::FocusClient* focus_client = client::GetFocusClient(root_window); + Window* focused_window = focus_client->GetFocusedWindow(); + if (!focused_window) + return window; + + client::EventClient* event_client = client::GetEventClient(root_window); + if (event_client && + !event_client->CanProcessEventsWithinSubtree(focused_window)) { + focus_client->FocusWindow(NULL); + return NULL; + } + return focused_window ? focused_window : window; +} + Window* WindowTargeter::FindTargetInRootWindow(Window* root_window, const ui::LocatedEvent& event) { DCHECK_EQ(root_window, root_window->GetRootWindow()); diff --git a/ui/aura/window_targeter.h b/ui/aura/window_targeter.h index 8d35fed..0b0acb3 100644 --- a/ui/aura/window_targeter.h +++ b/ui/aura/window_targeter.h @@ -38,6 +38,8 @@ class AURA_EXPORT WindowTargeter : public ui::EventTargeter { const ui::LocatedEvent& event) OVERRIDE; private: + Window* FindTargetForKeyEvent(Window* root_window, + const ui::KeyEvent& event); Window* FindTargetInRootWindow(Window* root_window, const ui::LocatedEvent& event); |