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

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

Issue 2884463002: Make event-targeting asynchronous in window server. (Closed)
Patch Set: comments Created 3 years, 6 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 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())
« 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