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

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

Issue 2125883003: Adds ability for pre-target accelerators to not consume events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: merge Created 4 years, 5 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 e70ec273f45bd0b83ed66b38ea2b59155672ffdf..4f4d2eeee12330265cfb8169edd7f5c00a0d6dc0 100644
--- a/services/ui/ws/window_manager_state.cc
+++ b/services/ui/ws/window_manager_state.cc
@@ -199,12 +199,15 @@ void WindowManagerState::ProcessEvent(const ui::Event& event) {
QueueEvent(event, nullptr);
return;
}
- event_dispatcher_.ProcessEvent(event);
+
+ event_dispatcher_.ProcessEvent(event,
+ EventDispatcher::AcceleratorMatchPhase::ANY);
}
void WindowManagerState::OnEventAck(mojom::WindowTree* tree,
mojom::EventResult result) {
- if (tree_awaiting_input_ack_ != tree) {
+ if (tree_awaiting_input_ack_ != tree ||
+ event_dispatch_phase_ != EventDispatchPhase::TARGET) {
// TODO(sad): The ack must have arrived after the timeout. We should do
// something here, and in OnEventAckTimeout().
return;
@@ -212,12 +215,39 @@ void WindowManagerState::OnEventAck(mojom::WindowTree* tree,
tree_awaiting_input_ack_ = nullptr;
event_ack_timer_.Stop();
- if (result == mojom::EventResult::UNHANDLED && post_target_accelerator_)
- OnAccelerator(post_target_accelerator_->id(), *event_awaiting_input_ack_);
+ if (result == mojom::EventResult::UNHANDLED && post_target_accelerator_) {
+ OnAccelerator(post_target_accelerator_->id(), *event_awaiting_input_ack_,
+ AcceleratorPhase::POST);
+ }
+ event_dispatch_phase_ = EventDispatchPhase::NONE;
ProcessNextEventFromQueue();
}
+void WindowManagerState::OnAcceleratorAck(mojom::EventResult result) {
+ if (event_dispatch_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;
+
+ if (result == mojom::EventResult::UNHANDLED) {
+ event_dispatcher_.ProcessEvent(
+ *event_awaiting_input_ack_,
+ 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()->SendToEventObservers(*event_awaiting_input_ack_, user_id(),
+ nullptr);
+ ProcessNextEventFromQueue();
+ }
+}
+
const WindowServer* WindowManagerState::window_server() const {
return window_tree_->window_server();
}
@@ -258,7 +288,10 @@ 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);
- OnEventAck(tree_awaiting_input_ack_, mojom::EventResult::UNHANDLED);
+ if (event_dispatch_phase_ == EventDispatchPhase::PRE_TARGET_ACCELERATOR)
+ OnAcceleratorAck(mojom::EventResult::UNHANDLED);
+ else
+ OnEventAck(tree_awaiting_input_ack_, mojom::EventResult::UNHANDLED);
}
void WindowManagerState::QueueEvent(
@@ -277,7 +310,8 @@ void WindowManagerState::ProcessNextEventFromQueue() {
std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front());
event_queue_.pop();
if (!queued_event->processed_target) {
- event_dispatcher_.ProcessEvent(*queued_event->event);
+ event_dispatcher_.ProcessEvent(
+ *queued_event->event, EventDispatcher::AcceleratorMatchPhase::ANY);
return;
}
if (queued_event->processed_target->IsValid()) {
@@ -309,18 +343,12 @@ void WindowManagerState::DispatchInputEventToWindowImpl(
}
}
+ event_dispatch_phase_ = EventDispatchPhase::TARGET;
+
WindowTree* tree = window_server()->GetTreeWithId(client_id);
- // 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()));
+ ScheduleInputEventTimeout(tree);
- tree_awaiting_input_ack_ = tree;
if (accelerator) {
event_awaiting_input_ack_ = ui::Event::Clone(event);
post_target_accelerator_ = accelerator;
@@ -361,15 +389,35 @@ bool WindowManagerState::HandleDebugAccelerator(uint32_t accelerator_id) {
return false;
}
+void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree) {
+ // 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;
+}
+
////////////////////////////////////////////////////////////////////////////////
// EventDispatcherDelegate:
void WindowManagerState::OnAccelerator(uint32_t accelerator_id,
- const ui::Event& event) {
+ const ui::Event& event,
+ AcceleratorPhase phase) {
DCHECK(IsActive());
if (HandleDebugAccelerator(accelerator_id))
return;
- window_tree_->OnAccelerator(accelerator_id, event);
+ 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_);
+ }
+ window_tree_->OnAccelerator(accelerator_id, event, needs_ack);
}
void WindowManagerState::SetFocusedWindowFromEventDispatcher(
« 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