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_.SetMousePointerDisplayLocationAndId( |
| 282 mouse_location_on_display, 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 26 matching lines...) Expand all Loading... | |
| 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; | 327 event_processing_display_id_ = details->display_id; |
| 325 event_dispatcher_.ProcessEvent( | 328 event_dispatcher_.ProcessEvent( |
| 326 *details->event, EventDispatcher::AcceleratorMatchPhase::POST_ONLY); | 329 *details->event, event_processing_display_id_, |
| 330 EventDispatcher::AcceleratorMatchPhase::POST_ONLY); | |
| 327 } else { | 331 } else { |
| 328 // We're not going to process the event any further, notify event observers. | 332 // 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. | 333 // 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, | 334 window_server()->SendToPointerWatchers(*details->event, user_id(), nullptr, |
| 331 nullptr, details->display_id); | 335 nullptr, details->display_id); |
| 332 ProcessNextEventFromQueue(); | 336 ProcessNextEventFromQueue(); |
| 333 } | 337 } |
| 334 } | 338 } |
| 335 | 339 |
| 336 const WindowServer* WindowManagerState::window_server() const { | 340 const WindowServer* WindowManagerState::window_server() const { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 } else { | 416 } else { |
| 413 OnEventAck(in_flight_event_details_->tree, mojom::EventResult::UNHANDLED); | 417 OnEventAck(in_flight_event_details_->tree, mojom::EventResult::UNHANDLED); |
| 414 } | 418 } |
| 415 } | 419 } |
| 416 | 420 |
| 417 void WindowManagerState::ProcessEventImpl(const ui::Event& event, | 421 void WindowManagerState::ProcessEventImpl(const ui::Event& event, |
| 418 int64_t display_id) { | 422 int64_t display_id) { |
| 419 // Debug accelerators are always checked and don't interfere with processing. | 423 // Debug accelerators are always checked and don't interfere with processing. |
| 420 ProcessDebugAccelerator(event); | 424 ProcessDebugAccelerator(event); |
| 421 event_processing_display_id_ = display_id; | 425 event_processing_display_id_ = display_id; |
| 422 event_dispatcher_.ProcessEvent(event, | 426 event_dispatcher_.ProcessEvent(event, event_processing_display_id_, |
| 423 EventDispatcher::AcceleratorMatchPhase::ANY); | 427 EventDispatcher::AcceleratorMatchPhase::ANY); |
| 424 } | 428 } |
| 425 | 429 |
| 426 void WindowManagerState::QueueEvent( | 430 void WindowManagerState::QueueEvent( |
| 427 const ui::Event& event, | 431 const ui::Event& event, |
| 428 std::unique_ptr<ProcessedEventTarget> processed_event_target, | 432 std::unique_ptr<ProcessedEventTarget> processed_event_target, |
| 429 int64_t display_id) { | 433 int64_t display_id) { |
| 430 std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent); | 434 std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent); |
| 431 queued_event->event = ui::Event::Clone(event); | 435 queued_event->event = ui::Event::Clone(event); |
| 432 queued_event->processed_target = std::move(processed_event_target); | 436 queued_event->processed_target = std::move(processed_event_target); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 533 const base::TimeDelta max_delay = base::debug::BeingDebugged() | 537 const base::TimeDelta max_delay = base::debug::BeingDebugged() |
| 534 ? base::TimeDelta::FromDays(1) | 538 ? base::TimeDelta::FromDays(1) |
| 535 : GetDefaultAckTimerDelay(); | 539 : GetDefaultAckTimerDelay(); |
| 536 details->timer.Start( | 540 details->timer.Start( |
| 537 FROM_HERE, max_delay, | 541 FROM_HERE, max_delay, |
| 538 base::Bind(&WindowManagerState::OnEventAckTimeout, | 542 base::Bind(&WindowManagerState::OnEventAckTimeout, |
| 539 details->weak_factory.GetWeakPtr(), tree->id())); | 543 details->weak_factory.GetWeakPtr(), tree->id())); |
| 540 in_flight_event_details_ = std::move(details); | 544 in_flight_event_details_ = std::move(details); |
| 541 } | 545 } |
| 542 | 546 |
| 547 bool WindowManagerState::ConvertPointToScreen(gfx::Point* point, | |
| 548 const int64_t display_id) { | |
| 549 Display* display = display_manager()->GetDisplayById(display_id); | |
| 550 if (display) { | |
| 551 const display::Display& originated_display = display->GetDisplay(); | |
| 552 *point = gfx::ConvertPointToDIP(originated_display.device_scale_factor(), | |
| 553 *point); | |
| 554 *point += originated_display.bounds().origin().OffsetFromOrigin(); | |
| 555 return true; | |
| 556 } | |
| 557 return false; | |
| 558 } | |
| 559 | |
| 543 //////////////////////////////////////////////////////////////////////////////// | 560 //////////////////////////////////////////////////////////////////////////////// |
| 544 // EventDispatcherDelegate: | 561 // EventDispatcherDelegate: |
| 545 | 562 |
| 546 void WindowManagerState::OnAccelerator(uint32_t accelerator_id, | 563 void WindowManagerState::OnAccelerator(uint32_t accelerator_id, |
| 547 const ui::Event& event, | 564 const ui::Event& event, |
| 548 AcceleratorPhase phase) { | 565 AcceleratorPhase phase) { |
| 549 DCHECK(IsActive()); | 566 DCHECK(IsActive()); |
| 550 const bool needs_ack = phase == AcceleratorPhase::PRE; | 567 const bool needs_ack = phase == AcceleratorPhase::PRE; |
| 551 WindowTree::AcceleratorCallback ack_callback; | 568 WindowTree::AcceleratorCallback ack_callback; |
| 552 if (needs_ack) { | 569 if (needs_ack) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 604 void WindowManagerState::UpdateNativeCursorFromDispatcher() { | 621 void WindowManagerState::UpdateNativeCursorFromDispatcher() { |
| 605 const ui::CursorData cursor = event_dispatcher_.GetCurrentMouseCursor(); | 622 const ui::CursorData cursor = event_dispatcher_.GetCurrentMouseCursor(); |
| 606 cursor_state_.SetCurrentWindowCursor(cursor); | 623 cursor_state_.SetCurrentWindowCursor(cursor); |
| 607 } | 624 } |
| 608 | 625 |
| 609 void WindowManagerState::OnCaptureChanged(ServerWindow* new_capture, | 626 void WindowManagerState::OnCaptureChanged(ServerWindow* new_capture, |
| 610 ServerWindow* old_capture) { | 627 ServerWindow* old_capture) { |
| 611 window_server()->ProcessCaptureChanged(new_capture, old_capture); | 628 window_server()->ProcessCaptureChanged(new_capture, old_capture); |
| 612 } | 629 } |
| 613 | 630 |
| 614 void WindowManagerState::OnMouseCursorLocationChanged(const gfx::Point& point) { | 631 void WindowManagerState::OnMouseCursorLocationChanged( |
| 632 const gfx::Point& point_in_display, | |
| 633 const int64_t display_id) { | |
| 634 gfx::Point point_in_screen(point_in_display); | |
| 635 ConvertPointToScreen(&point_in_screen, display_id); | |
| 615 window_server() | 636 window_server() |
| 616 ->display_manager() | 637 ->display_manager() |
| 617 ->GetCursorLocationManager(user_id()) | 638 ->GetCursorLocationManager(user_id()) |
| 618 ->OnMouseCursorLocationChanged(point); | 639 ->OnMouseCursorLocationChanged(point_in_screen); |
|
sky
2017/05/17 16:53:42
Won't this lead to rounding errors? By that I mean
sky
2017/05/17 19:02:07
Don't worry about the rounding errors for now. We
riajiang
2017/05/19 20:45:05
This won't introduce new rounding error? We were a
sky
2017/05/19 22:12:19
Before we were setting the location to pixels, so
| |
| 619 } | 640 } |
| 620 | 641 |
| 621 void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target, | 642 void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target, |
| 622 ClientSpecificId client_id, | 643 ClientSpecificId client_id, |
| 623 const ui::Event& event, | 644 const ui::Event& event, |
| 624 Accelerator* accelerator) { | 645 Accelerator* accelerator) { |
| 625 DCHECK(IsActive()); | 646 DCHECK(IsActive()); |
| 626 // TODO(sky): this needs to see if another wms has capture and if so forward | 647 // TODO(sky): this needs to see if another wms has capture and if so forward |
| 627 // to it. | 648 // to it. |
| 628 if (in_flight_event_details_) { | 649 if (in_flight_event_details_) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 661 while (tree && tree->embedder_intercepts_events()) { | 682 while (tree && tree->embedder_intercepts_events()) { |
| 662 DCHECK(tree->HasRoot(embed_root)); | 683 DCHECK(tree->HasRoot(embed_root)); |
| 663 tree = window_server()->GetTreeWithId(embed_root->id().client_id); | 684 tree = window_server()->GetTreeWithId(embed_root->id().client_id); |
| 664 embed_root = GetEmbedRoot(embed_root); | 685 embed_root = GetEmbedRoot(embed_root); |
| 665 } | 686 } |
| 666 DCHECK(tree); | 687 DCHECK(tree); |
| 667 return tree->id(); | 688 return tree->id(); |
| 668 } | 689 } |
| 669 | 690 |
| 670 ServerWindow* WindowManagerState::GetRootWindowContaining( | 691 ServerWindow* WindowManagerState::GetRootWindowContaining( |
| 671 gfx::Point* location) { | 692 gfx::Point* location_in_display, |
| 693 int64_t* display_id) { | |
|
sky
2017/05/17 16:53:42
I'm still confused about this. I thought all event
riajiang
2017/05/19 20:45:05
For most events the display id for the |target_dis
sky
2017/05/19 22:12:19
Are you *sure* about this? Again, I believe events
| |
| 672 if (window_manager_display_roots_.empty()) | 694 if (window_manager_display_roots_.empty()) |
| 673 return nullptr; | 695 return nullptr; |
| 674 | 696 |
| 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; | 697 WindowManagerDisplayRoot* target_display_root = nullptr; |
| 678 for (auto& display_root_ptr : window_manager_display_roots_) { | 698 gfx::Point location_in_screen(*location_in_display); |
| 679 if (display_root_ptr->display()->GetDisplay().bounds().Contains( | 699 if (ConvertPointToScreen(&location_in_screen, *display_id)) { |
| 680 *location)) { | 700 for (auto& display_root_ptr : window_manager_display_roots_) { |
| 681 target_display_root = display_root_ptr.get(); | 701 if (display_root_ptr->display()->GetDisplay().bounds().Contains( |
| 682 break; | 702 location_in_screen)) { |
| 703 target_display_root = display_root_ptr.get(); | |
| 704 break; | |
| 705 } | |
| 683 } | 706 } |
| 684 } | 707 } |
| 685 | 708 |
| 686 // TODO(kylechar): Better handle locations outside the window. Overlapping X11 | 709 // TODO(kylechar): Better handle locations outside the window. Overlapping X11 |
| 687 // windows, dragging and touch sensors need to be handled properly. | 710 // windows, dragging and touch sensors need to be handled properly. |
| 688 if (!target_display_root) { | 711 if (!target_display_root) { |
| 689 DVLOG(1) << "Invalid event location " << location->ToString(); | 712 DVLOG(1) << "Invalid event location " << location_in_display->ToString() |
| 713 << " / display id " << *display_id; | |
| 690 target_display_root = window_manager_display_roots_.begin()->get(); | 714 target_display_root = window_manager_display_roots_.begin()->get(); |
| 691 } | 715 } |
| 692 | 716 |
| 693 // Translate the location to be relative to the display instead of relative | 717 // Update |location_in_display| and |display_id| if the target display is |
| 694 // to the screen space. | 718 // different from the originated display, e.g. drag-and-drop. |
| 695 gfx::Point origin = | 719 if (*display_id != target_display_root->display()->GetId()) { |
| 696 target_display_root->display()->GetDisplay().bounds().origin(); | 720 gfx::Point origin = |
| 697 *location -= origin.OffsetFromOrigin(); | 721 target_display_root->display()->GetDisplay().bounds().origin(); |
| 722 *location_in_display = location_in_screen - origin.OffsetFromOrigin(); | |
| 723 *location_in_display = gfx::ConvertPointToPixel( | |
| 724 target_display_root->display()->GetDisplay().device_scale_factor(), | |
| 725 *location_in_display); | |
| 726 *display_id = target_display_root->display()->GetId(); | |
| 727 } | |
| 728 | |
| 698 return target_display_root->GetClientVisibleRoot(); | 729 return target_display_root->GetClientVisibleRoot(); |
| 699 } | 730 } |
| 700 | 731 |
| 701 void WindowManagerState::OnEventTargetNotFound(const ui::Event& event) { | 732 void WindowManagerState::OnEventTargetNotFound(const ui::Event& event) { |
| 702 window_server()->SendToPointerWatchers(event, user_id(), nullptr, /* window */ | 733 window_server()->SendToPointerWatchers(event, user_id(), nullptr, /* window */ |
| 703 nullptr /* ignore_tree */, | 734 nullptr /* ignore_tree */, |
| 704 event_processing_display_id_); | 735 event_processing_display_id_); |
| 705 if (event.IsMousePointerEvent()) | 736 if (event.IsMousePointerEvent()) |
| 706 UpdateNativeCursorFromDispatcher(); | 737 UpdateNativeCursorFromDispatcher(); |
| 707 } | 738 } |
| 708 | 739 |
| 709 void WindowManagerState::OnWindowEmbeddedAppDisconnected(ServerWindow* window) { | 740 void WindowManagerState::OnWindowEmbeddedAppDisconnected(ServerWindow* window) { |
| 710 for (auto iter = orphaned_window_manager_display_roots_.begin(); | 741 for (auto iter = orphaned_window_manager_display_roots_.begin(); |
| 711 iter != orphaned_window_manager_display_roots_.end(); ++iter) { | 742 iter != orphaned_window_manager_display_roots_.end(); ++iter) { |
| 712 if ((*iter)->root() == window) { | 743 if ((*iter)->root() == window) { |
| 713 window->RemoveObserver(this); | 744 window->RemoveObserver(this); |
| 714 orphaned_window_manager_display_roots_.erase(iter); | 745 orphaned_window_manager_display_roots_.erase(iter); |
| 715 return; | 746 return; |
| 716 } | 747 } |
| 717 } | 748 } |
| 718 NOTREACHED(); | 749 NOTREACHED(); |
| 719 } | 750 } |
| 720 | 751 |
| 721 } // namespace ws | 752 } // namespace ws |
| 722 } // namespace ui | 753 } // namespace ui |
| OLD | NEW |