| OLD | NEW |
| 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/platform_display.h" | 18 #include "services/ui/ws/platform_display.h" |
| 19 #include "services/ui/ws/server_window.h" | 19 #include "services/ui/ws/server_window.h" |
| 20 #include "services/ui/ws/user_display_manager.h" | 20 #include "services/ui/ws/user_display_manager.h" |
| 21 #include "services/ui/ws/user_id_tracker.h" | 21 #include "services/ui/ws/user_id_tracker.h" |
| 22 #include "services/ui/ws/window_manager_display_root.h" | 22 #include "services/ui/ws/window_manager_display_root.h" |
| 23 #include "services/ui/ws/window_server.h" | 23 #include "services/ui/ws/window_server.h" |
| 24 #include "services/ui/ws/window_tree.h" | 24 #include "services/ui/ws/window_tree.h" |
| 25 #include "ui/events/event.h" | 25 #include "ui/events/event.h" |
| 26 #include "ui/gfx/geometry/dip_util.h" |
| 26 | 27 |
| 27 namespace ui { | 28 namespace ui { |
| 28 namespace ws { | 29 namespace ws { |
| 29 namespace { | 30 namespace { |
| 30 | 31 |
| 31 // Flags that matter when checking if a key event matches an accelerator. | 32 // Flags that matter when checking if a key event matches an accelerator. |
| 32 const int kAcceleratorEventFlags = | 33 const int kAcceleratorEventFlags = |
| 33 EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_ALT_DOWN | EF_COMMAND_DOWN; | 34 EF_SHIFT_DOWN | EF_CONTROL_DOWN | EF_ALT_DOWN | EF_COMMAND_DOWN; |
| 34 | 35 |
| 35 base::TimeDelta GetDefaultAckTimerDelay() { | 36 base::TimeDelta GetDefaultAckTimerDelay() { |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 if (display_root_ptr->root()->id() == id) | 273 if (display_root_ptr->root()->id() == id) |
| 273 return display_root_ptr->root(); | 274 return display_root_ptr->root(); |
| 274 } | 275 } |
| 275 return nullptr; | 276 return nullptr; |
| 276 } | 277 } |
| 277 | 278 |
| 278 bool WindowManagerState::IsActive() const { | 279 bool WindowManagerState::IsActive() const { |
| 279 return window_server()->user_id_tracker()->active_id() == user_id(); | 280 return window_server()->user_id_tracker()->active_id() == user_id(); |
| 280 } | 281 } |
| 281 | 282 |
| 282 void WindowManagerState::Activate(const gfx::Point& mouse_location_on_screen) { | 283 void WindowManagerState::Activate(const gfx::Point& mouse_location_on_display, |
| 284 const int64_t display_id) { |
| 283 SetAllRootWindowsVisible(true); | 285 SetAllRootWindowsVisible(true); |
| 284 event_dispatcher_.Reset(); | 286 event_dispatcher_.Reset(); |
| 285 event_dispatcher_.SetMousePointerScreenLocation(mouse_location_on_screen); | 287 event_dispatcher_.SetMousePointerDisplayLocation(mouse_location_on_display, |
| 288 display_id); |
| 286 } | 289 } |
| 287 | 290 |
| 288 void WindowManagerState::Deactivate() { | 291 void WindowManagerState::Deactivate() { |
| 289 SetAllRootWindowsVisible(false); | 292 SetAllRootWindowsVisible(false); |
| 290 event_dispatcher_.Reset(); | 293 event_dispatcher_.Reset(); |
| 291 // The tree is no longer active, so no point in dispatching any further | 294 // The tree is no longer active, so no point in dispatching any further |
| 292 // events. | 295 // events. |
| 293 std::queue<std::unique_ptr<QueuedEvent>> event_queue; | 296 std::queue<std::unique_ptr<QueuedEvent>> event_queue; |
| 294 event_queue.swap(event_queue_); | 297 event_queue.swap(event_queue_); |
| 295 } | 298 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 320 DCHECK_EQ(EventDispatchPhase::PRE_TARGET_ACCELERATOR, | 323 DCHECK_EQ(EventDispatchPhase::PRE_TARGET_ACCELERATOR, |
| 321 in_flight_event_details_->phase); | 324 in_flight_event_details_->phase); |
| 322 | 325 |
| 323 std::unique_ptr<InFlightEventDetails> details = | 326 std::unique_ptr<InFlightEventDetails> details = |
| 324 std::move(in_flight_event_details_); | 327 std::move(in_flight_event_details_); |
| 325 | 328 |
| 326 if (result == mojom::EventResult::UNHANDLED) { | 329 if (result == mojom::EventResult::UNHANDLED) { |
| 327 DCHECK(details->event->IsKeyEvent()); | 330 DCHECK(details->event->IsKeyEvent()); |
| 328 if (!properties.empty()) | 331 if (!properties.empty()) |
| 329 details->event->AsKeyEvent()->SetProperties(properties); | 332 details->event->AsKeyEvent()->SetProperties(properties); |
| 330 event_processing_display_id_ = details->display_id; | |
| 331 event_dispatcher_.ProcessEvent( | 333 event_dispatcher_.ProcessEvent( |
| 332 *details->event, EventDispatcher::AcceleratorMatchPhase::POST_ONLY); | 334 *details->event, details->display_id, |
| 335 EventDispatcher::AcceleratorMatchPhase::POST_ONLY); |
| 333 } else { | 336 } else { |
| 334 // We're not going to process the event any further, notify event observers. | 337 // We're not going to process the event any further, notify event observers. |
| 335 // We don't do this first to ensure we don't send an event twice to clients. | 338 // We don't do this first to ensure we don't send an event twice to clients. |
| 336 window_server()->SendToPointerWatchers(*details->event, user_id(), nullptr, | 339 window_server()->SendToPointerWatchers(*details->event, user_id(), nullptr, |
| 337 nullptr, details->display_id); | 340 nullptr, details->display_id); |
| 338 ProcessNextEventFromQueue(); | 341 ProcessNextEventFromQueue(); |
| 339 } | 342 } |
| 340 } | 343 } |
| 341 | 344 |
| 342 const WindowServer* WindowManagerState::window_server() const { | 345 const WindowServer* WindowManagerState::window_server() const { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 } | 397 } |
| 395 | 398 |
| 396 void WindowManagerState::OnEventAck(mojom::WindowTree* tree, | 399 void WindowManagerState::OnEventAck(mojom::WindowTree* tree, |
| 397 mojom::EventResult result) { | 400 mojom::EventResult result) { |
| 398 DCHECK(in_flight_event_details_); | 401 DCHECK(in_flight_event_details_); |
| 399 std::unique_ptr<InFlightEventDetails> details = | 402 std::unique_ptr<InFlightEventDetails> details = |
| 400 std::move(in_flight_event_details_); | 403 std::move(in_flight_event_details_); |
| 401 | 404 |
| 402 if (result == mojom::EventResult::UNHANDLED && | 405 if (result == mojom::EventResult::UNHANDLED && |
| 403 details->post_target_accelerator) { | 406 details->post_target_accelerator) { |
| 404 OnAccelerator(details->post_target_accelerator->id(), *details->event, | 407 OnAccelerator(details->post_target_accelerator->id(), details->display_id, |
| 405 AcceleratorPhase::POST); | 408 *details->event, AcceleratorPhase::POST); |
| 406 } | 409 } |
| 407 | 410 |
| 408 ProcessNextEventFromQueue(); | 411 ProcessNextEventFromQueue(); |
| 409 } | 412 } |
| 410 | 413 |
| 411 void WindowManagerState::OnEventAckTimeout(ClientSpecificId client_id) { | 414 void WindowManagerState::OnEventAckTimeout(ClientSpecificId client_id) { |
| 412 WindowTree* hung_tree = window_server()->GetTreeWithId(client_id); | 415 WindowTree* hung_tree = window_server()->GetTreeWithId(client_id); |
| 413 if (hung_tree && !hung_tree->janky()) | 416 if (hung_tree && !hung_tree->janky()) |
| 414 window_tree_->ClientJankinessChanged(hung_tree); | 417 window_tree_->ClientJankinessChanged(hung_tree); |
| 415 if (in_flight_event_details_->phase == | 418 if (in_flight_event_details_->phase == |
| 416 EventDispatchPhase::PRE_TARGET_ACCELERATOR) { | 419 EventDispatchPhase::PRE_TARGET_ACCELERATOR) { |
| 417 OnAcceleratorAck(mojom::EventResult::UNHANDLED, KeyEvent::Properties()); | 420 OnAcceleratorAck(mojom::EventResult::UNHANDLED, KeyEvent::Properties()); |
| 418 } else { | 421 } else { |
| 419 OnEventAck(in_flight_event_details_->tree, mojom::EventResult::UNHANDLED); | 422 OnEventAck(in_flight_event_details_->tree, mojom::EventResult::UNHANDLED); |
| 420 } | 423 } |
| 421 } | 424 } |
| 422 | 425 |
| 423 void WindowManagerState::ProcessEventImpl(const ui::Event& event, | 426 void WindowManagerState::ProcessEventImpl(const ui::Event& event, |
| 424 int64_t display_id) { | 427 int64_t display_id) { |
| 425 // Debug accelerators are always checked and don't interfere with processing. | 428 // Debug accelerators are always checked and don't interfere with processing. |
| 426 ProcessDebugAccelerator(event); | 429 ProcessDebugAccelerator(event, display_id); |
| 427 event_processing_display_id_ = display_id; | 430 event_dispatcher_.ProcessEvent(event, display_id, |
| 428 event_dispatcher_.ProcessEvent(event, | |
| 429 EventDispatcher::AcceleratorMatchPhase::ANY); | 431 EventDispatcher::AcceleratorMatchPhase::ANY); |
| 430 } | 432 } |
| 431 | 433 |
| 432 void WindowManagerState::QueueEvent( | 434 void WindowManagerState::QueueEvent( |
| 433 const ui::Event& event, | 435 const ui::Event& event, |
| 434 std::unique_ptr<ProcessedEventTarget> processed_event_target, | 436 std::unique_ptr<ProcessedEventTarget> processed_event_target, |
| 435 int64_t display_id) { | 437 int64_t display_id) { |
| 436 std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent); | 438 std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent); |
| 437 queued_event->event = ui::Event::Clone(event); | 439 queued_event->event = ui::Event::Clone(event); |
| 438 queued_event->processed_target = std::move(processed_event_target); | 440 queued_event->processed_target = std::move(processed_event_target); |
| 439 queued_event->display_id = display_id; | 441 queued_event->display_id = display_id; |
| 440 event_queue_.push(std::move(queued_event)); | 442 event_queue_.push(std::move(queued_event)); |
| 441 } | 443 } |
| 442 | 444 |
| 443 void WindowManagerState::ProcessNextEventFromQueue() { | 445 void WindowManagerState::ProcessNextEventFromQueue() { |
| 444 // Loop through |event_queue_| stopping after dispatching the first valid | 446 // Loop through |event_queue_| stopping after dispatching the first valid |
| 445 // event. | 447 // event. |
| 446 while (!event_queue_.empty()) { | 448 while (!event_queue_.empty()) { |
| 447 std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front()); | 449 std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front()); |
| 448 event_queue_.pop(); | 450 event_queue_.pop(); |
| 449 if (!queued_event->processed_target) { | 451 if (!queued_event->processed_target) { |
| 450 ProcessEventImpl(*queued_event->event, queued_event->display_id); | 452 ProcessEventImpl(*queued_event->event, queued_event->display_id); |
| 451 return; | 453 return; |
| 452 } | 454 } |
| 453 if (queued_event->processed_target->IsValid()) { | 455 if (queued_event->processed_target->IsValid()) { |
| 454 DispatchInputEventToWindowImpl( | 456 DispatchInputEventToWindowImpl( |
| 455 queued_event->processed_target->window(), | 457 queued_event->processed_target->window(), |
| 456 queued_event->processed_target->client_id(), *queued_event->event, | 458 queued_event->processed_target->client_id(), queued_event->display_id, |
| 457 queued_event->processed_target->accelerator()); | 459 *queued_event->event, queued_event->processed_target->accelerator()); |
| 458 return; | 460 return; |
| 459 } | 461 } |
| 460 } | 462 } |
| 461 } | 463 } |
| 462 | 464 |
| 463 void WindowManagerState::DispatchInputEventToWindowImpl( | 465 void WindowManagerState::DispatchInputEventToWindowImpl( |
| 464 ServerWindow* target, | 466 ServerWindow* target, |
| 465 ClientSpecificId client_id, | 467 ClientSpecificId client_id, |
| 468 const int64_t display_id, |
| 466 const ui::Event& event, | 469 const ui::Event& event, |
| 467 base::WeakPtr<Accelerator> accelerator) { | 470 base::WeakPtr<Accelerator> accelerator) { |
| 468 DCHECK(target); | 471 DCHECK(target); |
| 469 if (target->parent() == nullptr) | 472 if (target->parent() == nullptr) |
| 470 target = GetWindowManagerRootForDisplayRoot(target); | 473 target = GetWindowManagerRootForDisplayRoot(target); |
| 471 | 474 |
| 472 if (event.IsMousePointerEvent()) { | 475 if (event.IsMousePointerEvent()) { |
| 473 DCHECK(event_dispatcher_.mouse_cursor_source_window()); | 476 DCHECK(event_dispatcher_.mouse_cursor_source_window()); |
| 474 UpdateNativeCursorFromDispatcher(); | 477 UpdateNativeCursorFromDispatcher(); |
| 475 } | 478 } |
| 476 | 479 |
| 477 WindowTree* tree = window_server()->GetTreeWithId(client_id); | 480 WindowTree* tree = window_server()->GetTreeWithId(client_id); |
| 478 DCHECK(tree); | 481 DCHECK(tree); |
| 479 ScheduleInputEventTimeout(tree, target, event, EventDispatchPhase::TARGET); | 482 ScheduleInputEventTimeout(tree, target, display_id, event, |
| 483 EventDispatchPhase::TARGET); |
| 480 in_flight_event_details_->post_target_accelerator = accelerator; | 484 in_flight_event_details_->post_target_accelerator = accelerator; |
| 481 | 485 |
| 482 // Ignore |tree| because it will receive the event via normal dispatch. | 486 // Ignore |tree| because it will receive the event via normal dispatch. |
| 483 window_server()->SendToPointerWatchers(event, user_id(), target, tree, | 487 window_server()->SendToPointerWatchers(event, user_id(), target, tree, |
| 484 in_flight_event_details_->display_id); | 488 in_flight_event_details_->display_id); |
| 485 | 489 |
| 486 tree->DispatchInputEvent( | 490 tree->DispatchInputEvent( |
| 487 target, event, | 491 target, event, |
| 488 base::BindOnce(&WindowManagerState::OnEventAck, | 492 base::BindOnce(&WindowManagerState::OnEventAck, |
| 489 in_flight_event_details_->weak_factory.GetWeakPtr(), | 493 in_flight_event_details_->weak_factory.GetWeakPtr(), |
| 490 tree)); | 494 tree)); |
| 491 } | 495 } |
| 492 | 496 |
| 493 void WindowManagerState::AddDebugAccelerators() { | 497 void WindowManagerState::AddDebugAccelerators() { |
| 494 const DebugAccelerator accelerator = { | 498 const DebugAccelerator accelerator = { |
| 495 DebugAcceleratorType::PRINT_WINDOWS, ui::VKEY_S, | 499 DebugAcceleratorType::PRINT_WINDOWS, ui::VKEY_S, |
| 496 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN}; | 500 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN}; |
| 497 debug_accelerators_.push_back(accelerator); | 501 debug_accelerators_.push_back(accelerator); |
| 498 } | 502 } |
| 499 | 503 |
| 500 void WindowManagerState::ProcessDebugAccelerator(const ui::Event& event) { | 504 void WindowManagerState::ProcessDebugAccelerator(const ui::Event& event, |
| 505 const int64_t display_id) { |
| 501 if (event.type() != ui::ET_KEY_PRESSED) | 506 if (event.type() != ui::ET_KEY_PRESSED) |
| 502 return; | 507 return; |
| 503 | 508 |
| 504 const ui::KeyEvent& key_event = *event.AsKeyEvent(); | 509 const ui::KeyEvent& key_event = *event.AsKeyEvent(); |
| 505 for (const DebugAccelerator& accelerator : debug_accelerators_) { | 510 for (const DebugAccelerator& accelerator : debug_accelerators_) { |
| 506 if (accelerator.Matches(key_event)) { | 511 if (accelerator.Matches(key_event)) { |
| 507 HandleDebugAccelerator(accelerator.type); | 512 HandleDebugAccelerator(accelerator.type, display_id); |
| 508 break; | 513 break; |
| 509 } | 514 } |
| 510 } | 515 } |
| 511 } | 516 } |
| 512 | 517 |
| 513 void WindowManagerState::HandleDebugAccelerator(DebugAcceleratorType type) { | 518 void WindowManagerState::HandleDebugAccelerator(DebugAcceleratorType type, |
| 519 const int64_t display_id) { |
| 514 #if DCHECK_IS_ON() | 520 #if DCHECK_IS_ON() |
| 515 // Error so it will be collected in system logs. | 521 // Error so it will be collected in system logs. |
| 516 for (Display* display : display_manager()->displays()) { | 522 for (Display* display : display_manager()->displays()) { |
| 517 WindowManagerDisplayRoot* display_root = | 523 WindowManagerDisplayRoot* display_root = |
| 518 display->GetWindowManagerDisplayRootForUser(user_id()); | 524 display->GetWindowManagerDisplayRootForUser(user_id()); |
| 519 if (display_root) { | 525 if (display_root) { |
| 520 LOG(ERROR) << "ServerWindow hierarchy:\n" | 526 LOG(ERROR) << "ServerWindow hierarchy:\n" |
| 521 << display_root->root()->GetDebugWindowHierarchy(); | 527 << display_root->root()->GetDebugWindowHierarchy(); |
| 522 } | 528 } |
| 523 } | 529 } |
| 524 ServerWindow* focused_window = GetFocusedWindowForEventDispatcher(); | 530 ServerWindow* focused_window = GetFocusedWindowForEventDispatcher(display_id); |
| 525 LOG(ERROR) << "Focused window: " | 531 LOG(ERROR) << "Focused window: " |
| 526 << (focused_window ? focused_window->id().ToString() : "(null)"); | 532 << (focused_window ? focused_window->id().ToString() : "(null)"); |
| 527 #endif | 533 #endif |
| 528 } | 534 } |
| 529 | 535 |
| 530 void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree, | 536 void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree, |
| 531 ServerWindow* target, | 537 ServerWindow* target, |
| 538 const int64_t display_id, |
| 532 const Event& event, | 539 const Event& event, |
| 533 EventDispatchPhase phase) { | 540 EventDispatchPhase phase) { |
| 534 std::unique_ptr<InFlightEventDetails> details = | 541 std::unique_ptr<InFlightEventDetails> details = |
| 535 base::MakeUnique<InFlightEventDetails>( | 542 base::MakeUnique<InFlightEventDetails>(this, tree, display_id, event, |
| 536 this, tree, event_processing_display_id_, event, phase); | 543 phase); |
| 537 | 544 |
| 538 // TOOD(sad): Adjust this delay, possibly make this dynamic. | 545 // TOOD(sad): Adjust this delay, possibly make this dynamic. |
| 539 const base::TimeDelta max_delay = base::debug::BeingDebugged() | 546 const base::TimeDelta max_delay = base::debug::BeingDebugged() |
| 540 ? base::TimeDelta::FromDays(1) | 547 ? base::TimeDelta::FromDays(1) |
| 541 : GetDefaultAckTimerDelay(); | 548 : GetDefaultAckTimerDelay(); |
| 542 details->timer.Start( | 549 details->timer.Start( |
| 543 FROM_HERE, max_delay, | 550 FROM_HERE, max_delay, |
| 544 base::Bind(&WindowManagerState::OnEventAckTimeout, | 551 base::Bind(&WindowManagerState::OnEventAckTimeout, |
| 545 details->weak_factory.GetWeakPtr(), tree->id())); | 552 details->weak_factory.GetWeakPtr(), tree->id())); |
| 546 in_flight_event_details_ = std::move(details); | 553 in_flight_event_details_ = std::move(details); |
| 547 } | 554 } |
| 548 | 555 |
| 556 bool WindowManagerState::ConvertPointToScreen(const int64_t display_id, |
| 557 gfx::Point* point) { |
| 558 Display* display = display_manager()->GetDisplayById(display_id); |
| 559 if (display) { |
| 560 const display::Display& originated_display = display->GetDisplay(); |
| 561 *point = gfx::ConvertPointToDIP(originated_display.device_scale_factor(), |
| 562 *point); |
| 563 *point += originated_display.bounds().origin().OffsetFromOrigin(); |
| 564 return true; |
| 565 } |
| 566 return false; |
| 567 } |
| 568 |
| 549 //////////////////////////////////////////////////////////////////////////////// | 569 //////////////////////////////////////////////////////////////////////////////// |
| 550 // EventDispatcherDelegate: | 570 // EventDispatcherDelegate: |
| 551 | 571 |
| 552 void WindowManagerState::OnAccelerator(uint32_t accelerator_id, | 572 void WindowManagerState::OnAccelerator(uint32_t accelerator_id, |
| 573 const int64_t display_id, |
| 553 const ui::Event& event, | 574 const ui::Event& event, |
| 554 AcceleratorPhase phase) { | 575 AcceleratorPhase phase) { |
| 555 DCHECK(IsActive()); | 576 DCHECK(IsActive()); |
| 556 const bool needs_ack = phase == AcceleratorPhase::PRE; | 577 const bool needs_ack = phase == AcceleratorPhase::PRE; |
| 557 WindowTree::AcceleratorCallback ack_callback; | 578 WindowTree::AcceleratorCallback ack_callback; |
| 558 if (needs_ack) { | 579 if (needs_ack) { |
| 559 DCHECK(!in_flight_event_details_); | 580 DCHECK(!in_flight_event_details_); |
| 560 ScheduleInputEventTimeout(window_tree_, nullptr, event, | 581 ScheduleInputEventTimeout(window_tree_, nullptr, display_id, event, |
| 561 EventDispatchPhase::PRE_TARGET_ACCELERATOR); | 582 EventDispatchPhase::PRE_TARGET_ACCELERATOR); |
| 562 ack_callback = | 583 ack_callback = |
| 563 base::BindOnce(&WindowManagerState::OnAcceleratorAck, | 584 base::BindOnce(&WindowManagerState::OnAcceleratorAck, |
| 564 in_flight_event_details_->weak_factory.GetWeakPtr()); | 585 in_flight_event_details_->weak_factory.GetWeakPtr()); |
| 565 } | 586 } |
| 566 window_tree_->OnAccelerator(accelerator_id, event, std::move(ack_callback)); | 587 window_tree_->OnAccelerator(accelerator_id, event, std::move(ack_callback)); |
| 567 } | 588 } |
| 568 | 589 |
| 569 void WindowManagerState::SetFocusedWindowFromEventDispatcher( | 590 void WindowManagerState::SetFocusedWindowFromEventDispatcher( |
| 570 ServerWindow* new_focused_window) { | 591 ServerWindow* new_focused_window) { |
| 571 DCHECK(IsActive()); | 592 DCHECK(IsActive()); |
| 572 window_server()->SetFocusedWindow(new_focused_window); | 593 window_server()->SetFocusedWindow(new_focused_window); |
| 573 } | 594 } |
| 574 | 595 |
| 575 ServerWindow* WindowManagerState::GetFocusedWindowForEventDispatcher() { | 596 ServerWindow* WindowManagerState::GetFocusedWindowForEventDispatcher( |
| 597 const int64_t display_id) { |
| 576 ServerWindow* focused_window = window_server()->GetFocusedWindow(); | 598 ServerWindow* focused_window = window_server()->GetFocusedWindow(); |
| 577 if (focused_window) | 599 if (focused_window) |
| 578 return focused_window; | 600 return focused_window; |
| 579 | 601 |
| 580 // When none of the windows have focus return the window manager's root. | 602 // When none of the windows have focus return the window manager's root. |
| 581 for (auto& display_root_ptr : window_manager_display_roots_) { | 603 for (auto& display_root_ptr : window_manager_display_roots_) { |
| 582 if (display_root_ptr->display()->GetId() == event_processing_display_id_) | 604 if (display_root_ptr->display()->GetId() == display_id) |
| 583 return display_root_ptr->GetClientVisibleRoot(); | 605 return display_root_ptr->GetClientVisibleRoot(); |
| 584 } | 606 } |
| 585 if (!window_manager_display_roots_.empty()) | 607 if (!window_manager_display_roots_.empty()) |
| 586 return (*window_manager_display_roots_.begin())->GetClientVisibleRoot(); | 608 return (*window_manager_display_roots_.begin())->GetClientVisibleRoot(); |
| 587 return nullptr; | 609 return nullptr; |
| 588 } | 610 } |
| 589 | 611 |
| 590 void WindowManagerState::SetNativeCapture(ServerWindow* window) { | 612 void WindowManagerState::SetNativeCapture(ServerWindow* window) { |
| 591 DCHECK(window); | 613 DCHECK(window); |
| 592 DCHECK(IsActive()); | 614 DCHECK(IsActive()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 610 void WindowManagerState::UpdateNativeCursorFromDispatcher() { | 632 void WindowManagerState::UpdateNativeCursorFromDispatcher() { |
| 611 const ui::CursorData cursor = event_dispatcher_.GetCurrentMouseCursor(); | 633 const ui::CursorData cursor = event_dispatcher_.GetCurrentMouseCursor(); |
| 612 cursor_state_.SetCurrentWindowCursor(cursor); | 634 cursor_state_.SetCurrentWindowCursor(cursor); |
| 613 } | 635 } |
| 614 | 636 |
| 615 void WindowManagerState::OnCaptureChanged(ServerWindow* new_capture, | 637 void WindowManagerState::OnCaptureChanged(ServerWindow* new_capture, |
| 616 ServerWindow* old_capture) { | 638 ServerWindow* old_capture) { |
| 617 window_server()->ProcessCaptureChanged(new_capture, old_capture); | 639 window_server()->ProcessCaptureChanged(new_capture, old_capture); |
| 618 } | 640 } |
| 619 | 641 |
| 620 void WindowManagerState::OnMouseCursorLocationChanged(const gfx::Point& point) { | 642 void WindowManagerState::OnMouseCursorLocationChanged( |
| 621 window_server() | 643 const gfx::Point& point_in_display, |
| 622 ->display_manager() | 644 const int64_t display_id) { |
| 623 ->GetCursorLocationManager(user_id()) | 645 gfx::Point point_in_screen(point_in_display); |
| 624 ->OnMouseCursorLocationChanged(point); | 646 if (ConvertPointToScreen(display_id, &point_in_screen)) { |
| 647 window_server() |
| 648 ->display_manager() |
| 649 ->GetCursorLocationManager(user_id()) |
| 650 ->OnMouseCursorLocationChanged(point_in_screen); |
| 651 } |
| 652 // If the display the |point_in_display| is on has been deleted, keep the old |
| 653 // cursor location. |
| 625 } | 654 } |
| 626 | 655 |
| 627 void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target, | 656 void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target, |
| 628 ClientSpecificId client_id, | 657 ClientSpecificId client_id, |
| 658 const int64_t display_id, |
| 629 const ui::Event& event, | 659 const ui::Event& event, |
| 630 Accelerator* accelerator) { | 660 Accelerator* accelerator) { |
| 631 DCHECK(IsActive()); | 661 DCHECK(IsActive()); |
| 632 // TODO(sky): this needs to see if another wms has capture and if so forward | 662 // TODO(sky): this needs to see if another wms has capture and if so forward |
| 633 // to it. | 663 // to it. |
| 634 if (in_flight_event_details_) { | 664 if (in_flight_event_details_) { |
| 635 std::unique_ptr<ProcessedEventTarget> processed_event_target( | 665 std::unique_ptr<ProcessedEventTarget> processed_event_target( |
| 636 new ProcessedEventTarget(target, client_id, accelerator)); | 666 new ProcessedEventTarget(target, client_id, accelerator)); |
| 637 QueueEvent(event, std::move(processed_event_target), | 667 QueueEvent(event, std::move(processed_event_target), display_id); |
| 638 event_processing_display_id_); | |
| 639 return; | 668 return; |
| 640 } | 669 } |
| 641 | 670 |
| 642 base::WeakPtr<Accelerator> weak_accelerator; | 671 base::WeakPtr<Accelerator> weak_accelerator; |
| 643 if (accelerator) | 672 if (accelerator) |
| 644 weak_accelerator = accelerator->GetWeakPtr(); | 673 weak_accelerator = accelerator->GetWeakPtr(); |
| 645 DispatchInputEventToWindowImpl(target, client_id, event, weak_accelerator); | 674 DispatchInputEventToWindowImpl(target, client_id, display_id, event, |
| 675 weak_accelerator); |
| 646 } | 676 } |
| 647 | 677 |
| 648 ClientSpecificId WindowManagerState::GetEventTargetClientId( | 678 ClientSpecificId WindowManagerState::GetEventTargetClientId( |
| 649 const ServerWindow* window, | 679 const ServerWindow* window, |
| 650 bool in_nonclient_area) { | 680 bool in_nonclient_area) { |
| 651 if (in_nonclient_area) { | 681 if (in_nonclient_area) { |
| 652 // Events in the non-client area always go to the window manager. | 682 // Events in the non-client area always go to the window manager. |
| 653 return window_tree_->id(); | 683 return window_tree_->id(); |
| 654 } | 684 } |
| 655 | 685 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 667 while (tree && tree->embedder_intercepts_events()) { | 697 while (tree && tree->embedder_intercepts_events()) { |
| 668 DCHECK(tree->HasRoot(embed_root)); | 698 DCHECK(tree->HasRoot(embed_root)); |
| 669 tree = window_server()->GetTreeWithId(embed_root->id().client_id); | 699 tree = window_server()->GetTreeWithId(embed_root->id().client_id); |
| 670 embed_root = GetEmbedRoot(embed_root); | 700 embed_root = GetEmbedRoot(embed_root); |
| 671 } | 701 } |
| 672 DCHECK(tree); | 702 DCHECK(tree); |
| 673 return tree->id(); | 703 return tree->id(); |
| 674 } | 704 } |
| 675 | 705 |
| 676 ServerWindow* WindowManagerState::GetRootWindowContaining( | 706 ServerWindow* WindowManagerState::GetRootWindowContaining( |
| 677 gfx::Point* location) { | 707 gfx::Point* location_in_display, |
| 708 int64_t* display_id) { |
| 678 if (window_manager_display_roots_.empty()) | 709 if (window_manager_display_roots_.empty()) |
| 679 return nullptr; | 710 return nullptr; |
| 680 | 711 |
| 681 // TODO(riajiang): This is broken for HDPI because it mixes PPs and DIPs. See | 712 gfx::Point location_in_screen(*location_in_display); |
| 682 // http://crbug.com/701036 for details. | 713 if (!ConvertPointToScreen(*display_id, &location_in_screen)) |
| 714 return nullptr; |
| 715 |
| 683 WindowManagerDisplayRoot* target_display_root = nullptr; | 716 WindowManagerDisplayRoot* target_display_root = nullptr; |
| 684 for (auto& display_root_ptr : window_manager_display_roots_) { | 717 for (auto& display_root_ptr : window_manager_display_roots_) { |
| 685 if (display_root_ptr->display()->GetDisplay().bounds().Contains( | 718 if (display_root_ptr->display()->GetDisplay().bounds().Contains( |
| 686 *location)) { | 719 location_in_screen)) { |
| 687 target_display_root = display_root_ptr.get(); | 720 target_display_root = display_root_ptr.get(); |
| 688 break; | 721 break; |
| 689 } | 722 } |
| 690 } | 723 } |
| 691 | 724 |
| 692 // TODO(kylechar): Better handle locations outside the window. Overlapping X11 | 725 // TODO(kylechar): Better handle locations outside the window. Overlapping X11 |
| 693 // windows, dragging and touch sensors need to be handled properly. | 726 // windows, dragging and touch sensors need to be handled properly. |
| 694 if (!target_display_root) { | 727 if (!target_display_root) { |
| 695 DVLOG(1) << "Invalid event location " << location->ToString(); | 728 DVLOG(1) << "Invalid event location " << location_in_display->ToString() |
| 729 << " / display id " << *display_id; |
| 696 target_display_root = window_manager_display_roots_.begin()->get(); | 730 target_display_root = window_manager_display_roots_.begin()->get(); |
| 697 } | 731 } |
| 698 | 732 |
| 699 // Translate the location to be relative to the display instead of relative | 733 // Update |location_in_display| and |display_id| if the target display is |
| 700 // to the screen space. | 734 // different from the originated display, e.g. drag-and-drop. |
| 701 gfx::Point origin = | 735 if (*display_id != target_display_root->display()->GetId()) { |
| 702 target_display_root->display()->GetDisplay().bounds().origin(); | 736 gfx::Point origin = |
| 703 *location -= origin.OffsetFromOrigin(); | 737 target_display_root->display()->GetDisplay().bounds().origin(); |
| 738 *location_in_display = location_in_screen - origin.OffsetFromOrigin(); |
| 739 *location_in_display = gfx::ConvertPointToPixel( |
| 740 target_display_root->display()->GetDisplay().device_scale_factor(), |
| 741 *location_in_display); |
| 742 *display_id = target_display_root->display()->GetId(); |
| 743 } |
| 744 |
| 704 return target_display_root->GetClientVisibleRoot(); | 745 return target_display_root->GetClientVisibleRoot(); |
| 705 } | 746 } |
| 706 | 747 |
| 707 void WindowManagerState::OnEventTargetNotFound(const ui::Event& event) { | 748 void WindowManagerState::OnEventTargetNotFound(const ui::Event& event, |
| 749 const int64_t display_id) { |
| 708 window_server()->SendToPointerWatchers(event, user_id(), nullptr, /* window */ | 750 window_server()->SendToPointerWatchers(event, user_id(), nullptr, /* window */ |
| 709 nullptr /* ignore_tree */, | 751 nullptr /* ignore_tree */, display_id); |
| 710 event_processing_display_id_); | |
| 711 if (event.IsMousePointerEvent()) | 752 if (event.IsMousePointerEvent()) |
| 712 UpdateNativeCursorFromDispatcher(); | 753 UpdateNativeCursorFromDispatcher(); |
| 713 } | 754 } |
| 714 | 755 |
| 715 void WindowManagerState::OnWindowEmbeddedAppDisconnected(ServerWindow* window) { | 756 void WindowManagerState::OnWindowEmbeddedAppDisconnected(ServerWindow* window) { |
| 716 for (auto iter = orphaned_window_manager_display_roots_.begin(); | 757 for (auto iter = orphaned_window_manager_display_roots_.begin(); |
| 717 iter != orphaned_window_manager_display_roots_.end(); ++iter) { | 758 iter != orphaned_window_manager_display_roots_.end(); ++iter) { |
| 718 if ((*iter)->root() == window) { | 759 if ((*iter)->root() == window) { |
| 719 window->RemoveObserver(this); | 760 window->RemoveObserver(this); |
| 720 orphaned_window_manager_display_roots_.erase(iter); | 761 orphaned_window_manager_display_roots_.erase(iter); |
| 721 return; | 762 return; |
| 722 } | 763 } |
| 723 } | 764 } |
| 724 NOTREACHED(); | 765 NOTREACHED(); |
| 725 } | 766 } |
| 726 | 767 |
| 727 } // namespace ws | 768 } // namespace ws |
| 728 } // namespace ui | 769 } // namespace ui |
| OLD | NEW |