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()) |