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

Side by Side Diff: components/mus/ws/event_dispatcher.cc

Issue 1677513002: mus Window Server: implement event capture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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 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> 7 #include <set>
8 8
9 #include "base/time/time.h"
9 #include "cc/surfaces/surface_hittest.h" 10 #include "cc/surfaces/surface_hittest.h"
10 #include "components/mus/surfaces/surfaces_state.h" 11 #include "components/mus/surfaces/surfaces_state.h"
11 #include "components/mus/ws/event_dispatcher_delegate.h" 12 #include "components/mus/ws/event_dispatcher_delegate.h"
12 #include "components/mus/ws/server_window.h" 13 #include "components/mus/ws/server_window.h"
13 #include "components/mus/ws/server_window_delegate.h" 14 #include "components/mus/ws/server_window_delegate.h"
14 #include "components/mus/ws/window_coordinate_conversions.h" 15 #include "components/mus/ws/window_coordinate_conversions.h"
15 #include "components/mus/ws/window_finder.h" 16 #include "components/mus/ws/window_finder.h"
16 #include "components/mus/ws/window_tree_host_impl.h" 17 #include "components/mus/ws/window_tree_host_impl.h"
17 #include "mojo/converters/geometry/geometry_type_converters.h" 18 #include "mojo/converters/geometry/geometry_type_converters.h"
18 #include "ui/gfx/geometry/point.h" 19 #include "ui/gfx/geometry/point.h"
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 mojom::KeyboardCode keyboard_code_; 151 mojom::KeyboardCode keyboard_code_;
151 mojom::PointerKind pointer_kind_; 152 mojom::PointerKind pointer_kind_;
152 gfx::RectF pointer_region_; 153 gfx::RectF pointer_region_;
153 }; 154 };
154 155
155 //////////////////////////////////////////////////////////////////////////////// 156 ////////////////////////////////////////////////////////////////////////////////
156 157
157 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) 158 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate)
158 : delegate_(delegate), 159 : delegate_(delegate),
159 root_(nullptr), 160 root_(nullptr),
161 capture_window_(nullptr),
162 capture_window_in_nonclient_area_(false),
160 mouse_button_down_(false), 163 mouse_button_down_(false),
161 mouse_cursor_source_window_(nullptr) {} 164 mouse_cursor_source_window_(nullptr) {}
162 165
163 EventDispatcher::~EventDispatcher() { 166 EventDispatcher::~EventDispatcher() {
164 std::set<ServerWindow*> pointer_targets; 167 std::set<ServerWindow*> pointer_targets;
168 if (capture_window_) {
169 pointer_targets.insert(capture_window_);
170 capture_window_->RemoveObserver(this);
171 capture_window_ = nullptr;
172 }
165 for (const auto& pair : pointer_targets_) { 173 for (const auto& pair : pointer_targets_) {
166 if (pair.second.window && 174 if (pair.second.window &&
167 pointer_targets.insert(pair.second.window).second) { 175 pointer_targets.insert(pair.second.window).second) {
168 pair.second.window->RemoveObserver(this); 176 pair.second.window->RemoveObserver(this);
169 } 177 }
170 } 178 }
179 pointer_targets_.clear();
180 }
181
182 void EventDispatcher::SetCaptureWindow(ServerWindow* window,
183 bool in_nonclient_area) {
184 if (window == capture_window_)
185 return;
186
187 if (capture_window_) {
188 // Stop observing old capture window. |pointer_targets_| are cleared on
189 // intial setting of a capture window.
190 delegate_->OnLostCapture(capture_window_);
191 capture_window_->RemoveObserver(this);
192 } else {
193 // Cancel implicit capture to all other windows.
194 std::set<ServerWindow*> unobserved_windows;
195 for (const auto& pair : pointer_targets_) {
196 ServerWindow* target = pair.second.window;
197 if (!target)
198 continue;
199 if (unobserved_windows.insert(target).second)
200 target->RemoveObserver(this);
201 if (target == window)
202 continue;
203 mojom::EventPtr cancel_event = mojom::Event::New();
204 cancel_event->action = mojom::EventType::POINTER_CANCEL;
205 cancel_event->flags = mojom::kEventFlagNone;
206 cancel_event->time_stamp = base::TimeTicks::Now().ToInternalValue();
207 cancel_event->pointer_data = mojom::PointerData::New();
208 // TODO(jonross): Track previous location in PointerTarget for sending
209 // cancels
210 cancel_event->pointer_data->location = mojom::LocationData::New();
211 cancel_event->pointer_data->pointer_id = pair.first;
212 DispatchToPointerTarget(pair.second, std::move(cancel_event));
213 }
214 pointer_targets_.clear();
215 }
216
217 // Begin tracking the capture window if it is not yet being observed.
218 if (window) {
219 window->AddObserver(this);
220 delegate_->SetCapture(window);
221 } else {
222 delegate_->ReleaseCapture(capture_window_);
223 if (!mouse_button_down_)
224 UpdateCursorProviderByLastKnownLocation();
225 }
226
227 capture_window_ = window;
228 capture_window_in_nonclient_area_ = in_nonclient_area;
171 } 229 }
172 230
173 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { 231 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
174 if (!mouse_button_down_) { 232 if (!mouse_button_down_) {
175 gfx::Point location = mouse_pointer_last_location_; 233 gfx::Point location = mouse_pointer_last_location_;
176 mouse_cursor_source_window_ = 234 mouse_cursor_source_window_ =
177 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); 235 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
178 } 236 }
179 } 237 }
180 238
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 std::move(event)); 288 std::move(event));
231 } 289 }
232 290
233 void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) { 291 void EventDispatcher::ProcessPointerEvent(mojom::EventPtr event) {
234 const bool is_mouse_event = event->pointer_data && 292 const bool is_mouse_event = event->pointer_data &&
235 event->pointer_data->kind == mojom::PointerKind::MOUSE; 293 event->pointer_data->kind == mojom::PointerKind::MOUSE;
236 294
237 if (is_mouse_event) 295 if (is_mouse_event)
238 mouse_pointer_last_location_ = EventLocationToPoint(*event); 296 mouse_pointer_last_location_ = EventLocationToPoint(*event);
239 297
298 // Release capture on pointer up. For mouse we only release if there are
299 // no buttons down.
300 const bool is_pointer_going_up =
301 (event->action == mojom::EventType::POINTER_UP ||
302 event->action == mojom::EventType::POINTER_CANCEL) &&
303 (event->pointer_data->kind != mojom::PointerKind::MOUSE ||
304 IsOnlyOneMouseButtonDown(event->flags));
305
306 // Update mouse down state upon events which change it.
307 if (is_mouse_event) {
308 if (event->action == mojom::EventType::POINTER_DOWN)
309 mouse_button_down_ = true;
310 else if (is_pointer_going_up)
311 mouse_button_down_ = false;
312 }
313
314 if (capture_window_) {
315 mouse_cursor_source_window_ = capture_window_;
316 PointerTarget pointer_target;
317 pointer_target.window = capture_window_;
318 pointer_target.in_nonclient_area = capture_window_in_nonclient_area_;
319 DispatchToPointerTarget(pointer_target, std::move(event));
320 return;
321 }
322
240 const int32_t pointer_id = event->pointer_data->pointer_id; 323 const int32_t pointer_id = event->pointer_data->pointer_id;
241 if (!IsTrackingPointer(pointer_id) || 324 if (!IsTrackingPointer(pointer_id) ||
sky 2016/02/10 17:38:22 Shouldn't we SetCapture and ReleaseCapture in here
jonross 2016/02/10 19:45:49 Right now DisplayManager is doing its own version
sky 2016/02/10 20:06:32 Yes please as otherwise things are in a bit of wei
jonross 2016/02/10 22:51:01 Done.
242 !pointer_targets_[pointer_id].is_pointer_down) { 325 !pointer_targets_[pointer_id].is_pointer_down) {
243 const bool any_pointers_down = AreAnyPointersDown(); 326 const bool any_pointers_down = AreAnyPointersDown();
244 UpdateTargetForPointer(*event); 327 UpdateTargetForPointer(*event);
245 if (is_mouse_event) 328 if (is_mouse_event)
246 mouse_cursor_source_window_ = pointer_targets_[pointer_id].window; 329 mouse_cursor_source_window_ = pointer_targets_[pointer_id].window;
247 330
248 PointerTarget& pointer_target = pointer_targets_[pointer_id]; 331 PointerTarget& pointer_target = pointer_targets_[pointer_id];
249 if (pointer_target.is_pointer_down) { 332 if (pointer_target.is_pointer_down) {
250 if (is_mouse_event) { 333 if (is_mouse_event)
251 mouse_button_down_ = true;
252 mouse_cursor_source_window_ = pointer_target.window; 334 mouse_cursor_source_window_ = pointer_target.window;
253 }
254 if (!any_pointers_down) 335 if (!any_pointers_down)
255 delegate_->SetFocusedWindowFromEventDispatcher(pointer_target.window); 336 delegate_->SetFocusedWindowFromEventDispatcher(pointer_target.window);
256 } 337 }
257 } 338 }
258 339
259 // Release capture on pointer up. For mouse we only release if there are 340 // When we release the mouse button, we want the cursor to be sourced from
260 // no buttons down. 341 // the window under the mouse pointer, even though we're sending the button
261 const bool is_pointer_going_up = 342 // up event to the window that had implicit capture. We have to set this
262 (event->action == mojom::EventType::POINTER_UP || 343 // before we perform dispatch because the Delegate is going to read this
263 event->action == mojom::EventType::POINTER_CANCEL) && 344 // information from us.
264 (event->pointer_data->kind != mojom::PointerKind::MOUSE || 345 if (is_pointer_going_up && is_mouse_event)
265 IsOnlyOneMouseButtonDown(event->flags)); 346 UpdateCursorProviderByLastKnownLocation();
266
267 if (is_pointer_going_up && is_mouse_event) {
268 // When we release the mouse button, we want the cursor to be sourced from
269 // the window under the mouse pointer, even though we're sending the button
270 // up event to the window that had implicit capture. We have to set this
271 // before we perform dispatch because the Delegate is going to read this
272 // information from us.
273 mouse_button_down_ = false;
274 gfx::Point location(EventLocationToPoint(*event));
275 mouse_cursor_source_window_ =
276 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
277 }
278 347
279 DispatchToPointerTarget(pointer_targets_[pointer_id], std::move(event)); 348 DispatchToPointerTarget(pointer_targets_[pointer_id], std::move(event));
280 349
281 if (is_pointer_going_up) { 350 if (is_pointer_going_up) {
282 if (is_mouse_event) 351 if (is_mouse_event)
283 pointer_targets_[pointer_id].is_pointer_down = false; 352 pointer_targets_[pointer_id].is_pointer_down = false;
284 else 353 else
285 StopTrackingPointer(pointer_id); 354 StopTrackingPointer(pointer_id);
286 } 355 }
287 } 356 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 transform.TransformPoint(&location); 442 transform.TransformPoint(&location);
374 event->pointer_data->location->x = location.x(); 443 event->pointer_data->location->x = location.x();
375 event->pointer_data->location->y = location.y(); 444 event->pointer_data->location->y = location.y();
376 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, 445 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area,
377 std::move(event)); 446 std::move(event));
378 } 447 }
379 448
380 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { 449 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
381 window->RemoveObserver(this); 450 window->RemoveObserver(this);
382 451
452 if (capture_window_ == window) {
453 capture_window_ = nullptr;
454 // A window only cares to be informed that it lost capture if it explicitly
455 // requested capture. A window can lose capture if another window gains
456 // explicit capture.
457 delegate_->OnLostCapture(window);
sky 2016/02/10 17:38:22 AFAICT you won't release native capture here. By t
jonross 2016/02/10 19:45:49 Correct. DisplayManagerDelegate::OnLostCapture()
458 mouse_button_down_ = false;
459 UpdateCursorProviderByLastKnownLocation();
460 return;
461 }
462
383 for (auto& pair : pointer_targets_) { 463 for (auto& pair : pointer_targets_) {
384 if (pair.second.window == window) 464 if (pair.second.window == window)
385 pair.second.window = nullptr; 465 pair.second.window = nullptr;
386 } 466 }
387 } 467 }
388 468
389 bool EventDispatcher::IsObservingWindow(ServerWindow* window) { 469 bool EventDispatcher::IsObservingWindow(ServerWindow* window) {
390 for (const auto& pair : pointer_targets_) { 470 for (const auto& pair : pointer_targets_) {
391 if (pair.second.window == window) 471 if (pair.second.window == window)
392 return true; 472 return true;
(...skipping 25 matching lines...) Expand all
418 498
419 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { 499 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) {
420 CancelPointerEventsToTarget(window); 500 CancelPointerEventsToTarget(window);
421 501
422 if (mouse_cursor_source_window_ == window) 502 if (mouse_cursor_source_window_ == window)
423 mouse_cursor_source_window_ = nullptr; 503 mouse_cursor_source_window_ = nullptr;
424 } 504 }
425 505
426 } // namespace ws 506 } // namespace ws
427 } // namespace mus 507 } // namespace mus
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698