Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(371)

Side by Side Diff: ui/aura/window_targeter.cc

Issue 1119423003: Refactors away method implementations in ui::EventTargeter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Refactors away method implementations in ui::EventTargeter (moves tests to aura) Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/aura/window_targeter.h" 5 #include "ui/aura/window_targeter.h"
6 6
7 #include "ui/aura/client/capture_client.h" 7 #include "ui/aura/client/capture_client.h"
8 #include "ui/aura/client/event_client.h" 8 #include "ui/aura/client/event_client.h"
9 #include "ui/aura/client/focus_client.h" 9 #include "ui/aura/client/focus_client.h"
10 #include "ui/aura/window.h" 10 #include "ui/aura/window.h"
11 #include "ui/aura/window_delegate.h" 11 #include "ui/aura/window_delegate.h"
12 #include "ui/aura/window_event_dispatcher.h" 12 #include "ui/aura/window_event_dispatcher.h"
13 #include "ui/aura/window_tree_host.h" 13 #include "ui/aura/window_tree_host.h"
14 #include "ui/events/event_target.h" 14 #include "ui/events/event_target.h"
15 #include "ui/events/event_target_iterator.h"
15 16
16 namespace aura { 17 namespace aura {
17 18
18 namespace {
19
20 bool IsLocatedEvent(const ui::Event& event) {
21 return event.IsMouseEvent() || event.IsTouchEvent() ||
22 event.IsScrollEvent() || event.IsGestureEvent();
23 }
24
25 } // namespace
26
27 WindowTargeter::WindowTargeter() {} 19 WindowTargeter::WindowTargeter() {}
28 WindowTargeter::~WindowTargeter() {} 20 WindowTargeter::~WindowTargeter() {}
29 21
30 ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root, 22 ui::EventTarget* WindowTargeter::FindTargetForLocatedEvent(
31 ui::Event* event) { 23 ui::EventTarget* root,
24 ui::LocatedEvent* event) {
32 Window* window = static_cast<Window*>(root); 25 Window* window = static_cast<Window*>(root);
33 Window* target = event->IsKeyEvent() ? 26 if (!window->parent()) {
34 FindTargetForKeyEvent(window, *static_cast<ui::KeyEvent*>(event)) : 27 Window* target = FindTargetInRootWindow(window, *event);
35 static_cast<Window*>(EventTargeter::FindTargetForEvent(root, event)); 28 if (target) {
36 if (target && !window->parent() && !window->Contains(target)) { 29 window->ConvertEventToTarget(target, event);
37 // |window| is the root window, but |target| is not a descendent of 30 return target;
38 // |window|. So do not allow dispatching from here. Instead, dispatch the
39 // event through the WindowEventDispatcher that owns |target|.
40 aura::Window* new_root = target->GetRootWindow();
41 if (IsLocatedEvent(*event)) {
42 // The event has been transformed to be in |target|'s coordinate system.
43 // But dispatching the event through the EventProcessor requires the event
44 // to be in the host's coordinate system. So, convert the event to be in
45 // the root's coordinate space, and then to the host's coordinate space by
46 // applying the host's transform.
47 ui::LocatedEvent* located_event = static_cast<ui::LocatedEvent*>(event);
48 located_event->ConvertLocationToTarget(target, new_root);
49 located_event->UpdateForRootTransform(
50 new_root->GetHost()->GetRootTransform());
51 } 31 }
52 ignore_result(
53 new_root->GetHost()->event_processor()->OnEventFromSource(event));
54
55 target = NULL;
56 } 32 }
57 return target; 33 return FindTargetForEventRecursively(window, event);
58 } 34 }
59 35
60 bool WindowTargeter::SubtreeCanAcceptEvent( 36 bool WindowTargeter::SubtreeCanAcceptEvent(
61 ui::EventTarget* target, 37 ui::EventTarget* target,
62 const ui::LocatedEvent& event) const { 38 const ui::LocatedEvent& event) const {
63 aura::Window* window = static_cast<aura::Window*>(target); 39 aura::Window* window = static_cast<aura::Window*>(target);
64 if (!window->IsVisible()) 40 if (!window->IsVisible())
65 return false; 41 return false;
66 if (window->ignore_events()) 42 if (window->ignore_events())
67 return false; 43 return false;
(...skipping 12 matching lines...) Expand all
80 bool WindowTargeter::EventLocationInsideBounds( 56 bool WindowTargeter::EventLocationInsideBounds(
81 ui::EventTarget* target, 57 ui::EventTarget* target,
82 const ui::LocatedEvent& event) const { 58 const ui::LocatedEvent& event) const {
83 aura::Window* window = static_cast<aura::Window*>(target); 59 aura::Window* window = static_cast<aura::Window*>(target);
84 gfx::Point point = event.location(); 60 gfx::Point point = event.location();
85 if (window->parent()) 61 if (window->parent())
86 aura::Window::ConvertPointToTarget(window->parent(), window, &point); 62 aura::Window::ConvertPointToTarget(window->parent(), window, &point);
87 return gfx::Rect(window->bounds().size()).Contains(point); 63 return gfx::Rect(window->bounds().size()).Contains(point);
88 } 64 }
89 65
90 ui::EventTarget* WindowTargeter::FindTargetForLocatedEvent( 66 ui::EventTarget* WindowTargeter::FindTargetForEvent(ui::EventTarget* root,
91 ui::EventTarget* root, 67 ui::Event* event) {
92 ui::LocatedEvent* event) {
93 Window* window = static_cast<Window*>(root); 68 Window* window = static_cast<Window*>(root);
94 if (!window->parent()) { 69 Window* target =
95 Window* target = FindTargetInRootWindow(window, *event); 70 event->IsKeyEvent()
96 if (target) { 71 ? FindTargetForKeyEvent(window, *static_cast<ui::KeyEvent*>(event))
97 window->ConvertEventToTarget(target, event); 72 : FindTargetForNonKeyEvent(window, event);
98 return target; 73 if (target && !window->parent() && !window->Contains(target)) {
74 // |window| is the root window, but |target| is not a descendent of
75 // |window|. So do not allow dispatching from here. Instead, dispatch the
76 // event through the WindowEventDispatcher that owns |target|.
77 aura::Window* new_root = target->GetRootWindow();
78 if (event->IsLocatedEvent()) {
79 // The event has been transformed to be in |target|'s coordinate system.
80 // But dispatching the event through the EventProcessor requires the event
81 // to be in the host's coordinate system. So, convert the event to be in
82 // the root's coordinate space, and then to the host's coordinate space by
83 // applying the host's transform.
84 ui::LocatedEvent* located_event = static_cast<ui::LocatedEvent*>(event);
85 located_event->ConvertLocationToTarget(target, new_root);
86 located_event->UpdateForRootTransform(
87 new_root->GetHost()->GetRootTransform());
99 } 88 }
89 ignore_result(
90 new_root->GetHost()->event_processor()->OnEventFromSource(event));
91
92 target = NULL;
100 } 93 }
101 return EventTargeter::FindTargetForLocatedEvent(root, event); 94 return target;
95 }
96
97 bool WindowTargeter::SubtreeShouldBeExploredForEvent(
98 ui::EventTarget* target,
99 const ui::LocatedEvent& event) {
100 return SubtreeCanAcceptEvent(target, event) &&
101 EventLocationInsideBounds(target, event);
102 } 102 }
103 103
104 Window* WindowTargeter::FindTargetForKeyEvent(Window* window, 104 Window* WindowTargeter::FindTargetForKeyEvent(Window* window,
105 const ui::KeyEvent& key) { 105 const ui::KeyEvent& key) {
106 Window* root_window = window->GetRootWindow(); 106 Window* root_window = window->GetRootWindow();
107 client::FocusClient* focus_client = client::GetFocusClient(root_window); 107 client::FocusClient* focus_client = client::GetFocusClient(root_window);
108 Window* focused_window = focus_client->GetFocusedWindow(); 108 Window* focused_window = focus_client->GetFocusedWindow();
109 if (!focused_window) 109 if (!focused_window)
110 return window; 110 return window;
111 111
112 client::EventClient* event_client = client::GetEventClient(root_window); 112 client::EventClient* event_client = client::GetEventClient(root_window);
113 if (event_client && 113 if (event_client &&
114 !event_client->CanProcessEventsWithinSubtree(focused_window)) { 114 !event_client->CanProcessEventsWithinSubtree(focused_window)) {
115 focus_client->FocusWindow(NULL); 115 focus_client->FocusWindow(NULL);
116 return NULL; 116 return NULL;
117 } 117 }
118 return focused_window ? focused_window : window; 118 return focused_window ? focused_window : window;
119 } 119 }
120 120
121 Window* WindowTargeter::FindTargetForNonKeyEvent(Window* root_window,
122 ui::Event* event) {
123 if (!event->IsLocatedEvent())
124 return root_window;
125 return static_cast<Window*>(FindTargetForLocatedEvent(
126 root_window, static_cast<ui::LocatedEvent*>(event)));
127 }
128
121 Window* WindowTargeter::FindTargetInRootWindow(Window* root_window, 129 Window* WindowTargeter::FindTargetInRootWindow(Window* root_window,
122 const ui::LocatedEvent& event) { 130 const ui::LocatedEvent& event) {
123 DCHECK_EQ(root_window, root_window->GetRootWindow()); 131 DCHECK_EQ(root_window, root_window->GetRootWindow());
124 132
125 // Mouse events should be dispatched to the window that processed the 133 // Mouse events should be dispatched to the window that processed the
126 // mouse-press events (if any). 134 // mouse-press events (if any).
127 if (event.IsScrollEvent() || event.IsMouseEvent()) { 135 if (event.IsScrollEvent() || event.IsMouseEvent()) {
128 WindowEventDispatcher* dispatcher = root_window->GetHost()->dispatcher(); 136 WindowEventDispatcher* dispatcher = root_window->GetHost()->dispatcher();
129 if (dispatcher->mouse_pressed_handler()) 137 if (dispatcher->mouse_pressed_handler())
130 return dispatcher->mouse_pressed_handler(); 138 return dispatcher->mouse_pressed_handler();
(...skipping 18 matching lines...) Expand all
149 return static_cast<Window*>(consumer); 157 return static_cast<Window*>(consumer);
150 158
151 // If the initial touch is outside the root window, target the root. 159 // If the initial touch is outside the root window, target the root.
152 if (!root_window->bounds().Contains(event.location())) 160 if (!root_window->bounds().Contains(event.location()))
153 return root_window; 161 return root_window;
154 } 162 }
155 163
156 return NULL; 164 return NULL;
157 } 165 }
158 166
167 ui::EventTarget* WindowTargeter::FindTargetForEventRecursively(
168 Window* root_window,
169 ui::LocatedEvent* event) {
170 scoped_ptr<ui::EventTargetIterator> iter = root_window->GetChildIterator();
171 if (iter) {
172 ui::EventTarget* target = root_window;
173 for (ui::EventTarget* child = iter->GetNextTarget(); child;
174 child = iter->GetNextTarget()) {
175 WindowTargeter* targeter =
176 static_cast<WindowTargeter*>(child->GetEventTargeter());
177 if (!targeter)
178 targeter = this;
179 if (!targeter->SubtreeShouldBeExploredForEvent(child, *event))
180 continue;
181 target->ConvertEventToTarget(child, event);
182 target = child;
183 ui::EventTarget* child_target =
184 targeter->FindTargetForEvent(child, event);
tdanderson 2015/05/13 18:38:25 Recursively?
varkha 2015/05/21 19:11:04 Not so sure. WindowTargeterTest.ScopedWindowTarget
tdanderson 2015/05/22 18:29:55 Seems OK to leave as-is to me, but I think it's wo
varkha 2015/05/22 22:18:33 Yes, the code now reproduces the original flow, no
sadrul 2015/05/28 04:48:38 I think calling FindTargetForEvent is the right th
185 if (child_target)
186 return child_target;
187 }
188 target->ConvertEventToTarget(root_window, event);
189 }
190 return root_window->CanAcceptEvent(*event) ? root_window : NULL;
191 }
192
159 } // namespace aura 193 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698