Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(802)

Unified Diff: services/ui/ws/window_manager_state.cc

Issue 2685883003: chromeos: converts observed pointer events to DIPs (Closed)
Patch Set: merge Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « services/ui/ws/window_manager_state.h ('k') | services/ui/ws/window_manager_state_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 d1725e8c549ddf59b5486f060418a3cc00949f7b..76c5684e6110498d51a7509a25e4321dfa7fd6cb 100644
--- a/services/ui/ws/window_manager_state.cc
+++ b/services/ui/ws/window_manager_state.cc
@@ -67,6 +67,18 @@ const ServerWindow* GetEmbedRoot(const ServerWindow* window) {
} // namespace
+WindowManagerState::InFlightEventDetails::InFlightEventDetails(
+ WindowTree* tree,
+ int64_t display_id,
+ const Event& event,
+ EventDispatchPhase phase)
+ : tree(tree),
+ display_id(display_id),
+ event(Event::Clone(event)),
+ phase(phase) {}
+
+WindowManagerState::InFlightEventDetails::~InFlightEventDetails() {}
+
class WindowManagerState::ProcessedEventTarget {
public:
ProcessedEventTarget(ServerWindow* window,
@@ -169,9 +181,10 @@ void WindowManagerState::SetDragDropSourceWindow(
const std::unordered_map<std::string, std::vector<uint8_t>>& drag_data,
uint32_t drag_operation) {
int32_t drag_pointer = PointerEvent::kMousePointerId;
- if (event_awaiting_input_ack_ &&
- event_awaiting_input_ack_->IsPointerEvent()) {
- drag_pointer = event_awaiting_input_ack_->AsPointerEvent()->pointer_id();
+ if (in_flight_event_details_ &&
+ in_flight_event_details_->event->IsPointerEvent()) {
+ drag_pointer =
+ in_flight_event_details_->event->AsPointerEvent()->pointer_id();
} else {
NOTIMPLEMENTED() << "Set drag drop set up during something other than a "
<< "pointer event; rejecting drag.";
@@ -205,15 +218,15 @@ const UserId& WindowManagerState::user_id() const {
void WindowManagerState::OnWillDestroyTree(WindowTree* tree) {
event_dispatcher_.OnWillDestroyDragTargetConnection(tree);
- if (tree_awaiting_input_ack_ != tree)
+ if (!in_flight_event_details_ || in_flight_event_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_| marked as handled so we don't
// notify it of accelerators.
- OnEventAck(tree_awaiting_input_ack_, tree == window_tree_
- ? mojom::EventResult::HANDLED
- : mojom::EventResult::UNHANDLED);
+ OnEventAck(in_flight_event_details_->tree,
+ tree == window_tree_ ? mojom::EventResult::HANDLED
+ : mojom::EventResult::UNHANDLED);
}
ServerWindow* WindowManagerState::GetOrphanedRootWithId(const WindowId& id) {
@@ -243,66 +256,68 @@ void WindowManagerState::Deactivate() {
event_queue.swap(event_queue_);
}
-void WindowManagerState::ProcessEvent(const ui::Event& event) {
+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 (event_ack_timer_.IsRunning()) {
+ if (in_flight_event_details_) {
if (!event_queue_.empty() && !event_queue_.back()->processed_target &&
EventsCanBeCoalesced(*event_queue_.back()->event, event)) {
event_queue_.back()->event = CoalesceEvents(
std::move(event_queue_.back()->event), ui::Event::Clone(event));
+ event_queue_.back()->display_id = display_id;
return;
}
- QueueEvent(event, nullptr);
+ QueueEvent(event, nullptr, display_id);
return;
}
- ProcessEventImpl(event);
+ ProcessEventImpl(event, display_id);
}
void WindowManagerState::OnEventAck(mojom::WindowTree* tree,
mojom::EventResult result) {
- if (tree_awaiting_input_ack_ != tree ||
- event_dispatch_phase_ != EventDispatchPhase::TARGET) {
+ if (!in_flight_event_details_ || in_flight_event_details_->tree != tree ||
+ in_flight_event_details_->phase != EventDispatchPhase::TARGET) {
// TODO(sad): The ack must have arrived after the timeout. We should do
// something here, and in OnEventAckTimeout().
return;
}
- tree_awaiting_input_ack_ = nullptr;
- event_ack_timer_.Stop();
+ std::unique_ptr<InFlightEventDetails> details =
+ std::move(in_flight_event_details_);
base::WeakPtr<Accelerator> post_target_accelerator = post_target_accelerator_;
post_target_accelerator_.reset();
- std::unique_ptr<ui::Event> event = std::move(event_awaiting_input_ack_);
if (result == mojom::EventResult::UNHANDLED && post_target_accelerator) {
- OnAccelerator(post_target_accelerator->id(), *event,
+ OnAccelerator(post_target_accelerator->id(), *details->event,
AcceleratorPhase::POST);
}
- event_dispatch_phase_ = EventDispatchPhase::NONE;
ProcessNextEventFromQueue();
}
void WindowManagerState::OnAcceleratorAck(mojom::EventResult result) {
- if (event_dispatch_phase_ != EventDispatchPhase::PRE_TARGET_ACCELERATOR) {
+ if (!in_flight_event_details_ ||
+ in_flight_event_details_->phase !=
+ EventDispatchPhase::PRE_TARGET_ACCELERATOR) {
// TODO(sad): The ack must have arrived after the timeout. We should do
// something here, and in OnEventAckTimeout().
return;
}
- tree_awaiting_input_ack_ = nullptr;
- event_ack_timer_.Stop();
- event_dispatch_phase_ = EventDispatchPhase::NONE;
- std::unique_ptr<ui::Event> event = std::move(event_awaiting_input_ack_);
+ std::unique_ptr<InFlightEventDetails> details =
+ std::move(in_flight_event_details_);
if (result == mojom::EventResult::UNHANDLED) {
+ event_processing_display_id_ = details->display_id;
event_dispatcher_.ProcessEvent(
- *event, EventDispatcher::AcceleratorMatchPhase::POST_ONLY);
+ *details->event, EventDispatcher::AcceleratorMatchPhase::POST_ONLY);
} else {
// We're not going to process the event any further, notify event observers.
// We don't do this first to ensure we don't send an event twice to clients.
- window_server()->SendToPointerWatchers(*event, user_id(), nullptr, nullptr);
+ window_server()->SendToPointerWatchers(*details->event, user_id(), nullptr,
+ nullptr, details->display_id);
ProcessNextEventFromQueue();
}
}
@@ -363,25 +378,33 @@ 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 (event_dispatch_phase_ == EventDispatchPhase::PRE_TARGET_ACCELERATOR)
+ if (in_flight_event_details_->phase ==
+ EventDispatchPhase::PRE_TARGET_ACCELERATOR) {
OnAcceleratorAck(mojom::EventResult::UNHANDLED);
- else
- OnEventAck(tree_awaiting_input_ack_, mojom::EventResult::UNHANDLED);
+ } else {
+ OnEventAck(
+ in_flight_event_details_ ? in_flight_event_details_->tree : nullptr,
+ mojom::EventResult::UNHANDLED);
+ }
}
-void WindowManagerState::ProcessEventImpl(const ui::Event& event) {
+void WindowManagerState::ProcessEventImpl(const ui::Event& event,
+ int64_t display_id) {
// Debug accelerators are always checked and don't interfere with processing.
ProcessDebugAccelerator(event);
+ event_processing_display_id_ = display_id;
event_dispatcher_.ProcessEvent(event,
EventDispatcher::AcceleratorMatchPhase::ANY);
}
void WindowManagerState::QueueEvent(
const ui::Event& event,
- std::unique_ptr<ProcessedEventTarget> processed_event_target) {
+ std::unique_ptr<ProcessedEventTarget> processed_event_target,
+ int64_t display_id) {
std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent);
queued_event->event = ui::Event::Clone(event);
queued_event->processed_target = std::move(processed_event_target);
+ queued_event->display_id = display_id;
event_queue_.push(std::move(queued_event));
}
@@ -392,7 +415,7 @@ void WindowManagerState::ProcessNextEventFromQueue() {
std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front());
event_queue_.pop();
if (!queued_event->processed_target) {
- ProcessEventImpl(*queued_event->event);
+ ProcessEventImpl(*queued_event->event, queued_event->display_id);
return;
}
if (queued_event->processed_target->IsValid()) {
@@ -410,7 +433,8 @@ void WindowManagerState::DispatchInputEventToWindowImpl(
ClientSpecificId client_id,
const ui::Event& event,
base::WeakPtr<Accelerator> accelerator) {
- if (target && target->parent() == nullptr)
+ DCHECK(target);
+ if (target->parent() == nullptr)
target = GetWindowManagerRoot(target);
if (event.IsMousePointerEvent()) {
@@ -418,19 +442,16 @@ void WindowManagerState::DispatchInputEventToWindowImpl(
UpdateNativeCursorFromDispatcher();
}
- event_dispatch_phase_ = EventDispatchPhase::TARGET;
-
WindowTree* tree = window_server()->GetTreeWithId(client_id);
DCHECK(tree);
- ScheduleInputEventTimeout(tree);
-
- event_awaiting_input_ack_ = ui::Event::Clone(event);
+ ScheduleInputEventTimeout(tree, target, event, EventDispatchPhase::TARGET);
if (accelerator)
post_target_accelerator_ = accelerator;
// Ignore |tree| because it will receive the event via normal dispatch.
- window_server()->SendToPointerWatchers(event, user_id(), target, tree);
+ window_server()->SendToPointerWatchers(event, user_id(), target, tree,
+ in_flight_event_details_->display_id);
tree->DispatchInputEvent(target, event);
}
@@ -469,16 +490,22 @@ void WindowManagerState::HandleDebugAccelerator(DebugAcceleratorType type) {
#endif
}
-void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree) {
+void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree,
+ ServerWindow* target,
+ const Event& event,
+ EventDispatchPhase phase) {
+ std::unique_ptr<InFlightEventDetails> details =
+ base::MakeUnique<InFlightEventDetails>(tree, event_processing_display_id_,
+ event, phase);
+
// TOOD(sad): Adjust this delay, possibly make this dynamic.
const base::TimeDelta max_delay = base::debug::BeingDebugged()
? base::TimeDelta::FromDays(1)
: GetDefaultAckTimerDelay();
- event_ack_timer_.Start(FROM_HERE, max_delay,
- base::Bind(&WindowManagerState::OnEventAckTimeout,
- weak_factory_.GetWeakPtr(), tree->id()));
-
- tree_awaiting_input_ack_ = tree;
+ details->timer.Start(FROM_HERE, max_delay,
+ base::Bind(&WindowManagerState::OnEventAckTimeout,
+ weak_factory_.GetWeakPtr(), tree->id()));
+ in_flight_event_details_ = std::move(details);
}
////////////////////////////////////////////////////////////////////////////////
@@ -490,10 +517,9 @@ void WindowManagerState::OnAccelerator(uint32_t accelerator_id,
DCHECK(IsActive());
const bool needs_ack = phase == AcceleratorPhase::PRE;
if (needs_ack) {
- DCHECK_EQ(EventDispatchPhase::NONE, event_dispatch_phase_);
- event_dispatch_phase_ = EventDispatchPhase::PRE_TARGET_ACCELERATOR;
- event_awaiting_input_ack_ = ui::Event::Clone(event);
- ScheduleInputEventTimeout(window_tree_);
+ DCHECK(!in_flight_event_details_);
+ ScheduleInputEventTimeout(window_tree_, nullptr, event,
+ EventDispatchPhase::PRE_TARGET_ACCELERATOR);
}
window_tree_->OnAccelerator(accelerator_id, event, needs_ack);
}
@@ -553,10 +579,11 @@ void WindowManagerState::DispatchInputEventToWindow(ServerWindow* target,
DCHECK(IsActive());
// TODO(sky): this needs to see if another wms has capture and if so forward
// to it.
- if (event_ack_timer_.IsRunning()) {
+ if (in_flight_event_details_) {
std::unique_ptr<ProcessedEventTarget> processed_event_target(
new ProcessedEventTarget(target, client_id, accelerator));
- QueueEvent(event, std::move(processed_event_target));
+ QueueEvent(event, std::move(processed_event_target),
+ event_processing_display_id_);
return;
}
@@ -625,7 +652,8 @@ ServerWindow* WindowManagerState::GetRootWindowContaining(
void WindowManagerState::OnEventTargetNotFound(const ui::Event& event) {
window_server()->SendToPointerWatchers(event, user_id(), nullptr, /* window */
- nullptr /* ignore_tree */);
+ nullptr /* ignore_tree */,
+ event_processing_display_id_);
if (event.IsMousePointerEvent())
UpdateNativeCursorFromDispatcher();
}
« no previous file with comments | « services/ui/ws/window_manager_state.h ('k') | services/ui/ws/window_manager_state_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698