1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/aura/window_targeter.h"
7 #include "ui/aura/client/capture_client.h"
8 #include "ui/aura/client/event_client.h"
9 #include "ui/aura/client/focus_client.h"
10 #include "ui/aura/root_window.h"
11 #include "ui/aura/window.h"
12 #include "ui/aura/window_delegate.h"
13 #include "ui/events/event_target.h"
17 WindowTargeter::WindowTargeter() {}
18 WindowTargeter::~WindowTargeter() {}
20 bool WindowTargeter::WindowCanAcceptEvent(aura::Window* window,
21 const ui::LocatedEvent& event) const {
22 if (!window->IsVisible())
24 if (window->ignore_events())
26 client::EventClient* client = client::GetEventClient(window->GetRootWindow());
27 if (client && !client->CanProcessEventsWithinSubtree(window))
30 Window* parent = window->parent();
31 if (parent && parent->delegate_ && !parent->delegate_->
32 ShouldDescendIntoChildForEventHandling(window, event.location())) {
38 bool WindowTargeter::EventLocationInsideBounds(
39 aura::Window* window, const ui::LocatedEvent& event) const {
40 gfx::Point point = event.location();
42 aura::Window::ConvertPointToTarget(window->parent(), window, &point);
43 return gfx::Rect(window->bounds().size()).Contains(point);
46 ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root,
48 if (event->IsKeyEvent()) {
49 Window* window = static_cast<Window*>(root);
50 Window* root_window = window->GetRootWindow();
51 const ui::KeyEvent& key = static_cast<const ui::KeyEvent&>(*event);
52 if (key.key_code() == ui::VKEY_UNKNOWN)
54 client::EventClient* event_client = client::GetEventClient(root_window);
55 client::FocusClient* focus_client = client::GetFocusClient(root_window);
56 Window* focused_window = focus_client->GetFocusedWindow();
58 !event_client->CanProcessEventsWithinSubtree(focused_window)) {
59 focus_client->FocusWindow(NULL);
62 return focused_window ? focused_window : window;
64 return EventTargeter::FindTargetForEvent(root, event);
67 bool WindowTargeter::SubtreeShouldBeExploredForEvent(
68 ui::EventTarget* root,
69 const ui::LocatedEvent& event) {
70 Window* window = static_cast<Window*>(root);
71 if (!WindowCanAcceptEvent(window, event))
74 return EventLocationInsideBounds(window, event);
77 ui::EventTarget* WindowTargeter::FindTargetForLocatedEvent(
78 ui::EventTarget* root,
79 ui::LocatedEvent* event) {
80 Window* window = static_cast<Window*>(root);
81 if (!window->parent()) {
82 Window* target = FindTargetInRootWindow(window, *event);
84 window->ConvertEventToTarget(target, event);
88 return EventTargeter::FindTargetForLocatedEvent(root, event);
91 Window* WindowTargeter::FindTargetInRootWindow(Window* root_window,
92 const ui::LocatedEvent& event) {
93 DCHECK_EQ(root_window, root_window->GetRootWindow());
95 // Mouse events should be dispatched to the window that processed the
96 // mouse-press events (if any).
97 if (event.IsScrollEvent() || event.IsMouseEvent()) {
98 WindowEventDispatcher* dispatcher = root_window->GetDispatcher();
99 if (dispatcher->mouse_pressed_handler())
100 return dispatcher->mouse_pressed_handler();
103 // All events should be directed towards the capture window (if any).
104 Window* capture_window = client::GetCaptureWindow(root_window);
106 return capture_window;
108 if (event.IsTouchEvent()) {
109 // Query the gesture-recognizer to find targets for touch events.
110 const ui::TouchEvent& touch = static_cast<const ui::TouchEvent&>(event);
111 ui::GestureConsumer* consumer =
112 ui::GestureRecognizer::Get()->GetTouchLockedTarget(touch);
114 return static_cast<Window*>(consumer);
116 ui::GestureRecognizer::Get()->GetTargetForLocation(
117 event.location(), touch.source_device_id());
119 return static_cast<Window*>(consumer);
121 // If the initial touch is outside the root window, target the root.
122 if (!root_window->bounds().Contains(event.location()))