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

Side by Side Diff: services/ui/ws/window_manager_state.cc

Issue 2884463002: Make event-targeting asynchronous in window server. (Closed)
Patch Set: comments Created 3 years, 6 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
« no previous file with comments | « services/ui/ws/window_manager_state.h ('k') | services/ui/ws/window_manager_state_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "services/ui/ws/window_manager_state.h" 5 #include "services/ui/ws/window_manager_state.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/weak_ptr.h" 10 #include "base/memory/weak_ptr.h"
11 #include "services/service_manager/public/interfaces/connector.mojom.h" 11 #include "services/service_manager/public/interfaces/connector.mojom.h"
12 #include "services/ui/common/accelerator_util.h" 12 #include "services/ui/common/accelerator_util.h"
13 #include "services/ui/ws/accelerator.h" 13 #include "services/ui/ws/accelerator.h"
14 #include "services/ui/ws/cursor_location_manager.h" 14 #include "services/ui/ws/cursor_location_manager.h"
15 #include "services/ui/ws/display.h" 15 #include "services/ui/ws/display.h"
16 #include "services/ui/ws/display_creation_config.h" 16 #include "services/ui/ws/display_creation_config.h"
17 #include "services/ui/ws/display_manager.h" 17 #include "services/ui/ws/display_manager.h"
18 #include "services/ui/ws/event_targeter.h"
18 #include "services/ui/ws/platform_display.h" 19 #include "services/ui/ws/platform_display.h"
19 #include "services/ui/ws/server_window.h" 20 #include "services/ui/ws/server_window.h"
20 #include "services/ui/ws/user_display_manager.h" 21 #include "services/ui/ws/user_display_manager.h"
21 #include "services/ui/ws/user_id_tracker.h" 22 #include "services/ui/ws/user_id_tracker.h"
22 #include "services/ui/ws/window_manager_display_root.h" 23 #include "services/ui/ws/window_manager_display_root.h"
23 #include "services/ui/ws/window_server.h" 24 #include "services/ui/ws/window_server.h"
24 #include "services/ui/ws/window_tree.h" 25 #include "services/ui/ws/window_tree.h"
25 #include "ui/events/event.h" 26 #include "ui/events/event.h"
26 #include "ui/gfx/geometry/dip_util.h" 27 #include "ui/gfx/geometry/dip_util.h"
27 28
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 const ServerWindow* GetEmbedRoot(const ServerWindow* window) { 68 const ServerWindow* GetEmbedRoot(const ServerWindow* window) {
68 DCHECK(window); 69 DCHECK(window);
69 const ServerWindow* embed_root = window->parent(); 70 const ServerWindow* embed_root = window->parent();
70 while (embed_root && embed_root->id().client_id == window->id().client_id) 71 while (embed_root && embed_root->id().client_id == window->id().client_id)
71 embed_root = embed_root->parent(); 72 embed_root = embed_root->parent();
72 return embed_root; 73 return embed_root;
73 } 74 }
74 75
75 } // namespace 76 } // namespace
76 77
77 WindowManagerState::InFlightEventDetails::InFlightEventDetails( 78 WindowManagerState::InFlightEventDispatchDetails::InFlightEventDispatchDetails(
78 WindowManagerState* window_manager_state, 79 WindowManagerState* window_manager_state,
79 WindowTree* tree, 80 WindowTree* tree,
80 int64_t display_id, 81 int64_t display_id,
81 const Event& event, 82 const Event& event,
82 EventDispatchPhase phase) 83 EventDispatchPhase phase)
83 : tree(tree), 84 : tree(tree),
84 display_id(display_id), 85 display_id(display_id),
85 event(Event::Clone(event)), 86 event(Event::Clone(event)),
86 phase(phase), 87 phase(phase),
87 weak_factory(window_manager_state) {} 88 weak_factory(window_manager_state) {}
88 89
89 WindowManagerState::InFlightEventDetails::~InFlightEventDetails() {} 90 WindowManagerState::InFlightEventDispatchDetails::
91 ~InFlightEventDispatchDetails() {}
90 92
91 class WindowManagerState::ProcessedEventTarget { 93 class WindowManagerState::ProcessedEventTarget {
92 public: 94 public:
93 ProcessedEventTarget(ServerWindow* window, 95 ProcessedEventTarget(ServerWindow* window,
94 ClientSpecificId client_id, 96 ClientSpecificId client_id,
95 Accelerator* accelerator) 97 Accelerator* accelerator)
96 : client_id_(client_id) { 98 : client_id_(client_id) {
97 tracker_.Add(window); 99 tracker_.Add(window);
98 if (accelerator) 100 if (accelerator)
99 accelerator_ = accelerator->GetWeakPtr(); 101 accelerator_ = accelerator->GetWeakPtr();
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 display->platform_display()->MoveCursorTo(display_pixels); 208 display->platform_display()->MoveCursorTo(display_pixels);
207 } 209 }
208 210
209 void WindowManagerState::SetDragDropSourceWindow( 211 void WindowManagerState::SetDragDropSourceWindow(
210 DragSource* drag_source, 212 DragSource* drag_source,
211 ServerWindow* window, 213 ServerWindow* window,
212 DragTargetConnection* source_connection, 214 DragTargetConnection* source_connection,
213 const std::unordered_map<std::string, std::vector<uint8_t>>& drag_data, 215 const std::unordered_map<std::string, std::vector<uint8_t>>& drag_data,
214 uint32_t drag_operation) { 216 uint32_t drag_operation) {
215 int32_t drag_pointer = MouseEvent::kMousePointerId; 217 int32_t drag_pointer = MouseEvent::kMousePointerId;
216 if (in_flight_event_details_ && 218 if (in_flight_event_dispatch_details_ &&
217 in_flight_event_details_->event->IsPointerEvent()) { 219 in_flight_event_dispatch_details_->event->IsPointerEvent()) {
218 drag_pointer = 220 drag_pointer = in_flight_event_dispatch_details_->event->AsPointerEvent()
219 in_flight_event_details_->event->AsPointerEvent()->pointer_details().id; 221 ->pointer_details()
222 .id;
220 } else { 223 } else {
221 NOTIMPLEMENTED() << "Set drag drop set up during something other than a " 224 NOTIMPLEMENTED() << "Set drag drop set up during something other than a "
222 << "pointer event; rejecting drag."; 225 << "pointer event; rejecting drag.";
223 drag_source->OnDragCompleted(false, ui::mojom::kDropEffectNone); 226 drag_source->OnDragCompleted(false, ui::mojom::kDropEffectNone);
224 return; 227 return;
225 } 228 }
226 229
227 event_dispatcher_.SetDragDropSourceWindow(drag_source, window, 230 event_dispatcher_.SetDragDropSourceWindow(drag_source, window,
228 source_connection, drag_pointer, 231 source_connection, drag_pointer,
229 drag_data, drag_operation); 232 drag_data, drag_operation);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 NOTREACHED(); 267 NOTREACHED();
265 } 268 }
266 269
267 const UserId& WindowManagerState::user_id() const { 270 const UserId& WindowManagerState::user_id() const {
268 return window_tree_->user_id(); 271 return window_tree_->user_id();
269 } 272 }
270 273
271 void WindowManagerState::OnWillDestroyTree(WindowTree* tree) { 274 void WindowManagerState::OnWillDestroyTree(WindowTree* tree) {
272 event_dispatcher_.OnWillDestroyDragTargetConnection(tree); 275 event_dispatcher_.OnWillDestroyDragTargetConnection(tree);
273 276
274 if (!in_flight_event_details_ || in_flight_event_details_->tree != tree) 277 if (!in_flight_event_dispatch_details_ ||
278 in_flight_event_dispatch_details_->tree != tree)
275 return; 279 return;
276 280
277 // The WindowTree is dying. So it's not going to ack the event. 281 // The WindowTree is dying. So it's not going to ack the event.
278 // If the dying tree matches the root |tree_| mark as handled so we don't 282 // If the dying tree matches the root |tree_| mark as handled so we don't
279 // notify it of accelerators. 283 // notify it of accelerators.
280 OnEventAck(in_flight_event_details_->tree, 284 OnEventAck(in_flight_event_dispatch_details_->tree,
281 tree == window_tree_ ? mojom::EventResult::HANDLED 285 tree == window_tree_ ? mojom::EventResult::HANDLED
282 : mojom::EventResult::UNHANDLED); 286 : mojom::EventResult::UNHANDLED);
283 } 287 }
284 288
285 ServerWindow* WindowManagerState::GetOrphanedRootWithId(const WindowId& id) { 289 ServerWindow* WindowManagerState::GetOrphanedRootWithId(const WindowId& id) {
286 for (auto& display_root_ptr : orphaned_window_manager_display_roots_) { 290 for (auto& display_root_ptr : orphaned_window_manager_display_roots_) {
287 if (display_root_ptr->root()->id() == id) 291 if (display_root_ptr->root()->id() == id)
288 return display_root_ptr->root(); 292 return display_root_ptr->root();
289 } 293 }
290 return nullptr; 294 return nullptr;
291 } 295 }
292 296
293 bool WindowManagerState::IsActive() const { 297 bool WindowManagerState::IsActive() const {
294 return window_server()->user_id_tracker()->active_id() == user_id(); 298 return window_server()->user_id_tracker()->active_id() == user_id();
295 } 299 }
296 300
297 void WindowManagerState::Activate(const gfx::Point& mouse_location_on_display, 301 void WindowManagerState::Activate(const gfx::Point& mouse_location_on_display,
298 const int64_t display_id) { 302 int64_t display_id) {
299 SetAllRootWindowsVisible(true); 303 SetAllRootWindowsVisible(true);
300 event_dispatcher_.Reset(); 304 event_dispatcher_.Reset();
301 event_dispatcher_.SetMousePointerDisplayLocation(mouse_location_on_display, 305 event_dispatcher_.SetMousePointerDisplayLocation(mouse_location_on_display,
302 display_id); 306 display_id);
303 } 307 }
304 308
305 void WindowManagerState::Deactivate() { 309 void WindowManagerState::Deactivate() {
306 SetAllRootWindowsVisible(false); 310 SetAllRootWindowsVisible(false);
307 event_dispatcher_.Reset(); 311 event_dispatcher_.Reset();
308 // The tree is no longer active, so no point in dispatching any further 312 // The tree is no longer active, so no point in dispatching any further
309 // events. 313 // events.
310 std::queue<std::unique_ptr<QueuedEvent>> event_queue; 314 std::queue<std::unique_ptr<QueuedEvent>> event_queue;
311 event_queue.swap(event_queue_); 315 event_queue.swap(event_queue_);
312 } 316 }
313 317
314 void WindowManagerState::ProcessEvent(const ui::Event& event, 318 void WindowManagerState::ProcessEvent(const ui::Event& event,
315 int64_t display_id) { 319 int64_t display_id) {
316 // If this is still waiting for an ack from a previously sent event, then 320 // If this is still waiting for an ack from a previously sent event, then
317 // queue up the event to be dispatched once the ack is received. 321 // queue up the event to be dispatched once the ack is received.
318 if (in_flight_event_details_) { 322 if (event_dispatcher_.IsProcessingEvent() ||
323 in_flight_event_dispatch_details_) {
319 if (!event_queue_.empty() && !event_queue_.back()->processed_target && 324 if (!event_queue_.empty() && !event_queue_.back()->processed_target &&
320 EventsCanBeCoalesced(*event_queue_.back()->event, event)) { 325 EventsCanBeCoalesced(*event_queue_.back()->event, event)) {
321 event_queue_.back()->event = CoalesceEvents( 326 event_queue_.back()->event = CoalesceEvents(
322 std::move(event_queue_.back()->event), ui::Event::Clone(event)); 327 std::move(event_queue_.back()->event), ui::Event::Clone(event));
323 event_queue_.back()->display_id = display_id; 328 event_queue_.back()->display_id = display_id;
324 return; 329 return;
325 } 330 }
326 QueueEvent(event, nullptr, display_id); 331 QueueEvent(event, nullptr, display_id);
327 return; 332 return;
328 } 333 }
329 334
330 ProcessEventImpl(event, display_id); 335 ProcessEventImpl(event, display_id);
331 } 336 }
332 337
333 void WindowManagerState::OnAcceleratorAck( 338 void WindowManagerState::OnAcceleratorAck(
334 mojom::EventResult result, 339 mojom::EventResult result,
335 const std::unordered_map<std::string, std::vector<uint8_t>>& properties) { 340 const std::unordered_map<std::string, std::vector<uint8_t>>& properties) {
336 DCHECK(in_flight_event_details_); 341 DCHECK(in_flight_event_dispatch_details_);
337 DCHECK_EQ(EventDispatchPhase::PRE_TARGET_ACCELERATOR, 342 DCHECK_EQ(EventDispatchPhase::PRE_TARGET_ACCELERATOR,
338 in_flight_event_details_->phase); 343 in_flight_event_dispatch_details_->phase);
339 344
340 std::unique_ptr<InFlightEventDetails> details = 345 std::unique_ptr<InFlightEventDispatchDetails> details =
341 std::move(in_flight_event_details_); 346 std::move(in_flight_event_dispatch_details_);
342 347
343 if (result == mojom::EventResult::UNHANDLED) { 348 if (result == mojom::EventResult::UNHANDLED) {
344 DCHECK(details->event->IsKeyEvent()); 349 DCHECK(details->event->IsKeyEvent());
345 if (!properties.empty()) 350 if (!properties.empty())
346 details->event->AsKeyEvent()->SetProperties(properties); 351 details->event->AsKeyEvent()->SetProperties(properties);
347 event_dispatcher_.ProcessEvent( 352 event_dispatcher_.ProcessEvent(
348 *details->event, details->display_id, 353 *details->event, details->display_id,
349 EventDispatcher::AcceleratorMatchPhase::POST_ONLY); 354 EventDispatcher::AcceleratorMatchPhase::POST_ONLY);
350 } else { 355 } else {
351 // We're not going to process the event any further, notify event observers. 356 // We're not going to process the event any further, notify event observers.
352 // We don't do this first to ensure we don't send an event twice to clients. 357 // We don't do this first to ensure we don't send an event twice to clients.
353 window_server()->SendToPointerWatchers(*details->event, user_id(), nullptr, 358 window_server()->SendToPointerWatchers(*details->event, user_id(), nullptr,
354 nullptr, details->display_id); 359 nullptr, details->display_id);
355 ProcessNextEventFromQueue(); 360 ProcessNextAvailableEvent();
356 } 361 }
357 } 362 }
358 363
359 const WindowServer* WindowManagerState::window_server() const { 364 const WindowServer* WindowManagerState::window_server() const {
360 return window_tree_->window_server(); 365 return window_tree_->window_server();
361 } 366 }
362 367
363 WindowServer* WindowManagerState::window_server() { 368 WindowServer* WindowManagerState::window_server() {
364 return window_tree_->window_server(); 369 return window_tree_->window_server();
365 } 370 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 for (auto& display_root_ptr : window_manager_display_roots_) { 410 for (auto& display_root_ptr : window_manager_display_roots_) {
406 if (display_root_ptr->root()->parent() == window) 411 if (display_root_ptr->root()->parent() == window)
407 return display_root_ptr->GetClientVisibleRoot(); 412 return display_root_ptr->GetClientVisibleRoot();
408 } 413 }
409 NOTREACHED(); 414 NOTREACHED();
410 return nullptr; 415 return nullptr;
411 } 416 }
412 417
413 void WindowManagerState::OnEventAck(mojom::WindowTree* tree, 418 void WindowManagerState::OnEventAck(mojom::WindowTree* tree,
414 mojom::EventResult result) { 419 mojom::EventResult result) {
415 DCHECK(in_flight_event_details_); 420 DCHECK(in_flight_event_dispatch_details_);
416 std::unique_ptr<InFlightEventDetails> details = 421 std::unique_ptr<InFlightEventDispatchDetails> details =
417 std::move(in_flight_event_details_); 422 std::move(in_flight_event_dispatch_details_);
418 423
419 if (result == mojom::EventResult::UNHANDLED && 424 if (result == mojom::EventResult::UNHANDLED &&
420 details->post_target_accelerator) { 425 details->post_target_accelerator) {
421 OnAccelerator(details->post_target_accelerator->id(), details->display_id, 426 OnAccelerator(details->post_target_accelerator->id(), details->display_id,
422 *details->event, AcceleratorPhase::POST); 427 *details->event, AcceleratorPhase::POST);
423 } 428 }
424 429
425 ProcessNextEventFromQueue(); 430 ProcessNextAvailableEvent();
426 } 431 }
427 432
428 void WindowManagerState::OnEventAckTimeout(ClientSpecificId client_id) { 433 void WindowManagerState::OnEventAckTimeout(ClientSpecificId client_id) {
429 WindowTree* hung_tree = window_server()->GetTreeWithId(client_id); 434 WindowTree* hung_tree = window_server()->GetTreeWithId(client_id);
430 if (hung_tree && !hung_tree->janky()) 435 if (hung_tree && !hung_tree->janky())
431 window_tree_->ClientJankinessChanged(hung_tree); 436 window_tree_->ClientJankinessChanged(hung_tree);
432 if (in_flight_event_details_->phase == 437 if (in_flight_event_dispatch_details_->phase ==
433 EventDispatchPhase::PRE_TARGET_ACCELERATOR) { 438 EventDispatchPhase::PRE_TARGET_ACCELERATOR) {
434 OnAcceleratorAck(mojom::EventResult::UNHANDLED, KeyEvent::Properties()); 439 OnAcceleratorAck(mojom::EventResult::UNHANDLED, KeyEvent::Properties());
435 } else { 440 } else {
436 OnEventAck(in_flight_event_details_->tree, mojom::EventResult::UNHANDLED); 441 OnEventAck(in_flight_event_dispatch_details_->tree,
442 mojom::EventResult::UNHANDLED);
437 } 443 }
438 } 444 }
439 445
440 void WindowManagerState::ProcessEventImpl(const ui::Event& event, 446 void WindowManagerState::ProcessEventImpl(const ui::Event& event,
441 int64_t display_id) { 447 int64_t display_id) {
448 DCHECK(!in_flight_event_dispatch_details_ &&
449 !event_dispatcher_.IsProcessingEvent());
442 // Debug accelerators are always checked and don't interfere with processing. 450 // Debug accelerators are always checked and don't interfere with processing.
443 ProcessDebugAccelerator(event, display_id); 451 ProcessDebugAccelerator(event, display_id);
444 event_dispatcher_.ProcessEvent(event, display_id, 452 event_dispatcher_.ProcessEvent(event, display_id,
445 EventDispatcher::AcceleratorMatchPhase::ANY); 453 EventDispatcher::AcceleratorMatchPhase::ANY);
446 } 454 }
447 455
448 void WindowManagerState::QueueEvent( 456 void WindowManagerState::QueueEvent(
449 const ui::Event& event, 457 const ui::Event& event,
450 std::unique_ptr<ProcessedEventTarget> processed_event_target, 458 std::unique_ptr<ProcessedEventTarget> processed_event_target,
451 int64_t display_id) { 459 int64_t display_id) {
452 std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent); 460 std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent);
453 queued_event->event = ui::Event::Clone(event); 461 queued_event->event = ui::Event::Clone(event);
454 queued_event->processed_target = std::move(processed_event_target); 462 queued_event->processed_target = std::move(processed_event_target);
455 queued_event->display_id = display_id; 463 queued_event->display_id = display_id;
456 event_queue_.push(std::move(queued_event)); 464 event_queue_.push(std::move(queued_event));
457 } 465 }
458 466
459 void WindowManagerState::ProcessNextEventFromQueue() { 467 // TODO(riajiang): We might want to do event targeting for the next event while
460 // Loop through |event_queue_| stopping after dispatching the first valid 468 // waiting for the current event to be dispatched. crbug.com/724521
461 // event.
462 while (!event_queue_.empty()) {
463 std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front());
464 event_queue_.pop();
465 if (!queued_event->processed_target) {
466 ProcessEventImpl(*queued_event->event, queued_event->display_id);
467 return;
468 }
469 if (queued_event->processed_target->IsValid()) {
470 DispatchInputEventToWindowImpl(
471 queued_event->processed_target->window(),
472 queued_event->processed_target->client_id(), queued_event->display_id,
473 *queued_event->event, queued_event->processed_target->accelerator());
474 return;
475 }
476 }
477 }
478
479 void WindowManagerState::DispatchInputEventToWindowImpl( 469 void WindowManagerState::DispatchInputEventToWindowImpl(
480 ServerWindow* target, 470 ServerWindow* target,
481 ClientSpecificId client_id, 471 ClientSpecificId client_id,
482 const int64_t display_id, 472 int64_t display_id,
483 const ui::Event& event, 473 const ui::Event& event,
484 base::WeakPtr<Accelerator> accelerator) { 474 base::WeakPtr<Accelerator> accelerator) {
475 DCHECK(!in_flight_event_dispatch_details_);
485 DCHECK(target); 476 DCHECK(target);
486 if (target->parent() == nullptr) 477 if (target->parent() == nullptr)
487 target = GetWindowManagerRootForDisplayRoot(target); 478 target = GetWindowManagerRootForDisplayRoot(target);
488 479
489 if (event.IsMousePointerEvent()) { 480 if (event.IsMousePointerEvent()) {
490 DCHECK(event_dispatcher_.mouse_cursor_source_window()); 481 DCHECK(event_dispatcher_.mouse_cursor_source_window());
491 UpdateNativeCursorFromDispatcher(); 482 UpdateNativeCursorFromDispatcher();
492 } 483 }
493 484
494 WindowTree* tree = window_server()->GetTreeWithId(client_id); 485 WindowTree* tree = window_server()->GetTreeWithId(client_id);
495 DCHECK(tree); 486 DCHECK(tree);
496 ScheduleInputEventTimeout(tree, target, display_id, event, 487 ScheduleInputEventTimeout(tree, target, display_id, event,
497 EventDispatchPhase::TARGET); 488 EventDispatchPhase::TARGET);
498 in_flight_event_details_->post_target_accelerator = accelerator; 489 in_flight_event_dispatch_details_->post_target_accelerator = accelerator;
499 490
500 // Ignore |tree| because it will receive the event via normal dispatch. 491 // Ignore |tree| because it will receive the event via normal dispatch.
501 window_server()->SendToPointerWatchers(event, user_id(), target, tree, 492 window_server()->SendToPointerWatchers(
502 in_flight_event_details_->display_id); 493 event, user_id(), target, tree,
494 in_flight_event_dispatch_details_->display_id);
503 495
504 tree->DispatchInputEvent( 496 tree->DispatchInputEvent(
505 target, event, 497 target, event,
506 base::BindOnce(&WindowManagerState::OnEventAck, 498 base::BindOnce(
507 in_flight_event_details_->weak_factory.GetWeakPtr(), 499 &WindowManagerState::OnEventAck,
508 tree)); 500 in_flight_event_dispatch_details_->weak_factory.GetWeakPtr(), tree));
509 } 501 }
510 502
511 void WindowManagerState::AddDebugAccelerators() { 503 void WindowManagerState::AddDebugAccelerators() {
512 const DebugAccelerator accelerator = { 504 const DebugAccelerator accelerator = {
513 DebugAcceleratorType::PRINT_WINDOWS, ui::VKEY_S, 505 DebugAcceleratorType::PRINT_WINDOWS, ui::VKEY_S,
514 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN}; 506 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN};
515 debug_accelerators_.push_back(accelerator); 507 debug_accelerators_.push_back(accelerator);
516 } 508 }
517 509
518 void WindowManagerState::ProcessDebugAccelerator(const ui::Event& event, 510 void WindowManagerState::ProcessDebugAccelerator(const ui::Event& event,
519 const int64_t display_id) { 511 int64_t display_id) {
520 if (event.type() != ui::ET_KEY_PRESSED) 512 if (event.type() != ui::ET_KEY_PRESSED)
521 return; 513 return;
522 514
523 const ui::KeyEvent& key_event = *event.AsKeyEvent(); 515 const ui::KeyEvent& key_event = *event.AsKeyEvent();
524 for (const DebugAccelerator& accelerator : debug_accelerators_) { 516 for (const DebugAccelerator& accelerator : debug_accelerators_) {
525 if (accelerator.Matches(key_event)) { 517 if (accelerator.Matches(key_event)) {
526 HandleDebugAccelerator(accelerator.type, display_id); 518 HandleDebugAccelerator(accelerator.type, display_id);
527 break; 519 break;
528 } 520 }
529 } 521 }
530 } 522 }
531 523
532 void WindowManagerState::HandleDebugAccelerator(DebugAcceleratorType type, 524 void WindowManagerState::HandleDebugAccelerator(DebugAcceleratorType type,
533 const int64_t display_id) { 525 int64_t display_id) {
534 #if DCHECK_IS_ON() 526 #if DCHECK_IS_ON()
535 // Error so it will be collected in system logs. 527 // Error so it will be collected in system logs.
536 for (Display* display : display_manager()->displays()) { 528 for (Display* display : display_manager()->displays()) {
537 WindowManagerDisplayRoot* display_root = 529 WindowManagerDisplayRoot* display_root =
538 display->GetWindowManagerDisplayRootForUser(user_id()); 530 display->GetWindowManagerDisplayRootForUser(user_id());
539 if (display_root) { 531 if (display_root) {
540 LOG(ERROR) << "ServerWindow hierarchy:\n" 532 LOG(ERROR) << "ServerWindow hierarchy:\n"
541 << display_root->root()->GetDebugWindowHierarchy(); 533 << display_root->root()->GetDebugWindowHierarchy();
542 } 534 }
543 } 535 }
544 ServerWindow* focused_window = GetFocusedWindowForEventDispatcher(display_id); 536 ServerWindow* focused_window = GetFocusedWindowForEventDispatcher(display_id);
545 LOG(ERROR) << "Focused window: " 537 LOG(ERROR) << "Focused window: "
546 << (focused_window ? focused_window->id().ToString() : "(null)"); 538 << (focused_window ? focused_window->id().ToString() : "(null)");
547 #endif 539 #endif
548 } 540 }
549 541
550 void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree, 542 void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree,
551 ServerWindow* target, 543 ServerWindow* target,
552 const int64_t display_id, 544 int64_t display_id,
553 const Event& event, 545 const Event& event,
554 EventDispatchPhase phase) { 546 EventDispatchPhase phase) {
555 std::unique_ptr<InFlightEventDetails> details = 547 std::unique_ptr<InFlightEventDispatchDetails> details =
556 base::MakeUnique<InFlightEventDetails>(this, tree, display_id, event, 548 base::MakeUnique<InFlightEventDispatchDetails>(this, tree, display_id,
557 phase); 549 event, phase);
558 550
559 // TOOD(sad): Adjust this delay, possibly make this dynamic. 551 // TOOD(sad): Adjust this delay, possibly make this dynamic.
560 const base::TimeDelta max_delay = base::debug::BeingDebugged() 552 const base::TimeDelta max_delay = base::debug::BeingDebugged()
561 ? base::TimeDelta::FromDays(1) 553 ? base::TimeDelta::FromDays(1)
562 : GetDefaultAckTimerDelay(); 554 : GetDefaultAckTimerDelay();
563 details->timer.Start( 555 details->timer.Start(
564 FROM_HERE, max_delay, 556 FROM_HERE, max_delay,
565 base::Bind(&WindowManagerState::OnEventAckTimeout, 557 base::Bind(&WindowManagerState::OnEventAckTimeout,
566 details->weak_factory.GetWeakPtr(), tree->id())); 558 details->weak_factory.GetWeakPtr(), tree->id()));
567 in_flight_event_details_ = std::move(details); 559 in_flight_event_dispatch_details_ = std::move(details);
568 } 560 }
569 561
570 bool WindowManagerState::ConvertPointToScreen(const int64_t display_id, 562 bool WindowManagerState::ConvertPointToScreen(int64_t display_id,
571 gfx::Point* point) { 563 gfx::Point* point) {
572 Display* display = display_manager()->GetDisplayById(display_id); 564 Display* display = display_manager()->GetDisplayById(display_id);
573 if (display) { 565 if (display) {
574 const display::Display& originated_display = display->GetDisplay(); 566 const display::Display& originated_display = display->GetDisplay();
575 *point = gfx::ConvertPointToDIP(originated_display.device_scale_factor(), 567 *point = gfx::ConvertPointToDIP(originated_display.device_scale_factor(),
576 *point); 568 *point);
577 *point += originated_display.bounds().origin().OffsetFromOrigin(); 569 *point += originated_display.bounds().origin().OffsetFromOrigin();
578 return true; 570 return true;
579 } 571 }
580 return false; 572 return false;
581 } 573 }
582 574
583 //////////////////////////////////////////////////////////////////////////////// 575 ////////////////////////////////////////////////////////////////////////////////
584 // EventDispatcherDelegate: 576 // EventDispatcherDelegate:
585 577
586 void WindowManagerState::OnAccelerator(uint32_t accelerator_id, 578 void WindowManagerState::OnAccelerator(uint32_t accelerator_id,
587 const int64_t display_id, 579 int64_t display_id,
588 const ui::Event& event, 580 const ui::Event& event,
589 AcceleratorPhase phase) { 581 AcceleratorPhase phase) {
590 DCHECK(IsActive()); 582 DCHECK(IsActive());
591 const bool needs_ack = phase == AcceleratorPhase::PRE; 583 const bool needs_ack = phase == AcceleratorPhase::PRE;
592 WindowTree::AcceleratorCallback ack_callback; 584 WindowTree::AcceleratorCallback ack_callback;
593 if (needs_ack) { 585 if (needs_ack) {
594 DCHECK(!in_flight_event_details_); 586 DCHECK(!in_flight_event_dispatch_details_);
595 ScheduleInputEventTimeout(window_tree_, nullptr, display_id, event, 587 ScheduleInputEventTimeout(window_tree_, nullptr, display_id, event,
596 EventDispatchPhase::PRE_TARGET_ACCELERATOR); 588 EventDispatchPhase::PRE_TARGET_ACCELERATOR);
597 ack_callback = 589 ack_callback = base::BindOnce(
598 base::BindOnce(&WindowManagerState::OnAcceleratorAck, 590 &WindowManagerState::OnAcceleratorAck,
599 in_flight_event_details_->weak_factory.GetWeakPtr()); 591 in_flight_event_dispatch_details_->weak_factory.GetWeakPtr());
600 } 592 }
601 window_tree_->OnAccelerator(accelerator_id, event, std::move(ack_callback)); 593 window_tree_->OnAccelerator(accelerator_id, event, std::move(ack_callback));
602 } 594 }
603 595
604 void WindowManagerState::SetFocusedWindowFromEventDispatcher( 596 void WindowManagerState::SetFocusedWindowFromEventDispatcher(
605 ServerWindow* new_focused_window) { 597 ServerWindow* new_focused_window) {
606 DCHECK(IsActive()); 598 DCHECK(IsActive());
607 window_server()->SetFocusedWindow(new_focused_window); 599 window_server()->SetFocusedWindow(new_focused_window);
608 } 600 }
609 601
610 ServerWindow* WindowManagerState::GetFocusedWindowForEventDispatcher( 602 ServerWindow* WindowManagerState::GetFocusedWindowForEventDispatcher(
611 const int64_t display_id) { 603 int64_t display_id) {
612 ServerWindow* focused_window = window_server()->GetFocusedWindow(); 604 ServerWindow* focused_window = window_server()->GetFocusedWindow();
613 if (focused_window) 605 if (focused_window)
614 return focused_window; 606 return focused_window;
615 607
616 // When none of the windows have focus return the window manager's root. 608 // When none of the windows have focus return the window manager's root.
617 for (auto& display_root_ptr : window_manager_display_roots_) { 609 for (auto& display_root_ptr : window_manager_display_roots_) {
618 if (display_root_ptr->display()->GetId() == display_id) 610 if (display_root_ptr->display()->GetId() == display_id)
619 return display_root_ptr->GetClientVisibleRoot(); 611 return display_root_ptr->GetClientVisibleRoot();
620 } 612 }
621 if (!window_manager_display_roots_.empty()) 613 if (!window_manager_display_roots_.empty())
(...skipping 26 matching lines...) Expand all
648 cursor_state_.SetCurrentWindowCursor(cursor); 640 cursor_state_.SetCurrentWindowCursor(cursor);
649 } 641 }
650 642
651 void WindowManagerState::OnCaptureChanged(ServerWindow* new_capture, 643 void WindowManagerState::OnCaptureChanged(ServerWindow* new_capture,
652 ServerWindow* old_capture) { 644 ServerWindow* old_capture) {
653 window_server()->ProcessCaptureChanged(new_capture, old_capture); 645 window_server()->ProcessCaptureChanged(new_capture, old_capture);
654 } 646 }
655 647
656 void WindowManagerState::OnMouseCursorLocationChanged( 648 void WindowManagerState::OnMouseCursorLocationChanged(
657 const gfx::Point& point_in_display, 649 const gfx::Point& point_in_display,
658 const int64_t display_id) { 650 int64_t display_id) {
659 gfx::Point point_in_screen(point_in_display); 651 gfx::Point point_in_screen(point_in_display);
660 if (ConvertPointToScreen(display_id, &point_in_screen)) { 652 if (ConvertPointToScreen(display_id, &point_in_screen)) {
661 window_server() 653 window_server()
662 ->display_manager() 654 ->display_manager()
663 ->GetCursorLocationManager(user_id()) 655 ->GetCursorLocationManager(user_id())
664 ->OnMouseCursorLocationChanged(point_in_screen); 656 ->OnMouseCursorLocationChanged(point_in_screen);
665 } 657 }
666 // If the display the |point_in_display| is on has been deleted, keep the old 658 // If the display the |point_in_display| is on has been deleted, keep the old
667 // cursor location. 659 // cursor location.
668 } 660 }
669 661
670 void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target, 662 void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target,
671 ClientSpecificId client_id, 663 ClientSpecificId client_id,
672 const int64_t display_id, 664 int64_t display_id,
673 const ui::Event& event, 665 const ui::Event& event,
674 Accelerator* accelerator) { 666 Accelerator* accelerator) {
675 DCHECK(IsActive()); 667 DCHECK(IsActive());
676 // TODO(sky): this needs to see if another wms has capture and if so forward 668 // TODO(sky): this needs to see if another wms has capture and if so forward
677 // to it. 669 // to it.
678 if (in_flight_event_details_) { 670 if (in_flight_event_dispatch_details_) {
679 std::unique_ptr<ProcessedEventTarget> processed_event_target( 671 std::unique_ptr<ProcessedEventTarget> processed_event_target(
680 new ProcessedEventTarget(target, client_id, accelerator)); 672 new ProcessedEventTarget(target, client_id, accelerator));
681 QueueEvent(event, std::move(processed_event_target), display_id); 673 QueueEvent(event, std::move(processed_event_target), display_id);
682 return; 674 return;
683 } 675 }
684 676
685 base::WeakPtr<Accelerator> weak_accelerator; 677 base::WeakPtr<Accelerator> weak_accelerator;
686 if (accelerator) 678 if (accelerator)
687 weak_accelerator = accelerator->GetWeakPtr(); 679 weak_accelerator = accelerator->GetWeakPtr();
688 DispatchInputEventToWindowImpl(target, client_id, display_id, event, 680 DispatchInputEventToWindowImpl(target, client_id, display_id, event,
689 weak_accelerator); 681 weak_accelerator);
690 } 682 }
691 683
684 void WindowManagerState::ProcessNextAvailableEvent() {
685 // Loop through |event_queue_| stopping after dispatching the first valid
686 // event.
687 while (!event_queue_.empty()) {
688 if (in_flight_event_dispatch_details_)
689 return;
690
691 if (!event_queue_.front()->processed_target &&
692 event_dispatcher_.IsProcessingEvent())
693 return;
694
695 std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front());
696 event_queue_.pop();
697 if (!queued_event->processed_target) {
698 ProcessEventImpl(*queued_event->event, queued_event->display_id);
699 return;
700 }
701 if (queued_event->processed_target->IsValid()) {
702 DispatchInputEventToWindowImpl(
703 queued_event->processed_target->window(),
704 queued_event->processed_target->client_id(), queued_event->display_id,
705 *queued_event->event, queued_event->processed_target->accelerator());
706 return;
707 }
708 }
709 }
710
692 ClientSpecificId WindowManagerState::GetEventTargetClientId( 711 ClientSpecificId WindowManagerState::GetEventTargetClientId(
693 const ServerWindow* window, 712 const ServerWindow* window,
694 bool in_nonclient_area) { 713 bool in_nonclient_area) {
695 if (in_nonclient_area) { 714 if (in_nonclient_area) {
696 // Events in the non-client area always go to the window manager. 715 // Events in the non-client area always go to the window manager.
697 return window_tree_->id(); 716 return window_tree_->id();
698 } 717 }
699 718
700 // If the window is an embed root, it goes to the tree embedded in the window. 719 // If the window is an embed root, it goes to the tree embedded in the window.
701 WindowTree* tree = window_server()->GetTreeWithRoot(window); 720 WindowTree* tree = window_server()->GetTreeWithRoot(window);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 *location_in_display = gfx::ConvertPointToPixel( 772 *location_in_display = gfx::ConvertPointToPixel(
754 target_display_root->display()->GetDisplay().device_scale_factor(), 773 target_display_root->display()->GetDisplay().device_scale_factor(),
755 *location_in_display); 774 *location_in_display);
756 *display_id = target_display_root->display()->GetId(); 775 *display_id = target_display_root->display()->GetId();
757 } 776 }
758 777
759 return target_display_root->GetClientVisibleRoot(); 778 return target_display_root->GetClientVisibleRoot();
760 } 779 }
761 780
762 void WindowManagerState::OnEventTargetNotFound(const ui::Event& event, 781 void WindowManagerState::OnEventTargetNotFound(const ui::Event& event,
763 const int64_t display_id) { 782 int64_t display_id) {
764 window_server()->SendToPointerWatchers(event, user_id(), nullptr, /* window */ 783 window_server()->SendToPointerWatchers(event, user_id(), nullptr, /* window */
765 nullptr /* ignore_tree */, display_id); 784 nullptr /* ignore_tree */, display_id);
766 if (event.IsMousePointerEvent()) 785 if (event.IsMousePointerEvent())
767 UpdateNativeCursorFromDispatcher(); 786 UpdateNativeCursorFromDispatcher();
768 } 787 }
769 788
770 void WindowManagerState::OnWindowEmbeddedAppDisconnected(ServerWindow* window) { 789 void WindowManagerState::OnWindowEmbeddedAppDisconnected(ServerWindow* window) {
771 for (auto iter = orphaned_window_manager_display_roots_.begin(); 790 for (auto iter = orphaned_window_manager_display_roots_.begin();
772 iter != orphaned_window_manager_display_roots_.end(); ++iter) { 791 iter != orphaned_window_manager_display_roots_.end(); ++iter) {
773 if ((*iter)->root() == window) { 792 if ((*iter)->root() == window) {
774 window->RemoveObserver(this); 793 window->RemoveObserver(this);
775 orphaned_window_manager_display_roots_.erase(iter); 794 orphaned_window_manager_display_roots_.erase(iter);
776 return; 795 return;
777 } 796 }
778 } 797 }
779 NOTREACHED(); 798 NOTREACHED();
780 } 799 }
781 800
782 } // namespace ws 801 } // namespace ws
783 } // namespace ui 802 } // namespace ui
OLDNEW
« no previous file with comments | « services/ui/ws/window_manager_state.h ('k') | services/ui/ws/window_manager_state_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698