summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvarkha <varkha@chromium.org>2015-06-11 11:32:58 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-11 18:33:28 +0000
commit9c6bcf714a44413a5bf00a4cd346197d854464e6 (patch)
tree9e5ef1a4674fb913bfa9495964ffd0085cb972c9
parentfd6b78bc2cac155f67f0bd09c184645353f7d6b9 (diff)
downloadchromium_src-9c6bcf714a44413a5bf00a4cd346197d854464e6.zip
chromium_src-9c6bcf714a44413a5bf00a4cd346197d854464e6.tar.gz
chromium_src-9c6bcf714a44413a5bf00a4cd346197d854464e6.tar.bz2
Refactors away method implementations in ui::EventTargeter
ui::EventTargeter is now a pure virtual interface with only two methods: FindTargetForEvent FindNextBestTarget. Following methods are removed from ui::EventTargeter and got added (with implementations) to aura::WindowTargeter: FindTargetForLocatedEvent SubtreeCanAcceptEvent EventLocationInsideBounds SubtreeShouldBeExploredForEvent Method implementations in aura::WindowTargeter that perform LocatedEvent targeting now take Window* instead of EventTarget*. Tests moved out of EventProcessorTest into WindowTargeterTest: + Bounds + TargeterChecksOwningEventTarget Those tests now require a bit less plumbing since a aura::Window implements coordinates based targeting. EventProcessorTest tests now use TestEventTarget that provides bubbling behavior optionally and can have an event target changed at runtime with set_target(). BUG=395388 TEST=EventProcessorTest, WindowTargeterTest TBR=sky@chromium.org Review URL: https://codereview.chromium.org/1119423003 Cr-Commit-Position: refs/heads/master@{#333993}
-rw-r--r--ash/accelerators/magnifier_key_scroller.cc1
-rw-r--r--ash/accelerators/magnifier_key_scroller_unittest.cc1
-rw-r--r--ash/accelerators/spoken_feedback_toggler.cc1
-rw-r--r--ash/display/mouse_cursor_event_filter.cc1
-rw-r--r--ash/utility/partial_screenshot_controller.cc1
-rw-r--r--ash/wm/cursor_manager_chromeos.cc1
-rw-r--r--ash/wm/resize_handle_window_targeter.cc22
-rw-r--r--ash/wm/resize_handle_window_targeter.h6
-rw-r--r--chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.cc3
-rw-r--r--chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.h4
-rw-r--r--chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc2
-rw-r--r--content/browser/web_contents/aura/overscroll_window_delegate.cc1
-rw-r--r--ui/aura/window_targeter.cc142
-rw-r--r--ui/aura/window_targeter.h50
-rw-r--r--ui/aura/window_targeter_unittest.cc125
-rw-r--r--ui/events/BUILD.gn3
-rw-r--r--ui/events/event_processor_unittest.cc213
-rw-r--r--ui/events/event_targeter.cc73
-rw-r--r--ui/events/event_targeter.h44
-rw-r--r--ui/events/events.gyp3
-rw-r--r--ui/events/null_event_targeter.cc7
-rw-r--r--ui/events/null_event_targeter.h6
-rw-r--r--ui/events/test/test_event_target.h4
-rw-r--r--ui/events/test/test_event_targeter.cc37
-rw-r--r--ui/events/test/test_event_targeter.h44
-rw-r--r--ui/views/test/event_generator_delegate_mac.mm18
-rw-r--r--ui/views/view_targeter.cc14
-rw-r--r--ui/views/view_targeter.h15
-rw-r--r--ui/wm/core/easy_resize_window_targeter.cc6
-rw-r--r--ui/wm/core/easy_resize_window_targeter.h4
-rw-r--r--ui/wm/core/masked_window_targeter.cc4
-rw-r--r--ui/wm/core/masked_window_targeter.h4
32 files changed, 447 insertions, 413 deletions
diff --git a/ash/accelerators/magnifier_key_scroller.cc b/ash/accelerators/magnifier_key_scroller.cc
index eeeda2d..2e33950 100644
--- a/ash/accelerators/magnifier_key_scroller.cc
+++ b/ash/accelerators/magnifier_key_scroller.cc
@@ -9,6 +9,7 @@
#include "ash/magnifier/magnification_controller.h"
#include "ash/shell.h"
#include "base/command_line.h"
+#include "ui/events/event.h"
namespace ash {
namespace {
diff --git a/ash/accelerators/magnifier_key_scroller_unittest.cc b/ash/accelerators/magnifier_key_scroller_unittest.cc
index 8555369..69f2273 100644
--- a/ash/accelerators/magnifier_key_scroller_unittest.cc
+++ b/ash/accelerators/magnifier_key_scroller_unittest.cc
@@ -9,6 +9,7 @@
#include "ash/test/ash_test_base.h"
#include "ash/wm/window_util.h"
#include "ui/aura/test/test_window_delegate.h"
+#include "ui/events/event.h"
#include "ui/events/test/event_generator.h"
namespace ash {
diff --git a/ash/accelerators/spoken_feedback_toggler.cc b/ash/accelerators/spoken_feedback_toggler.cc
index 53f6e6e..32ef929 100644
--- a/ash/accelerators/spoken_feedback_toggler.cc
+++ b/ash/accelerators/spoken_feedback_toggler.cc
@@ -7,6 +7,7 @@
#include "ash/accelerators/key_hold_detector.h"
#include "ash/accessibility_delegate.h"
#include "ash/shell.h"
+#include "ui/events/event.h"
namespace ash {
namespace {
diff --git a/ash/display/mouse_cursor_event_filter.cc b/ash/display/mouse_cursor_event_filter.cc
index 38b1cbd..fb24f2c 100644
--- a/ash/display/mouse_cursor_event_filter.cc
+++ b/ash/display/mouse_cursor_event_filter.cc
@@ -10,6 +10,7 @@
#include "ash/display/display_manager.h"
#include "ash/display/mouse_warp_controller.h"
#include "ash/shell.h"
+#include "ui/events/event.h"
namespace ash {
diff --git a/ash/utility/partial_screenshot_controller.cc b/ash/utility/partial_screenshot_controller.cc
index 18f8e4e..602fde4 100644
--- a/ash/utility/partial_screenshot_controller.cc
+++ b/ash/utility/partial_screenshot_controller.cc
@@ -12,6 +12,7 @@
#include "ash/shell_window_ids.h"
#include "base/stl_util.h"
#include "ui/compositor/paint_recorder.h"
+#include "ui/events/event.h"
#include "ui/events/event_handler.h"
#include "ui/gfx/canvas.h"
#include "ui/wm/core/cursor_manager.h"
diff --git a/ash/wm/cursor_manager_chromeos.cc b/ash/wm/cursor_manager_chromeos.cc
index af38d5c..3a1162f 100644
--- a/ash/wm/cursor_manager_chromeos.cc
+++ b/ash/wm/cursor_manager_chromeos.cc
@@ -5,6 +5,7 @@
#include "ash/wm/cursor_manager_chromeos.h"
#include "base/logging.h"
+#include "ui/events/event.h"
#include "ui/keyboard/keyboard_util.h"
#include "ui/wm/core/cursor_manager.h"
#include "ui/wm/core/native_cursor_manager.h"
diff --git a/ash/wm/resize_handle_window_targeter.cc b/ash/wm/resize_handle_window_targeter.cc
index 28bd0e2..8ee6924 100644
--- a/ash/wm/resize_handle_window_targeter.cc
+++ b/ash/wm/resize_handle_window_targeter.cc
@@ -8,6 +8,7 @@
#include "ash/wm/immersive_fullscreen_controller.h"
#include "ash/wm/window_state.h"
#include "ui/aura/window.h"
+#include "ui/events/event.h"
namespace ash {
@@ -48,10 +49,9 @@ void ResizeHandleWindowTargeter::OnWindowDestroying(aura::Window* window) {
window_ = NULL;
}
-ui::EventTarget* ResizeHandleWindowTargeter::FindTargetForLocatedEvent(
- ui::EventTarget* root,
+aura::Window* ResizeHandleWindowTargeter::FindTargetForLocatedEvent(
+ aura::Window* window,
ui::LocatedEvent* event) {
- aura::Window* window = static_cast<aura::Window*>(root);
if (window == window_) {
gfx::Insets insets;
if (immersive_controller_ && immersive_controller_->IsEnabled() &&
@@ -77,23 +77,25 @@ ui::EventTarget* ResizeHandleWindowTargeter::FindTargetForLocatedEvent(
return window_;
}
}
- return aura::WindowTargeter::FindTargetForLocatedEvent(root, event);
+ return aura::WindowTargeter::FindTargetForLocatedEvent(window, event);
}
bool ResizeHandleWindowTargeter::SubtreeShouldBeExploredForEvent(
- ui::EventTarget* target,
+ aura::Window* window,
const ui::LocatedEvent& event) {
- if (target == window_) {
+ if (window == window_) {
// Defer to the parent's targeter on whether |window_| should be able to
// receive the event.
- ui::EventTarget* parent = target->GetParentTarget();
+ ui::EventTarget* parent =
+ static_cast<ui::EventTarget*>(window)->GetParentTarget();
if (parent) {
- ui::EventTargeter* targeter = parent->GetEventTargeter();
+ aura::WindowTargeter* targeter =
+ static_cast<aura::WindowTargeter*>(parent->GetEventTargeter());
if (targeter)
- return targeter->SubtreeShouldBeExploredForEvent(target, event);
+ return targeter->SubtreeShouldBeExploredForEvent(window, event);
}
}
- return aura::WindowTargeter::SubtreeShouldBeExploredForEvent(target, event);
+ return aura::WindowTargeter::SubtreeShouldBeExploredForEvent(window, event);
}
} // namespace ash
diff --git a/ash/wm/resize_handle_window_targeter.h b/ash/wm/resize_handle_window_targeter.h
index c6b789e..24c2e32 100644
--- a/ash/wm/resize_handle_window_targeter.h
+++ b/ash/wm/resize_handle_window_targeter.h
@@ -35,9 +35,9 @@ class ResizeHandleWindowTargeter : public wm::WindowStateObserver,
void OnWindowDestroying(aura::Window* window) override;
// aura::WindowTargeter:
- ui::EventTarget* FindTargetForLocatedEvent(ui::EventTarget* root,
- ui::LocatedEvent* event) override;
- bool SubtreeShouldBeExploredForEvent(ui::EventTarget* target,
+ aura::Window* FindTargetForLocatedEvent(aura::Window* window,
+ ui::LocatedEvent* event) override;
+ bool SubtreeShouldBeExploredForEvent(aura::Window* window,
const ui::LocatedEvent& event) override;
// The targeter does not take ownership of |window_| or
diff --git a/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.cc b/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.cc
index 98be821..891511e 100644
--- a/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.cc
+++ b/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.cc
@@ -19,9 +19,8 @@ AppWindowEasyResizeWindowTargeter::~AppWindowEasyResizeWindowTargeter() {
}
bool AppWindowEasyResizeWindowTargeter::EventLocationInsideBounds(
- ui::EventTarget* target,
+ aura::Window* window,
const ui::LocatedEvent& event) const {
- aura::Window* window = static_cast<aura::Window*>(target);
// EasyResizeWindowTargeter intercepts events landing at the edges of the
// window. Since maximized and fullscreen windows can't be resized anyway,
// skip EasyResizeWindowTargeter so that the web contents receive all mouse
diff --git a/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.h b/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.h
index 69b08d6..90aa8c4 100644
--- a/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.h
+++ b/chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.h
@@ -23,8 +23,8 @@ class AppWindowEasyResizeWindowTargeter : public wm::EasyResizeWindowTargeter {
~AppWindowEasyResizeWindowTargeter() override;
protected:
- // ui::EventTargeter:
- bool EventLocationInsideBounds(ui::EventTarget* target,
+ // aura::WindowTargeter:
+ bool EventLocationInsideBounds(aura::Window* window,
const ui::LocatedEvent& event) const override;
private:
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
index 2790730..1911f4c 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller_interactive_uitest.cc
@@ -579,7 +579,7 @@ class MaskedWindowTargeter : public aura::WindowTargeter {
~MaskedWindowTargeter() override {}
// aura::WindowTargeter:
- bool EventLocationInsideBounds(ui::EventTarget* target,
+ bool EventLocationInsideBounds(aura::Window* target,
const ui::LocatedEvent& event) const override {
aura::Window* window = static_cast<aura::Window*>(target);
gfx::Point local_point = event.location();
diff --git a/content/browser/web_contents/aura/overscroll_window_delegate.cc b/content/browser/web_contents/aura/overscroll_window_delegate.cc
index d8ce8b6..76aa583 100644
--- a/content/browser/web_contents/aura/overscroll_window_delegate.cc
+++ b/content/browser/web_contents/aura/overscroll_window_delegate.cc
@@ -10,6 +10,7 @@
#include "content/browser/renderer_host/overscroll_controller_delegate.h"
#include "content/public/browser/overscroll_configuration.h"
#include "ui/aura/window.h"
+#include "ui/events/event.h"
#include "ui/gfx/image/image_png_rep.h"
namespace content {
diff --git a/ui/aura/window_targeter.cc b/ui/aura/window_targeter.cc
index 7303e22..192bd60 100644
--- a/ui/aura/window_targeter.cc
+++ b/ui/aura/window_targeter.cc
@@ -12,55 +12,28 @@
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/events/event_target.h"
+#include "ui/events/event_target_iterator.h"
namespace aura {
-namespace {
-
-bool IsLocatedEvent(const ui::Event& event) {
- return event.IsMouseEvent() || event.IsTouchEvent() ||
- event.IsScrollEvent() || event.IsGestureEvent();
-}
-
-} // namespace
-
WindowTargeter::WindowTargeter() {}
WindowTargeter::~WindowTargeter() {}
-ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root,
- ui::Event* event) {
- 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->Contains(target)) {
- // |window| is the root window, but |target| is not a descendent of
- // |window|. So do not allow dispatching from here. Instead, dispatch the
- // event through the WindowEventDispatcher that owns |target|.
- aura::Window* new_root = target->GetRootWindow();
- if (IsLocatedEvent(*event)) {
- // The event has been transformed to be in |target|'s coordinate system.
- // But dispatching the event through the EventProcessor requires the event
- // to be in the host's coordinate system. So, convert the event to be in
- // the root's coordinate space, and then to the host's coordinate space by
- // applying the host's transform.
- ui::LocatedEvent* located_event = static_cast<ui::LocatedEvent*>(event);
- located_event->ConvertLocationToTarget(target, new_root);
- located_event->UpdateForRootTransform(
- new_root->GetHost()->GetRootTransform());
+Window* WindowTargeter::FindTargetForLocatedEvent(Window* window,
+ ui::LocatedEvent* event) {
+ if (!window->parent()) {
+ Window* target = FindTargetInRootWindow(window, *event);
+ if (target) {
+ window->ConvertEventToTarget(target, event);
+ return target;
}
- ignore_result(
- new_root->GetHost()->event_processor()->OnEventFromSource(event));
-
- target = NULL;
}
- return target;
+ return FindTargetForLocatedEventRecursively(window, event);
}
bool WindowTargeter::SubtreeCanAcceptEvent(
- ui::EventTarget* target,
+ Window* window,
const ui::LocatedEvent& event) const {
- aura::Window* window = static_cast<aura::Window*>(target);
if (!window->IsVisible())
return false;
if (window->ignore_events())
@@ -78,27 +51,56 @@ bool WindowTargeter::SubtreeCanAcceptEvent(
}
bool WindowTargeter::EventLocationInsideBounds(
- ui::EventTarget* target,
+ Window* window,
const ui::LocatedEvent& event) const {
- aura::Window* window = static_cast<aura::Window*>(target);
gfx::Point point = event.location();
if (window->parent())
- aura::Window::ConvertPointToTarget(window->parent(), window, &point);
+ Window::ConvertPointToTarget(window->parent(), window, &point);
return gfx::Rect(window->bounds().size()).Contains(point);
}
-ui::EventTarget* WindowTargeter::FindTargetForLocatedEvent(
- ui::EventTarget* root,
- ui::LocatedEvent* event) {
+ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root,
+ ui::Event* event) {
Window* window = static_cast<Window*>(root);
- if (!window->parent()) {
- Window* target = FindTargetInRootWindow(window, *event);
- if (target) {
- window->ConvertEventToTarget(target, event);
- return target;
+ Window* target =
+ event->IsKeyEvent()
+ ? FindTargetForKeyEvent(window, *static_cast<ui::KeyEvent*>(event))
+ : FindTargetForNonKeyEvent(window, event);
+ if (target && !window->parent() && !window->Contains(target)) {
+ // |window| is the root window, but |target| is not a descendent of
+ // |window|. So do not allow dispatching from here. Instead, dispatch the
+ // event through the WindowEventDispatcher that owns |target|.
+ Window* new_root = target->GetRootWindow();
+ if (event->IsLocatedEvent()) {
+ // The event has been transformed to be in |target|'s coordinate system.
+ // But dispatching the event through the EventProcessor requires the event
+ // to be in the host's coordinate system. So, convert the event to be in
+ // the root's coordinate space, and then to the host's coordinate space by
+ // applying the host's transform.
+ ui::LocatedEvent* located_event = static_cast<ui::LocatedEvent*>(event);
+ located_event->ConvertLocationToTarget(target, new_root);
+ located_event->UpdateForRootTransform(
+ new_root->GetHost()->GetRootTransform());
}
+ ignore_result(
+ new_root->GetHost()->event_processor()->OnEventFromSource(event));
+
+ target = nullptr;
}
- return EventTargeter::FindTargetForLocatedEvent(root, event);
+ return target;
+}
+
+ui::EventTarget* WindowTargeter::FindNextBestTarget(
+ ui::EventTarget* previous_target,
+ ui::Event* event) {
+ return nullptr;
+}
+
+bool WindowTargeter::SubtreeShouldBeExploredForEvent(
+ Window* window,
+ const ui::LocatedEvent& event) {
+ return SubtreeCanAcceptEvent(window, event) &&
+ EventLocationInsideBounds(window, event);
}
Window* WindowTargeter::FindTargetForKeyEvent(Window* window,
@@ -112,12 +114,20 @@ Window* WindowTargeter::FindTargetForKeyEvent(Window* window,
client::EventClient* event_client = client::GetEventClient(root_window);
if (event_client &&
!event_client->CanProcessEventsWithinSubtree(focused_window)) {
- focus_client->FocusWindow(NULL);
- return NULL;
+ focus_client->FocusWindow(nullptr);
+ return nullptr;
}
return focused_window ? focused_window : window;
}
+Window* WindowTargeter::FindTargetForNonKeyEvent(Window* root_window,
+ ui::Event* event) {
+ if (!event->IsLocatedEvent())
+ return root_window;
+ return FindTargetForLocatedEvent(root_window,
+ static_cast<ui::LocatedEvent*>(event));
+}
+
Window* WindowTargeter::FindTargetInRootWindow(Window* root_window,
const ui::LocatedEvent& event) {
DCHECK_EQ(root_window, root_window->GetRootWindow());
@@ -153,7 +163,35 @@ Window* WindowTargeter::FindTargetInRootWindow(Window* root_window,
return root_window;
}
- return NULL;
+ return nullptr;
+}
+
+Window* WindowTargeter::FindTargetForLocatedEventRecursively(
+ Window* root_window,
+ ui::LocatedEvent* event) {
+ scoped_ptr<ui::EventTargetIterator> iter = root_window->GetChildIterator();
+ if (iter) {
+ ui::EventTarget* target = root_window;
+ for (ui::EventTarget* child = iter->GetNextTarget(); child;
+ child = iter->GetNextTarget()) {
+ WindowTargeter* targeter =
+ static_cast<WindowTargeter*>(child->GetEventTargeter());
+ if (!targeter)
+ targeter = this;
+ if (!targeter->SubtreeShouldBeExploredForEvent(
+ static_cast<Window*>(child), *event)) {
+ continue;
+ }
+ target->ConvertEventToTarget(child, event);
+ target = child;
+ Window* child_target_window =
+ static_cast<Window*>(targeter->FindTargetForEvent(child, event));
+ if (child_target_window)
+ return child_target_window;
+ }
+ target->ConvertEventToTarget(root_window, event);
+ }
+ return root_window->CanAcceptEvent(*event) ? root_window : nullptr;
}
} // namespace aura
diff --git a/ui/aura/window_targeter.h b/ui/aura/window_targeter.h
index 9571f2a..048d8ad 100644
--- a/ui/aura/window_targeter.h
+++ b/ui/aura/window_targeter.h
@@ -5,9 +5,15 @@
#ifndef UI_AURA_WINDOW_TARGETER_H_
#define UI_AURA_WINDOW_TARGETER_H_
+#include "base/macros.h"
#include "ui/aura/aura_export.h"
#include "ui/events/event_targeter.h"
+namespace ui {
+class KeyEvent;
+class LocatedEvent;
+} // namespace ui
+
namespace aura {
class Window;
@@ -17,22 +23,50 @@ class AURA_EXPORT WindowTargeter : public ui::EventTargeter {
WindowTargeter();
~WindowTargeter() override;
+ // Returns true if |window| or one of its descendants can be a target of
+ // |event|. This requires that |window| and its descendants are not
+ // prohibited from accepting the event, and that the event is within an
+ // actionable region of the target's bounds. Note that the location etc. of
+ // |event| is in |window|'s parent's coordinate system.
+ virtual bool SubtreeShouldBeExploredForEvent(Window* window,
+ const ui::LocatedEvent& event);
+
protected:
+ // Same as FindTargetForEvent(), but used for positional events. The location
+ // etc. of |event| are in |root|'s coordinate system. When finding the target
+ // for the event, the targeter can mutate the |event| (e.g. change the
+ // coordinate to be in the returned target's coordinate system) so that it can
+ // be dispatched to the target without any further modification.
+ virtual Window* FindTargetForLocatedEvent(Window* window,
+ ui::LocatedEvent* event);
+
+ // Returns false if neither |window| nor any of its descendants are allowed
+ // to accept |event| for reasons unrelated to the event's location or the
+ // target's bounds. For example, overrides of this function may consider
+ // attributes such as the visibility or enabledness of |window|. Note that
+ // the location etc. of |event| is in |window|'s parent's coordinate system.
+ virtual bool SubtreeCanAcceptEvent(Window* window,
+ const ui::LocatedEvent& event) const;
+
+ // Returns whether the location of the event is in an actionable region of the
+ // target. Note that the location etc. of |event| is in the |window|'s
+ // parent's coordinate system.
+ virtual bool EventLocationInsideBounds(Window* target,
+ const ui::LocatedEvent& event) const;
+
// ui::EventTargeter:
ui::EventTarget* FindTargetForEvent(ui::EventTarget* root,
ui::Event* event) override;
- ui::EventTarget* FindTargetForLocatedEvent(ui::EventTarget* root,
- ui::LocatedEvent* event) override;
- bool SubtreeCanAcceptEvent(ui::EventTarget* target,
- const ui::LocatedEvent& event) const override;
- bool EventLocationInsideBounds(ui::EventTarget* target,
- const ui::LocatedEvent& event) const override;
+ ui::EventTarget* FindNextBestTarget(ui::EventTarget* previous_target,
+ ui::Event* event) override;
private:
- Window* FindTargetForKeyEvent(Window* root_window,
- const ui::KeyEvent& event);
+ Window* FindTargetForKeyEvent(Window* root_window, const ui::KeyEvent& event);
+ Window* FindTargetForNonKeyEvent(Window* root_window, ui::Event* event);
Window* FindTargetInRootWindow(Window* root_window,
const ui::LocatedEvent& event);
+ Window* FindTargetForLocatedEventRecursively(Window* root_window,
+ ui::LocatedEvent* event);
DISALLOW_COPY_AND_ASSIGN(WindowTargeter);
};
diff --git a/ui/aura/window_targeter_unittest.cc b/ui/aura/window_targeter_unittest.cc
index 02217271..14dea71 100644
--- a/ui/aura/window_targeter_unittest.cc
+++ b/ui/aura/window_targeter_unittest.cc
@@ -14,16 +14,16 @@
namespace aura {
// Always returns the same window.
-class StaticWindowTargeter : public ui::EventTargeter {
+class StaticWindowTargeter : public WindowTargeter {
public:
explicit StaticWindowTargeter(aura::Window* window)
: window_(window) {}
~StaticWindowTargeter() override {}
private:
- // ui::EventTargeter:
- ui::EventTarget* FindTargetForLocatedEvent(ui::EventTarget* root,
- ui::LocatedEvent* event) override {
+ // aura::WindowTargeter:
+ Window* FindTargetForLocatedEvent(Window* window,
+ ui::LocatedEvent* event) override {
return window_;
}
@@ -175,4 +175,121 @@ TEST_F(WindowTargeterTest, TargetTransformedWindow) {
}
}
+class IdCheckingEventTargeter : public WindowTargeter {
+ public:
+ IdCheckingEventTargeter(int id) : id_(id) {}
+ ~IdCheckingEventTargeter() override {}
+
+ protected:
+ // WindowTargeter:
+ bool SubtreeShouldBeExploredForEvent(Window* window,
+ const ui::LocatedEvent& event) override {
+ return (window->id() == id_ &&
+ WindowTargeter::SubtreeShouldBeExploredForEvent(window, event));
+ }
+
+ private:
+ int id_;
+};
+
+TEST_F(WindowTargeterTest, Bounds) {
+ test::TestWindowDelegate delegate;
+ scoped_ptr<Window> parent(CreateNormalWindow(1, root_window(), &delegate));
+ scoped_ptr<Window> child(CreateNormalWindow(1, parent.get(), &delegate));
+ scoped_ptr<Window> grandchild(CreateNormalWindow(1, child.get(), &delegate));
+
+ parent->SetBounds(gfx::Rect(0, 0, 30, 30));
+ child->SetBounds(gfx::Rect(5, 5, 20, 20));
+ grandchild->SetBounds(gfx::Rect(5, 5, 5, 5));
+
+ ASSERT_EQ(1u, root_window()->children().size());
+ ASSERT_EQ(1u, root_window()->children()[0]->children().size());
+ ASSERT_EQ(1u, root_window()->children()[0]->children()[0]->children().size());
+
+ Window* parent_r = root_window()->children()[0];
+ Window* child_r = parent_r->children()[0];
+ Window* grandchild_r = child_r->children()[0];
+
+ ui::EventTarget* root_target = root_window();
+ ui::EventTargeter* targeter = root_target->GetEventTargeter();
+
+ // Dispatch a mouse event that falls on the parent, but not on the child. When
+ // the default event-targeter used, the event will still reach |grandchild|,
+ // because the default targeter does not look at the bounds.
+ ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(1, 1), gfx::Point(1, 1),
+ ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
+ EXPECT_EQ(parent_r, targeter->FindTargetForEvent(root_target, &mouse));
+
+ // Install a targeter on the |child| that looks at the window id as well
+ // as the bounds and makes sure the event reaches the target only if the id of
+ // the window is equal to 2 (incorrect). This causes the event to get handled
+ // by |parent|.
+ ui::MouseEvent mouse2(ui::ET_MOUSE_MOVED, gfx::Point(8, 8), gfx::Point(8, 8),
+ ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
+ scoped_ptr<ui::EventTargeter> original_targeter = child_r->SetEventTargeter(
+ scoped_ptr<ui::EventTargeter>(new IdCheckingEventTargeter(2)));
+ EXPECT_EQ(parent_r, targeter->FindTargetForEvent(root_target, &mouse2));
+
+ // Now install a targeter on the |child| that looks at the window id as well
+ // as the bounds and makes sure the event reaches the target only if the id of
+ // the window is equal to 1 (correct).
+ ui::MouseEvent mouse3(ui::ET_MOUSE_MOVED, gfx::Point(8, 8), gfx::Point(8, 8),
+ ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
+ child_r->SetEventTargeter(
+ scoped_ptr<ui::EventTargeter>(new IdCheckingEventTargeter(1)));
+ EXPECT_EQ(child_r, targeter->FindTargetForEvent(root_target, &mouse3));
+
+ // restore original WindowTargeter for |child|.
+ child_r->SetEventTargeter(original_targeter.Pass());
+
+ // Target |grandchild| location.
+ ui::MouseEvent second(ui::ET_MOUSE_MOVED, gfx::Point(12, 12),
+ gfx::Point(12, 12), ui::EventTimeForNow(), ui::EF_NONE,
+ ui::EF_NONE);
+ EXPECT_EQ(grandchild_r, targeter->FindTargetForEvent(root_target, &second));
+
+ // Target |child| location.
+ ui::MouseEvent third(ui::ET_MOUSE_MOVED, gfx::Point(8, 8), gfx::Point(8, 8),
+ ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
+ EXPECT_EQ(child_r, targeter->FindTargetForEvent(root_target, &third));
+}
+
+class IgnoreWindowTargeter : public WindowTargeter {
+ public:
+ IgnoreWindowTargeter() {}
+ ~IgnoreWindowTargeter() override {}
+
+ private:
+ // WindowTargeter:
+ bool SubtreeShouldBeExploredForEvent(Window* window,
+ const ui::LocatedEvent& event) override {
+ return false;
+ }
+};
+
+// Verifies that an EventTargeter installed on an EventTarget can dictate
+// whether the target itself can process an event.
+TEST_F(WindowTargeterTest, TargeterChecksOwningEventTarget) {
+ test::TestWindowDelegate delegate;
+ scoped_ptr<Window> child(CreateNormalWindow(1, root_window(), &delegate));
+
+ ui::EventTarget* root_target = root_window();
+ ui::EventTargeter* targeter = root_target->GetEventTargeter();
+
+ ui::MouseEvent mouse(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
+ gfx::Point(10, 10), ui::EventTimeForNow(), ui::EF_NONE,
+ ui::EF_NONE);
+ EXPECT_EQ(child.get(), targeter->FindTargetForEvent(root_target, &mouse));
+
+ // Install an event targeter on |child| which always prevents the target from
+ // receiving event.
+ child->SetEventTargeter(
+ scoped_ptr<ui::EventTargeter>(new IgnoreWindowTargeter()));
+
+ ui::MouseEvent mouse2(ui::ET_MOUSE_MOVED, gfx::Point(10, 10),
+ gfx::Point(10, 10), ui::EventTimeForNow(), ui::EF_NONE,
+ ui::EF_NONE);
+ EXPECT_EQ(root_window(), targeter->FindTargetForEvent(root_target, &mouse2));
+}
+
} // namespace aura
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn
index 4fe11f4..0add919 100644
--- a/ui/events/BUILD.gn
+++ b/ui/events/BUILD.gn
@@ -105,7 +105,6 @@ component("events") {
"event_target.cc",
"event_target.h",
"event_target_iterator.h",
- "event_targeter.cc",
"event_targeter.h",
"event_utils.cc",
"event_utils.h",
@@ -254,6 +253,8 @@ source_set("test_support") {
"test/test_event_processor.h",
"test/test_event_target.cc",
"test/test_event_target.h",
+ "test/test_event_targeter.cc",
+ "test/test_event_targeter.h",
]
public_deps = [
diff --git a/ui/events/event_processor_unittest.cc b/ui/events/event_processor_unittest.cc
index 4bf4f0d..a0ab5b6 100644
--- a/ui/events/event_processor_unittest.cc
+++ b/ui/events/event_processor_unittest.cc
@@ -6,12 +6,14 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event.h"
+#include "ui/events/event_target_iterator.h"
#include "ui/events/event_targeter.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/events_test_utils.h"
#include "ui/events/test/test_event_handler.h"
#include "ui/events/test/test_event_processor.h"
#include "ui/events/test/test_event_target.h"
+#include "ui/events/test/test_event_targeter.h"
typedef std::vector<std::string> HandlerSequenceRecorder;
@@ -23,11 +25,13 @@ class EventProcessorTest : public testing::Test {
EventProcessorTest() {}
~EventProcessorTest() override {}
+ protected:
// testing::Test:
void SetUp() override {
- processor_.SetRoot(scoped_ptr<EventTarget>(new TestEventTarget()));
+ processor_.SetRoot(make_scoped_ptr(new TestEventTarget()));
processor_.Reset();
- root()->SetEventTargeter(make_scoped_ptr(new EventTargeter()));
+ root()->SetEventTargeter(
+ make_scoped_ptr(new TestEventTargeter(root(), false)));
}
TestEventTarget* root() {
@@ -42,7 +46,12 @@ class EventProcessorTest : public testing::Test {
processor_.OnEventFromSource(event);
}
- protected:
+ void SetTarget(TestEventTarget* target) {
+ static_cast<TestEventTargeter*>(root()->GetEventTargeter())
+ ->set_target(target);
+ }
+
+ private:
TestEventProcessor processor_;
DISALLOW_COPY_AND_ASSIGN(EventProcessorTest);
@@ -50,6 +59,9 @@ class EventProcessorTest : public testing::Test {
TEST_F(EventProcessorTest, Basic) {
scoped_ptr<TestEventTarget> child(new TestEventTarget());
+ child->SetEventTargeter(
+ make_scoped_ptr(new TestEventTargeter(child.get(), false)));
+ SetTarget(child.get());
root()->AddChild(child.Pass());
MouseEvent mouse(ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10),
@@ -58,121 +70,12 @@ TEST_F(EventProcessorTest, Basic) {
EXPECT_TRUE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
+ SetTarget(root());
root()->RemoveChild(root()->child_at(0));
DispatchEvent(&mouse);
EXPECT_TRUE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
}
-template<typename T>
-class BoundsEventTargeter : public EventTargeter {
- public:
- ~BoundsEventTargeter() override {}
-
- protected:
- bool SubtreeShouldBeExploredForEvent(
- EventTarget* target, const LocatedEvent& event) override {
- T* t = static_cast<T*>(target);
- return (t->bounds().Contains(event.location()));
- }
-};
-
-class BoundsTestTarget : public TestEventTarget {
- public:
- BoundsTestTarget() {}
- ~BoundsTestTarget() override {}
-
- void set_bounds(gfx::Rect rect) { bounds_ = rect; }
- gfx::Rect bounds() const { return bounds_; }
-
- static void ConvertPointToTarget(BoundsTestTarget* source,
- BoundsTestTarget* target,
- gfx::Point* location) {
- gfx::Vector2d vector;
- if (source->Contains(target)) {
- for (; target && target != source;
- target = static_cast<BoundsTestTarget*>(target->parent())) {
- vector += target->bounds().OffsetFromOrigin();
- }
- *location -= vector;
- } else if (target->Contains(source)) {
- for (; source && source != target;
- source = static_cast<BoundsTestTarget*>(source->parent())) {
- vector += source->bounds().OffsetFromOrigin();
- }
- *location += vector;
- } else {
- NOTREACHED();
- }
- }
-
- private:
- // EventTarget:
- void ConvertEventToTarget(EventTarget* target, LocatedEvent* event) override {
- event->ConvertLocationToTarget(this,
- static_cast<BoundsTestTarget*>(target));
- }
-
- gfx::Rect bounds_;
-
- DISALLOW_COPY_AND_ASSIGN(BoundsTestTarget);
-};
-
-TEST_F(EventProcessorTest, Bounds) {
- scoped_ptr<BoundsTestTarget> parent(new BoundsTestTarget());
- scoped_ptr<BoundsTestTarget> child(new BoundsTestTarget());
- scoped_ptr<BoundsTestTarget> grandchild(new BoundsTestTarget());
-
- parent->set_bounds(gfx::Rect(0, 0, 30, 30));
- child->set_bounds(gfx::Rect(5, 5, 20, 20));
- grandchild->set_bounds(gfx::Rect(5, 5, 5, 5));
-
- child->AddChild(scoped_ptr<TestEventTarget>(grandchild.Pass()));
- parent->AddChild(scoped_ptr<TestEventTarget>(child.Pass()));
- root()->AddChild(scoped_ptr<TestEventTarget>(parent.Pass()));
-
- ASSERT_EQ(1u, root()->child_count());
- ASSERT_EQ(1u, root()->child_at(0)->child_count());
- ASSERT_EQ(1u, root()->child_at(0)->child_at(0)->child_count());
-
- TestEventTarget* parent_r = root()->child_at(0);
- TestEventTarget* child_r = parent_r->child_at(0);
- TestEventTarget* grandchild_r = child_r->child_at(0);
-
- // Dispatch a mouse event that falls on the parent, but not on the child. When
- // the default event-targeter used, the event will still reach |grandchild|,
- // because the default targeter does not look at the bounds.
- MouseEvent mouse(ET_MOUSE_MOVED, gfx::Point(1, 1), gfx::Point(1, 1),
- EventTimeForNow(), EF_NONE, EF_NONE);
- DispatchEvent(&mouse);
- EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
- EXPECT_FALSE(parent_r->DidReceiveEvent(ET_MOUSE_MOVED));
- EXPECT_FALSE(child_r->DidReceiveEvent(ET_MOUSE_MOVED));
- EXPECT_TRUE(grandchild_r->DidReceiveEvent(ET_MOUSE_MOVED));
- grandchild_r->ResetReceivedEvents();
-
- // Now install a targeter on the parent that looks at the bounds and makes
- // sure the event reaches the target only if the location of the event within
- // the bounds of the target.
- MouseEvent mouse2(ET_MOUSE_MOVED, gfx::Point(1, 1), gfx::Point(1, 1),
- EventTimeForNow(), EF_NONE, EF_NONE);
- parent_r->SetEventTargeter(scoped_ptr<EventTargeter>(
- new BoundsEventTargeter<BoundsTestTarget>()));
- DispatchEvent(&mouse2);
- EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
- EXPECT_TRUE(parent_r->DidReceiveEvent(ET_MOUSE_MOVED));
- EXPECT_FALSE(child_r->DidReceiveEvent(ET_MOUSE_MOVED));
- EXPECT_FALSE(grandchild_r->DidReceiveEvent(ET_MOUSE_MOVED));
- parent_r->ResetReceivedEvents();
-
- MouseEvent second(ET_MOUSE_MOVED, gfx::Point(12, 12), gfx::Point(12, 12),
- EventTimeForNow(), EF_NONE, EF_NONE);
- DispatchEvent(&second);
- EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
- EXPECT_FALSE(parent_r->DidReceiveEvent(ET_MOUSE_MOVED));
- EXPECT_FALSE(child_r->DidReceiveEvent(ET_MOUSE_MOVED));
- EXPECT_TRUE(grandchild_r->DidReceiveEvent(ET_MOUSE_MOVED));
-}
-
// ReDispatchEventHandler is used to receive mouse events and forward them
// to a specified EventProcessor. Verifies that the event has the correct
// target and phase both before and after the nested event processing. Also
@@ -216,14 +119,16 @@ class ReDispatchEventHandler : public TestEventHandler {
TEST_F(EventProcessorTest, NestedEventProcessing) {
// Add one child to the default event processor used in this test suite.
scoped_ptr<TestEventTarget> child(new TestEventTarget());
+ SetTarget(child.get());
root()->AddChild(child.Pass());
// Define a second root target and child.
scoped_ptr<EventTarget> second_root_scoped(new TestEventTarget());
TestEventTarget* second_root =
static_cast<TestEventTarget*>(second_root_scoped.get());
- second_root->SetEventTargeter(make_scoped_ptr(new EventTargeter()));
scoped_ptr<TestEventTarget> second_child(new TestEventTarget());
+ second_root->SetEventTargeter(
+ make_scoped_ptr(new TestEventTargeter(second_child.get(), false)));
second_root->AddChild(second_child.Pass());
// Define a second event processor which owns the second root.
@@ -267,6 +172,7 @@ TEST_F(EventProcessorTest, NestedEventProcessing) {
TEST_F(EventProcessorTest, OnEventProcessingFinished) {
scoped_ptr<TestEventTarget> child(new TestEventTarget());
child->set_mark_events_as_handled(true);
+ SetTarget(child.get());
root()->AddChild(child.Pass());
// Dispatch a mouse event. We expect the event to be seen by the target,
@@ -286,6 +192,7 @@ TEST_F(EventProcessorTest, OnEventProcessingFinished) {
// OnEventProcessingFinished() is also called in either case.
TEST_F(EventProcessorTest, OnEventProcessingStarted) {
scoped_ptr<TestEventTarget> child(new TestEventTarget());
+ SetTarget(child.get());
root()->AddChild(child.Pass());
// Dispatch a mouse event. We expect the event to be seen by the target,
@@ -319,77 +226,15 @@ TEST_F(EventProcessorTest, OnEventProcessingStarted) {
EXPECT_EQ(1, processor()->num_times_processing_finished());
}
-class IgnoreEventTargeter : public EventTargeter {
- public:
- IgnoreEventTargeter() {}
- ~IgnoreEventTargeter() override {}
-
- private:
- // EventTargeter:
- bool SubtreeShouldBeExploredForEvent(EventTarget* target,
- const LocatedEvent& event) override {
- return false;
- }
-};
-
-// Verifies that the EventTargeter installed on an EventTarget can dictate
-// whether the target itself can process an event.
-TEST_F(EventProcessorTest, TargeterChecksOwningEventTarget) {
- scoped_ptr<TestEventTarget> child(new TestEventTarget());
- root()->AddChild(child.Pass());
-
- MouseEvent mouse(ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10),
- EventTimeForNow(), EF_NONE, EF_NONE);
- DispatchEvent(&mouse);
- EXPECT_TRUE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
- EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
- root()->child_at(0)->ResetReceivedEvents();
-
- // Install an event handler on |child| which always prevents the target from
- // receiving event.
- root()->child_at(0)->SetEventTargeter(
- scoped_ptr<EventTargeter>(new IgnoreEventTargeter()));
- MouseEvent mouse2(ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10),
- EventTimeForNow(), EF_NONE, EF_NONE);
- DispatchEvent(&mouse2);
- EXPECT_FALSE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
- EXPECT_TRUE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
-}
-
-// An EventTargeter which is used to allow a bubbling behaviour in event
-// dispatch: if an event is not handled after being dispatched to its
-// initial target, the event is dispatched to the next-best target as
-// specified by FindNextBestTarget().
-class BubblingEventTargeter : public EventTargeter {
- public:
- explicit BubblingEventTargeter(TestEventTarget* initial_target)
- : initial_target_(initial_target) {}
- ~BubblingEventTargeter() override {}
-
- private:
- // EventTargeter:
- EventTarget* FindTargetForEvent(EventTarget* root, Event* event) override {
- return initial_target_;
- }
-
- EventTarget* FindNextBestTarget(EventTarget* previous_target,
- Event* event) override {
- return previous_target->GetParentTarget();
- }
-
- TestEventTarget* initial_target_;
-
- DISALLOW_COPY_AND_ASSIGN(BubblingEventTargeter);
-};
-
// Tests that unhandled events are correctly dispatched to the next-best
-// target as decided by the BubblingEventTargeter.
+// target as decided by the TestEventTargeter.
TEST_F(EventProcessorTest, DispatchToNextBestTarget) {
scoped_ptr<TestEventTarget> child(new TestEventTarget());
scoped_ptr<TestEventTarget> grandchild(new TestEventTarget());
+ // Install a TestEventTargeter which permits bubbling.
root()->SetEventTargeter(
- scoped_ptr<EventTargeter>(new BubblingEventTargeter(grandchild.get())));
+ make_scoped_ptr(new TestEventTargeter(grandchild.get(), true)));
child->AddChild(grandchild.Pass());
root()->AddChild(child.Pass());
@@ -400,8 +245,9 @@ TEST_F(EventProcessorTest, DispatchToNextBestTarget) {
TestEventTarget* child_r = root()->child_at(0);
TestEventTarget* grandchild_r = child_r->child_at(0);
- // When the root has a BubblingEventTargeter installed, events targeted
- // at the grandchild target should be dispatched to all three targets.
+ // When the root has a TestEventTargeter installed which permits bubbling,
+ // events targeted at the grandchild target should be dispatched to all three
+ // targets.
KeyEvent key_event(ET_KEY_PRESSED, VKEY_ESCAPE, EF_NONE);
DispatchEvent(&key_event);
EXPECT_TRUE(root()->DidReceiveEvent(ET_KEY_PRESSED));
@@ -455,13 +301,14 @@ TEST_F(EventProcessorTest, DispatchToNextBestTarget) {
// Tests that unhandled events are seen by the correct sequence of
// targets, pre-target handlers, and post-target handlers when
-// a BubblingEventTargeter is installed on the root target.
+// a TestEventTargeter is installed on the root target which permits bubbling.
TEST_F(EventProcessorTest, HandlerSequence) {
scoped_ptr<TestEventTarget> child(new TestEventTarget());
scoped_ptr<TestEventTarget> grandchild(new TestEventTarget());
+ // Install a TestEventTargeter which permits bubbling.
root()->SetEventTargeter(
- scoped_ptr<EventTargeter>(new BubblingEventTargeter(grandchild.get())));
+ make_scoped_ptr(new TestEventTargeter(grandchild.get(), true)));
child->AddChild(grandchild.Pass());
root()->AddChild(child.Pass());
diff --git a/ui/events/event_targeter.cc b/ui/events/event_targeter.cc
deleted file mode 100644
index 5d43b29..0000000
--- a/ui/events/event_targeter.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/events/event_targeter.h"
-
-#include "ui/events/event.h"
-#include "ui/events/event_target.h"
-#include "ui/events/event_target_iterator.h"
-
-namespace ui {
-
-EventTargeter::~EventTargeter() {
-}
-
-EventTarget* EventTargeter::FindTargetForEvent(EventTarget* root,
- Event* event) {
- if (event->IsMouseEvent() ||
- event->IsScrollEvent() ||
- event->IsTouchEvent() ||
- event->IsGestureEvent()) {
- return FindTargetForLocatedEvent(root,
- static_cast<LocatedEvent*>(event));
- }
- return root;
-}
-
-EventTarget* EventTargeter::FindTargetForLocatedEvent(EventTarget* root,
- LocatedEvent* event) {
- scoped_ptr<EventTargetIterator> iter = root->GetChildIterator();
- if (iter) {
- EventTarget* target = root;
- for (EventTarget* child = iter->GetNextTarget(); child;
- child = iter->GetNextTarget()) {
- EventTargeter* targeter = child->GetEventTargeter();
- if (!targeter)
- targeter = this;
- if (!targeter->SubtreeShouldBeExploredForEvent(child, *event))
- continue;
- target->ConvertEventToTarget(child, event);
- target = child;
- EventTarget* child_target =
- targeter->FindTargetForLocatedEvent(child, event);
- if (child_target)
- return child_target;
- }
- target->ConvertEventToTarget(root, event);
- }
- return root->CanAcceptEvent(*event) ? root : NULL;
-}
-
-bool EventTargeter::SubtreeShouldBeExploredForEvent(EventTarget* target,
- const LocatedEvent& event) {
- return SubtreeCanAcceptEvent(target, event) &&
- EventLocationInsideBounds(target, event);
-}
-
-EventTarget* EventTargeter::FindNextBestTarget(EventTarget* previous_target,
- Event* event) {
- return NULL;
-}
-
-bool EventTargeter::SubtreeCanAcceptEvent(EventTarget* target,
- const LocatedEvent& event) const {
- return true;
-}
-
-bool EventTargeter::EventLocationInsideBounds(EventTarget* target,
- const LocatedEvent& event) const {
- return true;
-}
-
-} // namespace ui
diff --git a/ui/events/event_targeter.h b/ui/events/event_targeter.h
index 23b1261..fbe7a0e 100644
--- a/ui/events/event_targeter.h
+++ b/ui/events/event_targeter.h
@@ -6,18 +6,16 @@
#define UI_EVENTS_EVENT_TARGETER_H_
#include "base/compiler_specific.h"
-#include "ui/events/event.h"
#include "ui/events/events_export.h"
namespace ui {
class Event;
class EventTarget;
-class LocatedEvent;
class EVENTS_EXPORT EventTargeter {
public:
- virtual ~EventTargeter();
+ virtual ~EventTargeter() {}
// Returns the target |event| should be dispatched to. If there is no such
// target, return NULL. If |event| is a located event, the location of |event|
@@ -25,28 +23,7 @@ class EVENTS_EXPORT EventTargeter {
// the event (e.g., by changing the location of the event to be in the
// returned target's coordinate space) so that it can be dispatched to the
// target without any further modification.
- virtual EventTarget* FindTargetForEvent(EventTarget* root,
- Event* event);
-
- // Same as FindTargetForEvent(), but used for positional events. The location
- // etc. of |event| are in |root|'s coordinate system. When finding the target
- // for the event, the targeter can mutate the |event| (e.g. change the
- // coordinate to be in the returned target's coordinate system) so that it can
- // be dispatched to the target without any further modification.
- // TODO(tdanderson|sadrul): This should not be in the public API of
- // EventTargeter.
- virtual EventTarget* FindTargetForLocatedEvent(EventTarget* root,
- LocatedEvent* event);
-
- // Returns true if |target| or one of its descendants can be a target of
- // |event|. This requires that |target| and its descendants are not
- // prohibited from accepting the event, and that the event is within an
- // actionable region of the target's bounds. Note that the location etc. of
- // |event| is in |target|'s parent's coordinate system.
- // TODO(tdanderson|sadrul): This function should be made non-virtual and
- // non-public.
- virtual bool SubtreeShouldBeExploredForEvent(EventTarget* target,
- const LocatedEvent& event);
+ virtual EventTarget* FindTargetForEvent(EventTarget* root, Event* event) = 0;
// Returns the next best target for |event| as compared to |previous_target|.
// |event| is in the local coordinate space of |previous_target|.
@@ -54,22 +31,7 @@ class EVENTS_EXPORT EventTargeter {
// (e.g., by changing |event|'s location to be in the returned target's
// coordinate space).
virtual EventTarget* FindNextBestTarget(EventTarget* previous_target,
- Event* event);
-
- protected:
- // Returns false if neither |target| nor any of its descendants are allowed
- // to accept |event| for reasons unrelated to the event's location or the
- // target's bounds. For example, overrides of this function may consider
- // attributes such as the visibility or enabledness of |target|. Note that
- // the location etc. of |event| is in |target|'s parent's coordinate system.
- virtual bool SubtreeCanAcceptEvent(EventTarget* target,
- const LocatedEvent& event) const;
-
- // Returns whether the location of the event is in an actionable region of the
- // target. Note that the location etc. of |event| is in the |target|'s
- // parent's coordinate system.
- virtual bool EventLocationInsideBounds(EventTarget* target,
- const LocatedEvent& event) const;
+ Event* event) = 0;
};
} // namespace ui
diff --git a/ui/events/events.gyp b/ui/events/events.gyp
index aea07ae..a914952 100644
--- a/ui/events/events.gyp
+++ b/ui/events/events.gyp
@@ -126,7 +126,6 @@
'event_target.cc',
'event_target.h',
'event_target_iterator.h',
- 'event_targeter.cc',
'event_targeter.h',
'event_utils.cc',
'event_utils.h',
@@ -324,6 +323,8 @@
'test/test_event_processor.h',
'test/test_event_target.cc',
'test/test_event_target.h',
+ 'test/test_event_targeter.cc',
+ 'test/test_event_targeter.h',
],
'conditions': [
['OS=="ios"', {
diff --git a/ui/events/null_event_targeter.cc b/ui/events/null_event_targeter.cc
index 8907384..9a946a9 100644
--- a/ui/events/null_event_targeter.cc
+++ b/ui/events/null_event_targeter.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/logging.h"
#include "ui/events/null_event_targeter.h"
namespace ui {
@@ -17,4 +18,10 @@ EventTarget* NullEventTargeter::FindTargetForEvent(EventTarget* root,
return nullptr;
}
+EventTarget* NullEventTargeter::FindNextBestTarget(EventTarget* previous_target,
+ Event* event) {
+ NOTREACHED();
+ return nullptr;
+}
+
} // namespace ui
diff --git a/ui/events/null_event_targeter.h b/ui/events/null_event_targeter.h
index 010c060..c22e7a7 100644
--- a/ui/events/null_event_targeter.h
+++ b/ui/events/null_event_targeter.h
@@ -3,17 +3,23 @@
// found in the LICENSE file.
#include "base/compiler_specific.h"
+#include "base/macros.h"
#include "ui/events/event_targeter.h"
#include "ui/events/events_export.h"
namespace ui {
+// NullEventTargeter can be installed on a root window to prevent it from
+// dispatching events such as during shutdown.
class EVENTS_EXPORT NullEventTargeter : public EventTargeter {
public:
NullEventTargeter();
~NullEventTargeter() override;
+ // EventTargeter:
EventTarget* FindTargetForEvent(EventTarget* root, Event* event) override;
+ EventTarget* FindNextBestTarget(EventTarget* previous_target,
+ Event* event) override;
private:
DISALLOW_COPY_AND_ASSIGN(NullEventTargeter);
diff --git a/ui/events/test/test_event_target.h b/ui/events/test/test_event_target.h
index 17969be..06ddc99 100644
--- a/ui/events/test/test_event_target.h
+++ b/ui/events/test/test_event_target.h
@@ -50,6 +50,9 @@ class TestEventTarget : public EventTarget {
target_name_ = target_name;
}
+ // EventTarget:
+ EventTargeter* GetEventTargeter() override;
+
protected:
bool Contains(TestEventTarget* target) const;
@@ -57,7 +60,6 @@ class TestEventTarget : public EventTarget {
bool CanAcceptEvent(const ui::Event& event) override;
EventTarget* GetParentTarget() override;
scoped_ptr<EventTargetIterator> GetChildIterator() const override;
- EventTargeter* GetEventTargeter() override;
// EventHandler:
void OnEvent(Event* event) override;
diff --git a/ui/events/test/test_event_targeter.cc b/ui/events/test/test_event_targeter.cc
new file mode 100644
index 0000000..0794d45
--- /dev/null
+++ b/ui/events/test/test_event_targeter.cc
@@ -0,0 +1,37 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/test/test_event_targeter.h"
+
+#include "ui/events/test/test_event_target.h"
+
+namespace ui {
+namespace test {
+
+TestEventTargeter::TestEventTargeter(TestEventTarget* initial_target,
+ bool should_bubble)
+ : target_(initial_target), should_bubble_(should_bubble) {
+}
+
+TestEventTargeter::~TestEventTargeter() {
+}
+
+void TestEventTargeter::set_target(TestEventTarget* target) {
+ target_ = target;
+}
+
+EventTarget* TestEventTargeter::FindTargetForEvent(EventTarget* root,
+ Event* event) {
+ return target_;
+}
+
+EventTarget* TestEventTargeter::FindNextBestTarget(EventTarget* previous_target,
+ Event* event) {
+ if (!should_bubble_)
+ return nullptr;
+ return previous_target->GetParentTarget();
+}
+
+} // namespace test
+} // namespace ui
diff --git a/ui/events/test/test_event_targeter.h b/ui/events/test/test_event_targeter.h
new file mode 100644
index 0000000..ee2502c
--- /dev/null
+++ b/ui/events/test/test_event_targeter.h
@@ -0,0 +1,44 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_EVENTS_TEST_TEST_EVENT_TARGETER_H_
+#define UI_EVENTS_TEST_TEST_EVENT_TARGETER_H_
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "ui/events/event_targeter.h"
+
+namespace ui {
+namespace test {
+
+class TestEventTarget;
+
+// An EventTargeter which is used to allow a bubbling behaviour in event
+// dispatch: if an event is not handled after being dispatched to its
+// |initial_target|, the event is dispatched to the next-best target as
+// specified by FindNextBestTarget().
+// Bubbling behaviour is controlled by |should_bubble| at creation time.
+class TestEventTargeter : public EventTargeter {
+ public:
+ TestEventTargeter(TestEventTarget* initial_target, bool should_bubble);
+ ~TestEventTargeter() override;
+
+ void set_target(TestEventTarget* target);
+
+ private:
+ // EventTargeter:
+ EventTarget* FindTargetForEvent(EventTarget* root, Event* event) override;
+ EventTarget* FindNextBestTarget(EventTarget* previous_target,
+ Event* event) override;
+
+ TestEventTarget* target_;
+ bool should_bubble_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestEventTargeter);
+};
+
+} // namespace test
+} // namespace ui
+
+#endif // UI_EVENTS_TEST_TEST_EVENT_TARGETER_H_
diff --git a/ui/views/test/event_generator_delegate_mac.mm b/ui/views/test/event_generator_delegate_mac.mm
index 5bd4537..4e4a32b 100644
--- a/ui/views/test/event_generator_delegate_mac.mm
+++ b/ui/views/test/event_generator_delegate_mac.mm
@@ -236,7 +236,7 @@ class EventGeneratorDelegateMac : public ui::EventTarget,
// Overridden from ui::EventTarget:
bool CanAcceptEvent(const ui::Event& event) override { return true; }
- ui::EventTarget* GetParentTarget() override { return NULL; }
+ ui::EventTarget* GetParentTarget() override { return nullptr; }
scoped_ptr<ui::EventTargetIterator> GetChildIterator() const override;
ui::EventTargeter* GetEventTargeter() override { return this; }
@@ -254,6 +254,16 @@ class EventGeneratorDelegateMac : public ui::EventTarget,
// Overridden from ui::EventDispatcherDelegate (via ui::EventProcessor):
bool CanDispatchToTarget(EventTarget* target) override { return true; }
+ // Overridden from ui::EventTargeter:
+ ui::EventTarget* FindTargetForEvent(ui::EventTarget* root,
+ ui::Event* event) override {
+ return root;
+ }
+ ui::EventTarget* FindNextBestTarget(ui::EventTarget* previous_target,
+ ui::Event* event) override {
+ return nullptr;
+ }
+
// Overridden from ui::test::EventGeneratorDelegate:
void SetContext(ui::test::EventGenerator* owner,
gfx::NativeWindow root_window,
@@ -290,7 +300,7 @@ class EventGeneratorDelegateMac : public ui::EventTarget,
DISALLOW_COPY_AND_ASSIGN(EventGeneratorDelegateMac);
};
-EventGeneratorDelegateMac::EventGeneratorDelegateMac() : owner_(NULL) {
+EventGeneratorDelegateMac::EventGeneratorDelegateMac() : owner_(nullptr) {
DCHECK(!ui::test::EventGenerator::default_delegate);
ui::test::EventGenerator::default_delegate = this;
// Install a fake "edit" menu. This is normally provided by Chrome's
@@ -318,12 +328,12 @@ EventGeneratorDelegateMac::EventGeneratorDelegateMac() : owner_(NULL) {
EventGeneratorDelegateMac::~EventGeneratorDelegateMac() {
DCHECK_EQ(this, ui::test::EventGenerator::default_delegate);
- ui::test::EventGenerator::default_delegate = NULL;
+ ui::test::EventGenerator::default_delegate = nullptr;
}
scoped_ptr<ui::EventTargetIterator>
EventGeneratorDelegateMac::GetChildIterator() const {
- // Return NULL to dispatch all events to the result of GetRootTarget().
+ // Return nullptr to dispatch all events to the result of GetRootTarget().
return nullptr;
}
diff --git a/ui/views/view_targeter.cc b/ui/views/view_targeter.cc
index 3c5af01..5e52ce9 100644
--- a/ui/views/view_targeter.cc
+++ b/ui/views/view_targeter.cc
@@ -67,20 +67,6 @@ ui::EventTarget* ViewTargeter::FindNextBestTarget(
return previous_target->GetParentTarget();
}
-bool ViewTargeter::SubtreeCanAcceptEvent(
- ui::EventTarget* target,
- const ui::LocatedEvent& event) const {
- NOTREACHED();
- return false;
-}
-
-bool ViewTargeter::EventLocationInsideBounds(
- ui::EventTarget* target,
- const ui::LocatedEvent& event) const {
- NOTREACHED();
- return false;
-}
-
View* ViewTargeter::FindTargetForKeyEvent(View* root, const ui::KeyEvent& key) {
if (root->GetFocusManager())
return root->GetFocusManager()->GetFocusedView();
diff --git a/ui/views/view_targeter.h b/ui/views/view_targeter.h
index db52e66..3e460ca 100644
--- a/ui/views/view_targeter.h
+++ b/ui/views/view_targeter.h
@@ -5,9 +5,20 @@
#ifndef UI_VIEWS_VIEW_TARGETER_H_
#define UI_VIEWS_VIEW_TARGETER_H_
+#include "base/macros.h"
#include "ui/events/event_targeter.h"
#include "ui/views/views_export.h"
+namespace gfx {
+class Rect;
+} // namespace gfx
+
+namespace ui {
+class GestureEvent;
+class KeyEvent;
+class ScrollEvent;
+} // namespace ui
+
namespace views {
namespace internal {
@@ -36,10 +47,6 @@ class VIEWS_EXPORT ViewTargeter : public ui::EventTargeter {
ui::Event* event) override;
ui::EventTarget* FindNextBestTarget(ui::EventTarget* previous_target,
ui::Event* event) override;
- bool SubtreeCanAcceptEvent(ui::EventTarget* target,
- const ui::LocatedEvent& event) const override;
- bool EventLocationInsideBounds(ui::EventTarget* target,
- const ui::LocatedEvent& event) const override;
private:
View* FindTargetForKeyEvent(View* root, const ui::KeyEvent& key);
diff --git a/ui/wm/core/easy_resize_window_targeter.cc b/ui/wm/core/easy_resize_window_targeter.cc
index 445028c..c286bc2 100644
--- a/ui/wm/core/easy_resize_window_targeter.cc
+++ b/ui/wm/core/easy_resize_window_targeter.cc
@@ -5,6 +5,7 @@
#include "ui/wm/core/easy_resize_window_targeter.h"
#include "ui/aura/window.h"
+#include "ui/events/event.h"
#include "ui/gfx/geometry/insets_f.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/wm/public/transient_window_client.h"
@@ -24,9 +25,8 @@ EasyResizeWindowTargeter::~EasyResizeWindowTargeter() {
}
bool EasyResizeWindowTargeter::EventLocationInsideBounds(
- ui::EventTarget* target,
+ aura::Window* window,
const ui::LocatedEvent& event) const {
- aura::Window* window = static_cast<aura::Window*>(target);
if (ShouldUseExtendedBounds(window)) {
// Note that |event|'s location is in |window|'s parent's coordinate system,
// so convert it to |window|'s coordinate system first.
@@ -48,7 +48,7 @@ bool EasyResizeWindowTargeter::EventLocationInsideBounds(
bool EasyResizeWindowTargeter::ShouldUseExtendedBounds(
const aura::Window* window) const {
// Use the extended bounds only for immediate child windows of |container_|.
- // Use the default targetter otherwise.
+ // Use the default targeter otherwise.
if (window->parent() != container_)
return false;
diff --git a/ui/wm/core/easy_resize_window_targeter.h b/ui/wm/core/easy_resize_window_targeter.h
index 2543a23..c6a47af 100644
--- a/ui/wm/core/easy_resize_window_targeter.h
+++ b/ui/wm/core/easy_resize_window_targeter.h
@@ -31,8 +31,8 @@ class WM_EXPORT EasyResizeWindowTargeter : public aura::WindowTargeter {
touch_extend_ = touch_extend;
}
- // ui::EventTargeter:
- bool EventLocationInsideBounds(ui::EventTarget* target,
+ // aura::WindowTargeter:
+ bool EventLocationInsideBounds(aura::Window* window,
const ui::LocatedEvent& event) const override;
private:
diff --git a/ui/wm/core/masked_window_targeter.cc b/ui/wm/core/masked_window_targeter.cc
index 5cbdb19..74e8bc8 100644
--- a/ui/wm/core/masked_window_targeter.cc
+++ b/ui/wm/core/masked_window_targeter.cc
@@ -5,6 +5,7 @@
#include "ui/wm/core/masked_window_targeter.h"
#include "ui/aura/window.h"
+#include "ui/events/event.h"
#include "ui/gfx/path.h"
namespace wm {
@@ -16,9 +17,8 @@ MaskedWindowTargeter::MaskedWindowTargeter(aura::Window* masked_window)
MaskedWindowTargeter::~MaskedWindowTargeter() {}
bool MaskedWindowTargeter::EventLocationInsideBounds(
- ui::EventTarget* target,
+ aura::Window* window,
const ui::LocatedEvent& event) const {
- aura::Window* window = static_cast<aura::Window*>(target);
if (window == masked_window_) {
gfx::Path mask;
if (!GetHitTestMask(window, &mask))
diff --git a/ui/wm/core/masked_window_targeter.h b/ui/wm/core/masked_window_targeter.h
index cc209f3..00617bf 100644
--- a/ui/wm/core/masked_window_targeter.h
+++ b/ui/wm/core/masked_window_targeter.h
@@ -24,8 +24,8 @@ class WM_EXPORT MaskedWindowTargeter : public aura::WindowTargeter {
// coordinate system). Returns whether a valid mask has been set in |mask|.
virtual bool GetHitTestMask(aura::Window* window, gfx::Path* mask) const = 0;
- // ui::EventTargeter:
- bool EventLocationInsideBounds(ui::EventTarget* target,
+ // aura::WindowTargeter:
+ bool EventLocationInsideBounds(aura::Window* target,
const ui::LocatedEvent& event) const override;
private: