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