| Index: services/ui/ws/window_manager_state.cc
|
| diff --git a/services/ui/ws/window_manager_state.cc b/services/ui/ws/window_manager_state.cc
|
| index eec946760385723df96e39512c1fac962a836dd7..df511740145d3d734dbad4c6fcf955b2b464f16e 100644
|
| --- a/services/ui/ws/window_manager_state.cc
|
| +++ b/services/ui/ws/window_manager_state.cc
|
| @@ -15,6 +15,7 @@
|
| #include "services/ui/ws/display.h"
|
| #include "services/ui/ws/display_creation_config.h"
|
| #include "services/ui/ws/display_manager.h"
|
| +#include "services/ui/ws/event_targeter.h"
|
| #include "services/ui/ws/platform_display.h"
|
| #include "services/ui/ws/server_window.h"
|
| #include "services/ui/ws/user_display_manager.h"
|
| @@ -74,7 +75,7 @@ const ServerWindow* GetEmbedRoot(const ServerWindow* window) {
|
|
|
| } // namespace
|
|
|
| -WindowManagerState::InFlightEventDetails::InFlightEventDetails(
|
| +WindowManagerState::InFlightEventDispatchDetails::InFlightEventDispatchDetails(
|
| WindowManagerState* window_manager_state,
|
| WindowTree* tree,
|
| int64_t display_id,
|
| @@ -86,7 +87,8 @@ WindowManagerState::InFlightEventDetails::InFlightEventDetails(
|
| phase(phase),
|
| weak_factory(window_manager_state) {}
|
|
|
| -WindowManagerState::InFlightEventDetails::~InFlightEventDetails() {}
|
| +WindowManagerState::InFlightEventDispatchDetails::
|
| + ~InFlightEventDispatchDetails() {}
|
|
|
| class WindowManagerState::ProcessedEventTarget {
|
| public:
|
| @@ -213,10 +215,11 @@ void WindowManagerState::SetDragDropSourceWindow(
|
| const std::unordered_map<std::string, std::vector<uint8_t>>& drag_data,
|
| uint32_t drag_operation) {
|
| int32_t drag_pointer = MouseEvent::kMousePointerId;
|
| - if (in_flight_event_details_ &&
|
| - in_flight_event_details_->event->IsPointerEvent()) {
|
| - drag_pointer =
|
| - in_flight_event_details_->event->AsPointerEvent()->pointer_details().id;
|
| + if (in_flight_event_dispatch_details_ &&
|
| + in_flight_event_dispatch_details_->event->IsPointerEvent()) {
|
| + drag_pointer = in_flight_event_dispatch_details_->event->AsPointerEvent()
|
| + ->pointer_details()
|
| + .id;
|
| } else {
|
| NOTIMPLEMENTED() << "Set drag drop set up during something other than a "
|
| << "pointer event; rejecting drag.";
|
| @@ -271,13 +274,14 @@ const UserId& WindowManagerState::user_id() const {
|
| void WindowManagerState::OnWillDestroyTree(WindowTree* tree) {
|
| event_dispatcher_.OnWillDestroyDragTargetConnection(tree);
|
|
|
| - if (!in_flight_event_details_ || in_flight_event_details_->tree != tree)
|
| + if (!in_flight_event_dispatch_details_ ||
|
| + in_flight_event_dispatch_details_->tree != tree)
|
| return;
|
|
|
| // The WindowTree is dying. So it's not going to ack the event.
|
| // If the dying tree matches the root |tree_| mark as handled so we don't
|
| // notify it of accelerators.
|
| - OnEventAck(in_flight_event_details_->tree,
|
| + OnEventAck(in_flight_event_dispatch_details_->tree,
|
| tree == window_tree_ ? mojom::EventResult::HANDLED
|
| : mojom::EventResult::UNHANDLED);
|
| }
|
| @@ -295,7 +299,7 @@ bool WindowManagerState::IsActive() const {
|
| }
|
|
|
| void WindowManagerState::Activate(const gfx::Point& mouse_location_on_display,
|
| - const int64_t display_id) {
|
| + int64_t display_id) {
|
| SetAllRootWindowsVisible(true);
|
| event_dispatcher_.Reset();
|
| event_dispatcher_.SetMousePointerDisplayLocation(mouse_location_on_display,
|
| @@ -315,7 +319,8 @@ void WindowManagerState::ProcessEvent(const ui::Event& event,
|
| int64_t display_id) {
|
| // If this is still waiting for an ack from a previously sent event, then
|
| // queue up the event to be dispatched once the ack is received.
|
| - if (in_flight_event_details_) {
|
| + if (event_dispatcher_.IsProcessingEvent() ||
|
| + in_flight_event_dispatch_details_) {
|
| if (!event_queue_.empty() && !event_queue_.back()->processed_target &&
|
| EventsCanBeCoalesced(*event_queue_.back()->event, event)) {
|
| event_queue_.back()->event = CoalesceEvents(
|
| @@ -333,12 +338,12 @@ void WindowManagerState::ProcessEvent(const ui::Event& event,
|
| void WindowManagerState::OnAcceleratorAck(
|
| mojom::EventResult result,
|
| const std::unordered_map<std::string, std::vector<uint8_t>>& properties) {
|
| - DCHECK(in_flight_event_details_);
|
| + DCHECK(in_flight_event_dispatch_details_);
|
| DCHECK_EQ(EventDispatchPhase::PRE_TARGET_ACCELERATOR,
|
| - in_flight_event_details_->phase);
|
| + in_flight_event_dispatch_details_->phase);
|
|
|
| - std::unique_ptr<InFlightEventDetails> details =
|
| - std::move(in_flight_event_details_);
|
| + std::unique_ptr<InFlightEventDispatchDetails> details =
|
| + std::move(in_flight_event_dispatch_details_);
|
|
|
| if (result == mojom::EventResult::UNHANDLED) {
|
| DCHECK(details->event->IsKeyEvent());
|
| @@ -352,7 +357,7 @@ void WindowManagerState::OnAcceleratorAck(
|
| // We don't do this first to ensure we don't send an event twice to clients.
|
| window_server()->SendToPointerWatchers(*details->event, user_id(), nullptr,
|
| nullptr, details->display_id);
|
| - ProcessNextEventFromQueue();
|
| + ProcessNextAvailableEvent();
|
| }
|
| }
|
|
|
| @@ -412,9 +417,9 @@ ServerWindow* WindowManagerState::GetWindowManagerRootForDisplayRoot(
|
|
|
| void WindowManagerState::OnEventAck(mojom::WindowTree* tree,
|
| mojom::EventResult result) {
|
| - DCHECK(in_flight_event_details_);
|
| - std::unique_ptr<InFlightEventDetails> details =
|
| - std::move(in_flight_event_details_);
|
| + DCHECK(in_flight_event_dispatch_details_);
|
| + std::unique_ptr<InFlightEventDispatchDetails> details =
|
| + std::move(in_flight_event_dispatch_details_);
|
|
|
| if (result == mojom::EventResult::UNHANDLED &&
|
| details->post_target_accelerator) {
|
| @@ -422,23 +427,26 @@ void WindowManagerState::OnEventAck(mojom::WindowTree* tree,
|
| *details->event, AcceleratorPhase::POST);
|
| }
|
|
|
| - ProcessNextEventFromQueue();
|
| + ProcessNextAvailableEvent();
|
| }
|
|
|
| void WindowManagerState::OnEventAckTimeout(ClientSpecificId client_id) {
|
| WindowTree* hung_tree = window_server()->GetTreeWithId(client_id);
|
| if (hung_tree && !hung_tree->janky())
|
| window_tree_->ClientJankinessChanged(hung_tree);
|
| - if (in_flight_event_details_->phase ==
|
| + if (in_flight_event_dispatch_details_->phase ==
|
| EventDispatchPhase::PRE_TARGET_ACCELERATOR) {
|
| OnAcceleratorAck(mojom::EventResult::UNHANDLED, KeyEvent::Properties());
|
| } else {
|
| - OnEventAck(in_flight_event_details_->tree, mojom::EventResult::UNHANDLED);
|
| + OnEventAck(in_flight_event_dispatch_details_->tree,
|
| + mojom::EventResult::UNHANDLED);
|
| }
|
| }
|
|
|
| void WindowManagerState::ProcessEventImpl(const ui::Event& event,
|
| int64_t display_id) {
|
| + DCHECK(!in_flight_event_dispatch_details_ &&
|
| + !event_dispatcher_.IsProcessingEvent());
|
| // Debug accelerators are always checked and don't interfere with processing.
|
| ProcessDebugAccelerator(event, display_id);
|
| event_dispatcher_.ProcessEvent(event, display_id,
|
| @@ -456,32 +464,15 @@ void WindowManagerState::QueueEvent(
|
| event_queue_.push(std::move(queued_event));
|
| }
|
|
|
| -void WindowManagerState::ProcessNextEventFromQueue() {
|
| - // Loop through |event_queue_| stopping after dispatching the first valid
|
| - // event.
|
| - while (!event_queue_.empty()) {
|
| - std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front());
|
| - event_queue_.pop();
|
| - if (!queued_event->processed_target) {
|
| - ProcessEventImpl(*queued_event->event, queued_event->display_id);
|
| - return;
|
| - }
|
| - if (queued_event->processed_target->IsValid()) {
|
| - DispatchInputEventToWindowImpl(
|
| - queued_event->processed_target->window(),
|
| - queued_event->processed_target->client_id(), queued_event->display_id,
|
| - *queued_event->event, queued_event->processed_target->accelerator());
|
| - return;
|
| - }
|
| - }
|
| -}
|
| -
|
| +// TODO(riajiang): We might want to do event targeting for the next event while
|
| +// waiting for the current event to be dispatched. crbug.com/724521
|
| void WindowManagerState::DispatchInputEventToWindowImpl(
|
| ServerWindow* target,
|
| ClientSpecificId client_id,
|
| - const int64_t display_id,
|
| + int64_t display_id,
|
| const ui::Event& event,
|
| base::WeakPtr<Accelerator> accelerator) {
|
| + DCHECK(!in_flight_event_dispatch_details_);
|
| DCHECK(target);
|
| if (target->parent() == nullptr)
|
| target = GetWindowManagerRootForDisplayRoot(target);
|
| @@ -495,17 +486,18 @@ void WindowManagerState::DispatchInputEventToWindowImpl(
|
| DCHECK(tree);
|
| ScheduleInputEventTimeout(tree, target, display_id, event,
|
| EventDispatchPhase::TARGET);
|
| - in_flight_event_details_->post_target_accelerator = accelerator;
|
| + in_flight_event_dispatch_details_->post_target_accelerator = accelerator;
|
|
|
| // Ignore |tree| because it will receive the event via normal dispatch.
|
| - window_server()->SendToPointerWatchers(event, user_id(), target, tree,
|
| - in_flight_event_details_->display_id);
|
| + window_server()->SendToPointerWatchers(
|
| + event, user_id(), target, tree,
|
| + in_flight_event_dispatch_details_->display_id);
|
|
|
| tree->DispatchInputEvent(
|
| target, event,
|
| - base::BindOnce(&WindowManagerState::OnEventAck,
|
| - in_flight_event_details_->weak_factory.GetWeakPtr(),
|
| - tree));
|
| + base::BindOnce(
|
| + &WindowManagerState::OnEventAck,
|
| + in_flight_event_dispatch_details_->weak_factory.GetWeakPtr(), tree));
|
| }
|
|
|
| void WindowManagerState::AddDebugAccelerators() {
|
| @@ -516,7 +508,7 @@ void WindowManagerState::AddDebugAccelerators() {
|
| }
|
|
|
| void WindowManagerState::ProcessDebugAccelerator(const ui::Event& event,
|
| - const int64_t display_id) {
|
| + int64_t display_id) {
|
| if (event.type() != ui::ET_KEY_PRESSED)
|
| return;
|
|
|
| @@ -530,7 +522,7 @@ void WindowManagerState::ProcessDebugAccelerator(const ui::Event& event,
|
| }
|
|
|
| void WindowManagerState::HandleDebugAccelerator(DebugAcceleratorType type,
|
| - const int64_t display_id) {
|
| + int64_t display_id) {
|
| #if DCHECK_IS_ON()
|
| // Error so it will be collected in system logs.
|
| for (Display* display : display_manager()->displays()) {
|
| @@ -549,12 +541,12 @@ void WindowManagerState::HandleDebugAccelerator(DebugAcceleratorType type,
|
|
|
| void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree,
|
| ServerWindow* target,
|
| - const int64_t display_id,
|
| + int64_t display_id,
|
| const Event& event,
|
| EventDispatchPhase phase) {
|
| - std::unique_ptr<InFlightEventDetails> details =
|
| - base::MakeUnique<InFlightEventDetails>(this, tree, display_id, event,
|
| - phase);
|
| + std::unique_ptr<InFlightEventDispatchDetails> details =
|
| + base::MakeUnique<InFlightEventDispatchDetails>(this, tree, display_id,
|
| + event, phase);
|
|
|
| // TOOD(sad): Adjust this delay, possibly make this dynamic.
|
| const base::TimeDelta max_delay = base::debug::BeingDebugged()
|
| @@ -564,10 +556,10 @@ void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree,
|
| FROM_HERE, max_delay,
|
| base::Bind(&WindowManagerState::OnEventAckTimeout,
|
| details->weak_factory.GetWeakPtr(), tree->id()));
|
| - in_flight_event_details_ = std::move(details);
|
| + in_flight_event_dispatch_details_ = std::move(details);
|
| }
|
|
|
| -bool WindowManagerState::ConvertPointToScreen(const int64_t display_id,
|
| +bool WindowManagerState::ConvertPointToScreen(int64_t display_id,
|
| gfx::Point* point) {
|
| Display* display = display_manager()->GetDisplayById(display_id);
|
| if (display) {
|
| @@ -584,19 +576,19 @@ bool WindowManagerState::ConvertPointToScreen(const int64_t display_id,
|
| // EventDispatcherDelegate:
|
|
|
| void WindowManagerState::OnAccelerator(uint32_t accelerator_id,
|
| - const int64_t display_id,
|
| + int64_t display_id,
|
| const ui::Event& event,
|
| AcceleratorPhase phase) {
|
| DCHECK(IsActive());
|
| const bool needs_ack = phase == AcceleratorPhase::PRE;
|
| WindowTree::AcceleratorCallback ack_callback;
|
| if (needs_ack) {
|
| - DCHECK(!in_flight_event_details_);
|
| + DCHECK(!in_flight_event_dispatch_details_);
|
| ScheduleInputEventTimeout(window_tree_, nullptr, display_id, event,
|
| EventDispatchPhase::PRE_TARGET_ACCELERATOR);
|
| - ack_callback =
|
| - base::BindOnce(&WindowManagerState::OnAcceleratorAck,
|
| - in_flight_event_details_->weak_factory.GetWeakPtr());
|
| + ack_callback = base::BindOnce(
|
| + &WindowManagerState::OnAcceleratorAck,
|
| + in_flight_event_dispatch_details_->weak_factory.GetWeakPtr());
|
| }
|
| window_tree_->OnAccelerator(accelerator_id, event, std::move(ack_callback));
|
| }
|
| @@ -608,7 +600,7 @@ void WindowManagerState::SetFocusedWindowFromEventDispatcher(
|
| }
|
|
|
| ServerWindow* WindowManagerState::GetFocusedWindowForEventDispatcher(
|
| - const int64_t display_id) {
|
| + int64_t display_id) {
|
| ServerWindow* focused_window = window_server()->GetFocusedWindow();
|
| if (focused_window)
|
| return focused_window;
|
| @@ -655,7 +647,7 @@ void WindowManagerState::OnCaptureChanged(ServerWindow* new_capture,
|
|
|
| void WindowManagerState::OnMouseCursorLocationChanged(
|
| const gfx::Point& point_in_display,
|
| - const int64_t display_id) {
|
| + int64_t display_id) {
|
| gfx::Point point_in_screen(point_in_display);
|
| if (ConvertPointToScreen(display_id, &point_in_screen)) {
|
| window_server()
|
| @@ -669,13 +661,13 @@ void WindowManagerState::OnMouseCursorLocationChanged(
|
|
|
| void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target,
|
| ClientSpecificId client_id,
|
| - const int64_t display_id,
|
| + int64_t display_id,
|
| const ui::Event& event,
|
| Accelerator* accelerator) {
|
| DCHECK(IsActive());
|
| // TODO(sky): this needs to see if another wms has capture and if so forward
|
| // to it.
|
| - if (in_flight_event_details_) {
|
| + if (in_flight_event_dispatch_details_) {
|
| std::unique_ptr<ProcessedEventTarget> processed_event_target(
|
| new ProcessedEventTarget(target, client_id, accelerator));
|
| QueueEvent(event, std::move(processed_event_target), display_id);
|
| @@ -689,6 +681,33 @@ void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target,
|
| weak_accelerator);
|
| }
|
|
|
| +void WindowManagerState::ProcessNextAvailableEvent() {
|
| + // Loop through |event_queue_| stopping after dispatching the first valid
|
| + // event.
|
| + while (!event_queue_.empty()) {
|
| + if (in_flight_event_dispatch_details_)
|
| + return;
|
| +
|
| + if (!event_queue_.front()->processed_target &&
|
| + event_dispatcher_.IsProcessingEvent())
|
| + return;
|
| +
|
| + std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front());
|
| + event_queue_.pop();
|
| + if (!queued_event->processed_target) {
|
| + ProcessEventImpl(*queued_event->event, queued_event->display_id);
|
| + return;
|
| + }
|
| + if (queued_event->processed_target->IsValid()) {
|
| + DispatchInputEventToWindowImpl(
|
| + queued_event->processed_target->window(),
|
| + queued_event->processed_target->client_id(), queued_event->display_id,
|
| + *queued_event->event, queued_event->processed_target->accelerator());
|
| + return;
|
| + }
|
| + }
|
| +}
|
| +
|
| ClientSpecificId WindowManagerState::GetEventTargetClientId(
|
| const ServerWindow* window,
|
| bool in_nonclient_area) {
|
| @@ -760,7 +779,7 @@ ServerWindow* WindowManagerState::GetRootWindowContaining(
|
| }
|
|
|
| void WindowManagerState::OnEventTargetNotFound(const ui::Event& event,
|
| - const int64_t display_id) {
|
| + int64_t display_id) {
|
| window_server()->SendToPointerWatchers(event, user_id(), nullptr, /* window */
|
| nullptr /* ignore_tree */, display_id);
|
| if (event.IsMousePointerEvent())
|
|
|