OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/mus/ws/event_dispatcher.h" | 5 #include "components/mus/ws/event_dispatcher.h" |
6 | 6 |
7 #include <set> | |
8 | |
7 #include "cc/surfaces/surface_hittest.h" | 9 #include "cc/surfaces/surface_hittest.h" |
8 #include "components/mus/surfaces/surfaces_state.h" | 10 #include "components/mus/surfaces/surfaces_state.h" |
9 #include "components/mus/ws/event_dispatcher_delegate.h" | 11 #include "components/mus/ws/event_dispatcher_delegate.h" |
10 #include "components/mus/ws/server_window.h" | 12 #include "components/mus/ws/server_window.h" |
11 #include "components/mus/ws/server_window_delegate.h" | 13 #include "components/mus/ws/server_window_delegate.h" |
12 #include "components/mus/ws/window_coordinate_conversions.h" | 14 #include "components/mus/ws/window_coordinate_conversions.h" |
13 #include "components/mus/ws/window_finder.h" | 15 #include "components/mus/ws/window_finder.h" |
14 #include "components/mus/ws/window_tree_host_impl.h" | 16 #include "components/mus/ws/window_tree_host_impl.h" |
15 #include "mojo/converters/geometry/geometry_type_converters.h" | 17 #include "mojo/converters/geometry/geometry_type_converters.h" |
16 #include "ui/gfx/geometry/point.h" | 18 #include "ui/gfx/geometry/point.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 mojo::EventType event_type_; | 136 mojo::EventType event_type_; |
135 mojo::EventFlags event_flags_; | 137 mojo::EventFlags event_flags_; |
136 mojo::KeyboardCode keyboard_code_; | 138 mojo::KeyboardCode keyboard_code_; |
137 mojo::PointerKind pointer_kind_; | 139 mojo::PointerKind pointer_kind_; |
138 gfx::RectF pointer_region_; | 140 gfx::RectF pointer_region_; |
139 }; | 141 }; |
140 | 142 |
141 //////////////////////////////////////////////////////////////////////////////// | 143 //////////////////////////////////////////////////////////////////////////////// |
142 | 144 |
143 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) | 145 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) |
144 : delegate_(delegate), | 146 : delegate_(delegate), root_(nullptr) {} |
145 root_(nullptr), | |
146 capture_window_(nullptr), | |
147 capture_in_nonclient_area_(false) {} | |
148 | 147 |
149 EventDispatcher::~EventDispatcher() {} | 148 EventDispatcher::~EventDispatcher() { |
149 std::set<ServerWindow*> pointer_targets; | |
150 for (const auto& pair : pointer_targets_) { | |
151 if (pair.second.window && | |
152 pointer_targets.insert(pair.second.window).second) { | |
153 pair.second.window->RemoveObserver(this); | |
154 } | |
155 } | |
156 } | |
150 | 157 |
151 void EventDispatcher::AddAccelerator(uint32_t id, | 158 void EventDispatcher::AddAccelerator(uint32_t id, |
152 mojo::EventMatcherPtr event_matcher) { | 159 mojo::EventMatcherPtr event_matcher) { |
153 EventMatcher matcher(*event_matcher); | 160 EventMatcher matcher(*event_matcher); |
154 #if !defined(NDEBUG) | 161 #if !defined(NDEBUG) |
155 for (const auto& pair : accelerators_) { | 162 for (const auto& pair : accelerators_) { |
156 DCHECK_NE(pair.first, id); | 163 DCHECK_NE(pair.first, id); |
157 DCHECK(!matcher.Equals(pair.second)); | 164 DCHECK(!matcher.Equals(pair.second)); |
158 } | 165 } |
159 #endif | 166 #endif |
(...skipping 12 matching lines...) Expand all Loading... | |
172 | 179 |
173 if (event->action == mojo::EVENT_TYPE_KEY_PRESSED && | 180 if (event->action == mojo::EVENT_TYPE_KEY_PRESSED && |
174 !event->key_data->is_char) { | 181 !event->key_data->is_char) { |
175 uint32_t accelerator = 0u; | 182 uint32_t accelerator = 0u; |
176 if (FindAccelerator(*event, &accelerator)) { | 183 if (FindAccelerator(*event, &accelerator)) { |
177 delegate_->OnAccelerator(accelerator, event.Pass()); | 184 delegate_->OnAccelerator(accelerator, event.Pass()); |
178 return; | 185 return; |
179 } | 186 } |
180 } | 187 } |
181 | 188 |
182 ServerWindow* target = FindEventTarget(event.get()); | 189 if (event->key_data) { |
183 bool in_nonclient_area = false; | 190 ProcessKeyEvent(event.Pass()); |
184 | 191 return; |
185 if (IsMouseEventFlag(event->flags)) { | |
186 if (!capture_window_ && target && | |
187 (event->action == mojo::EVENT_TYPE_POINTER_DOWN)) { | |
188 // TODO(sky): |capture_window_| needs to be reset when window removed | |
189 // from hierarchy. | |
190 capture_window_ = target; | |
191 // TODO(sky): this needs to happen for pointer down events too. | |
192 capture_in_nonclient_area_ = | |
193 IsLocationInNonclientArea(target, EventLocationToPoint(*event)); | |
194 in_nonclient_area = capture_in_nonclient_area_; | |
195 } else if (event->action == mojo::EVENT_TYPE_POINTER_UP && | |
196 IsOnlyOneMouseButtonDown(event->flags)) { | |
197 capture_window_ = nullptr; | |
198 } | |
199 in_nonclient_area = capture_in_nonclient_area_; | |
200 } | 192 } |
201 | 193 |
202 if (target) { | 194 if (event->pointer_data.get()) { |
203 if (event->action == mojo::EVENT_TYPE_POINTER_DOWN) | 195 ProcessPointerEvent(event.Pass()); |
196 return; | |
197 } | |
198 | |
199 NOTREACHED(); | |
200 } | |
201 | |
202 void EventDispatcher::ProcessKeyEvent(mojo::EventPtr event) { | |
203 ServerWindow* focused_window = | |
204 delegate_->GetFocusedWindowForEventDispatcher(); | |
205 if (focused_window) | |
206 delegate_->DispatchInputEventToWindow(focused_window, false, event.Pass()); | |
207 } | |
208 | |
209 void EventDispatcher::ProcessPointerEvent(mojo::EventPtr event) { | |
210 const int32_t pointer_id = event->pointer_data->pointer_id; | |
211 if (event->action == mojo::EVENT_TYPE_WHEEL || | |
212 (event->action == mojo::EVENT_TYPE_POINTER_MOVE && | |
213 pointer_targets_.count(pointer_id) == 0)) { | |
214 PointerTarget pointer_target; | |
215 if (pointer_targets_.count(pointer_id) != 0) { | |
216 pointer_target = pointer_targets_[pointer_id]; | |
217 } else { | |
218 gfx::Point location(EventLocationToPoint(*event)); | |
219 pointer_target.window = | |
220 FindDeepestVisibleWindow(root_, surface_id_, &location); | |
221 } | |
222 DispatchToPointerTarget(pointer_target, event.Pass()); | |
223 return; | |
224 } | |
225 | |
226 // Pointer down implicitly captures. | |
227 if (pointer_targets_.count(pointer_id) == 0) { | |
228 DCHECK(event->action == mojo::EVENT_TYPE_POINTER_DOWN); | |
229 const bool is_first_pointer_down = pointer_targets_.empty(); | |
230 gfx::Point location(EventLocationToPoint(*event)); | |
231 ServerWindow* target = | |
232 FindDeepestVisibleWindow(root_, surface_id_, &location); | |
233 DCHECK(target); | |
234 if (!IsSendingPointerEventsToTarget(target)) | |
235 target->AddObserver(this); | |
236 | |
237 pointer_targets_[pointer_id].window = target; | |
238 pointer_targets_[pointer_id].in_nonclient_area = | |
239 IsLocationInNonclientArea(target, location); | |
240 | |
241 if (is_first_pointer_down) | |
204 delegate_->SetFocusedWindowFromEventDispatcher(target); | 242 delegate_->SetFocusedWindowFromEventDispatcher(target); |
243 } | |
205 | 244 |
206 delegate_->DispatchInputEventToWindow(target, in_nonclient_area, | 245 // Release capture on pointer up. For mouse we only release if there are |
207 event.Pass()); | 246 // no buttons down. |
247 const bool should_reset_target = | |
248 (event->action == mojo::EVENT_TYPE_POINTER_UP || | |
249 event->action == mojo::EVENT_TYPE_POINTER_CANCEL) && | |
250 (event->pointer_data->kind != mojo::POINTER_KIND_MOUSE || | |
251 IsOnlyOneMouseButtonDown(event->flags)); | |
252 | |
253 DispatchToPointerTarget(pointer_targets_[pointer_id], event.Pass()); | |
254 | |
255 if (should_reset_target) { | |
256 ServerWindow* target = pointer_targets_[pointer_id].window; | |
257 pointer_targets_.erase(pointer_id); | |
258 if (target && !IsSendingPointerEventsToTarget(target)) | |
259 target->RemoveObserver(this); | |
208 } | 260 } |
209 } | 261 } |
210 | 262 |
263 void EventDispatcher::DispatchToPointerTarget(const PointerTarget& target, | |
264 mojo::EventPtr event) { | |
265 if (!target.window) | |
266 return; | |
267 | |
268 gfx::Point location(EventLocationToPoint(*event)); | |
269 gfx::Transform transform(GetTransformToWindow(surface_id_, target.window)); | |
270 transform.TransformPoint(&location); | |
271 event->pointer_data->location->x = location.x(); | |
272 event->pointer_data->location->y = location.y(); | |
273 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, | |
274 event.Pass()); | |
275 } | |
276 | |
277 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { | |
278 window->RemoveObserver(this); | |
279 | |
280 for (auto& pair : pointer_targets_) { | |
281 if (pair.second.window == window) | |
282 pair.second.window = nullptr; | |
283 } | |
284 } | |
285 | |
286 bool EventDispatcher::IsSendingPointerEventsToTarget(ServerWindow* window) { | |
sadrul
2015/10/29 00:48:25
Would IsObservingWindow() better explain what this
sky
2015/10/29 14:54:16
Done.
| |
287 for (const auto& pair : pointer_targets_) { | |
288 if (pair.second.window == window) | |
289 return true; | |
290 } | |
291 return false; | |
292 } | |
293 | |
211 bool EventDispatcher::FindAccelerator(const mojo::Event& event, | 294 bool EventDispatcher::FindAccelerator(const mojo::Event& event, |
212 uint32_t* accelerator_id) { | 295 uint32_t* accelerator_id) { |
213 DCHECK(event.key_data); | 296 DCHECK(event.key_data); |
214 for (const auto& pair : accelerators_) { | 297 for (const auto& pair : accelerators_) { |
215 if (pair.second.MatchesEvent(event)) { | 298 if (pair.second.MatchesEvent(event)) { |
216 *accelerator_id = pair.first; | 299 *accelerator_id = pair.first; |
217 return true; | 300 return true; |
218 } | 301 } |
219 } | 302 } |
220 return false; | 303 return false; |
221 } | 304 } |
222 | 305 |
223 ServerWindow* EventDispatcher::FindEventTarget(mojo::Event* event) { | 306 void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window, |
224 ServerWindow* focused_window = | 307 ServerWindow* new_parent, |
225 delegate_->GetFocusedWindowForEventDispatcher(); | 308 ServerWindow* old_parent) { |
226 if (event->key_data) | 309 CancelPointerEventsToTarget(window); |
227 return focused_window; | 310 } |
228 | 311 |
229 DCHECK(event->pointer_data) << "Unknown event type: " << event->action; | 312 void EventDispatcher::OnWindowVisibilityChanged(ServerWindow* window) { |
230 mojo::LocationData* event_location = event->pointer_data->location.get(); | 313 CancelPointerEventsToTarget(window); |
231 DCHECK(event_location); | 314 } |
232 gfx::Point location(static_cast<int>(event_location->x), | |
233 static_cast<int>(event_location->y)); | |
234 | 315 |
235 ServerWindow* target = capture_window_; | 316 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { |
236 | 317 CancelPointerEventsToTarget(window); |
237 if (!target) { | |
238 target = FindDeepestVisibleWindow(root_, surface_id_, &location); | |
239 } else { | |
240 gfx::Transform transform(GetTransformToWindow(surface_id_, target)); | |
241 transform.TransformPoint(&location); | |
242 } | |
243 | |
244 event_location->x = location.x(); | |
245 event_location->y = location.y(); | |
246 | |
247 return target; | |
248 } | 318 } |
249 | 319 |
250 } // namespace ws | 320 } // namespace ws |
251 } // namespace mus | 321 } // namespace mus |
OLD | NEW |