diff options
author | varkha <varkha@chromium.org> | 2015-06-11 11:32:58 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-11 18:33:28 +0000 |
commit | 9c6bcf714a44413a5bf00a4cd346197d854464e6 (patch) | |
tree | 9e5ef1a4674fb913bfa9495964ffd0085cb972c9 | |
parent | fd6b78bc2cac155f67f0bd09c184645353f7d6b9 (diff) | |
download | chromium_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}
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: |