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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "services/ui/ws/window_manager_state.h" 5 #include "services/ui/ws/window_manager_state.h"
6 6
7 #include "base/memory/weak_ptr.h" 7 #include "base/memory/weak_ptr.h"
8 #include "services/shell/public/interfaces/connector.mojom.h" 8 #include "services/shell/public/interfaces/connector.mojom.h"
9 #include "services/ui/common/event_matcher_util.h" 9 #include "services/ui/common/event_matcher_util.h"
10 #include "services/ui/ws/accelerator.h" 10 #include "services/ui/ws/accelerator.h"
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 if (event_ack_timer_.IsRunning()) { 192 if (event_ack_timer_.IsRunning()) {
193 if (!event_queue_.empty() && !event_queue_.back()->processed_target && 193 if (!event_queue_.empty() && !event_queue_.back()->processed_target &&
194 EventsCanBeCoalesced(*event_queue_.back()->event, event)) { 194 EventsCanBeCoalesced(*event_queue_.back()->event, event)) {
195 event_queue_.back()->event = CoalesceEvents( 195 event_queue_.back()->event = CoalesceEvents(
196 std::move(event_queue_.back()->event), ui::Event::Clone(event)); 196 std::move(event_queue_.back()->event), ui::Event::Clone(event));
197 return; 197 return;
198 } 198 }
199 QueueEvent(event, nullptr); 199 QueueEvent(event, nullptr);
200 return; 200 return;
201 } 201 }
202 event_dispatcher_.ProcessEvent(event); 202
203 event_dispatcher_.ProcessEvent(event,
204 EventDispatcher::AcceleratorMatchPhase::ANY);
203 } 205 }
204 206
205 void WindowManagerState::OnEventAck(mojom::WindowTree* tree, 207 void WindowManagerState::OnEventAck(mojom::WindowTree* tree,
206 mojom::EventResult result) { 208 mojom::EventResult result) {
207 if (tree_awaiting_input_ack_ != tree) { 209 if (tree_awaiting_input_ack_ != tree ||
210 event_dispatch_phase_ != EventDispatchPhase::TARGET) {
208 // TODO(sad): The ack must have arrived after the timeout. We should do 211 // TODO(sad): The ack must have arrived after the timeout. We should do
209 // something here, and in OnEventAckTimeout(). 212 // something here, and in OnEventAckTimeout().
210 return; 213 return;
211 } 214 }
212 tree_awaiting_input_ack_ = nullptr; 215 tree_awaiting_input_ack_ = nullptr;
213 event_ack_timer_.Stop(); 216 event_ack_timer_.Stop();
214 217
215 if (result == mojom::EventResult::UNHANDLED && post_target_accelerator_) 218 if (result == mojom::EventResult::UNHANDLED && post_target_accelerator_) {
216 OnAccelerator(post_target_accelerator_->id(), *event_awaiting_input_ack_); 219 OnAccelerator(post_target_accelerator_->id(), *event_awaiting_input_ack_,
220 AcceleratorPhase::POST);
221 }
217 222
223 event_dispatch_phase_ = EventDispatchPhase::NONE;
218 ProcessNextEventFromQueue(); 224 ProcessNextEventFromQueue();
219 } 225 }
220 226
227 void WindowManagerState::OnAcceleratorAck(mojom::EventResult result) {
228 if (event_dispatch_phase_ != EventDispatchPhase::PRE_TARGET_ACCELERATOR) {
229 // TODO(sad): The ack must have arrived after the timeout. We should do
230 // something here, and in OnEventAckTimeout().
231 return;
232 }
233
234 tree_awaiting_input_ack_ = nullptr;
235 event_ack_timer_.Stop();
236 event_dispatch_phase_ = EventDispatchPhase::NONE;
237
238 if (result == mojom::EventResult::UNHANDLED) {
239 event_dispatcher_.ProcessEvent(
240 *event_awaiting_input_ack_,
241 EventDispatcher::AcceleratorMatchPhase::POST_ONLY);
242 } else {
243 // We're not going to process the event any further, notify event observers.
244 // We don't do this first to ensure we don't send an event twice to clients.
245 window_server()->SendToEventObservers(*event_awaiting_input_ack_, user_id(),
246 nullptr);
247 ProcessNextEventFromQueue();
248 }
249 }
250
221 const WindowServer* WindowManagerState::window_server() const { 251 const WindowServer* WindowManagerState::window_server() const {
222 return window_tree_->window_server(); 252 return window_tree_->window_server();
223 } 253 }
224 254
225 WindowServer* WindowManagerState::window_server() { 255 WindowServer* WindowManagerState::window_server() {
226 return window_tree_->window_server(); 256 return window_tree_->window_server();
227 } 257 }
228 258
229 DisplayManager* WindowManagerState::display_manager() { 259 DisplayManager* WindowManagerState::display_manager() {
230 return window_tree_->display_manager(); 260 return window_tree_->display_manager();
(...skipping 20 matching lines...) Expand all
251 return display_root->root(); 281 return display_root->root();
252 } 282 }
253 NOTREACHED(); 283 NOTREACHED();
254 return nullptr; 284 return nullptr;
255 } 285 }
256 286
257 void WindowManagerState::OnEventAckTimeout(ClientSpecificId client_id) { 287 void WindowManagerState::OnEventAckTimeout(ClientSpecificId client_id) {
258 WindowTree* hung_tree = window_server()->GetTreeWithId(client_id); 288 WindowTree* hung_tree = window_server()->GetTreeWithId(client_id);
259 if (hung_tree && !hung_tree->janky()) 289 if (hung_tree && !hung_tree->janky())
260 window_tree_->ClientJankinessChanged(hung_tree); 290 window_tree_->ClientJankinessChanged(hung_tree);
261 OnEventAck(tree_awaiting_input_ack_, mojom::EventResult::UNHANDLED); 291 if (event_dispatch_phase_ == EventDispatchPhase::PRE_TARGET_ACCELERATOR)
292 OnAcceleratorAck(mojom::EventResult::UNHANDLED);
293 else
294 OnEventAck(tree_awaiting_input_ack_, mojom::EventResult::UNHANDLED);
262 } 295 }
263 296
264 void WindowManagerState::QueueEvent( 297 void WindowManagerState::QueueEvent(
265 const ui::Event& event, 298 const ui::Event& event,
266 std::unique_ptr<ProcessedEventTarget> processed_event_target) { 299 std::unique_ptr<ProcessedEventTarget> processed_event_target) {
267 std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent); 300 std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent);
268 queued_event->event = ui::Event::Clone(event); 301 queued_event->event = ui::Event::Clone(event);
269 queued_event->processed_target = std::move(processed_event_target); 302 queued_event->processed_target = std::move(processed_event_target);
270 event_queue_.push(std::move(queued_event)); 303 event_queue_.push(std::move(queued_event));
271 } 304 }
272 305
273 void WindowManagerState::ProcessNextEventFromQueue() { 306 void WindowManagerState::ProcessNextEventFromQueue() {
274 // Loop through |event_queue_| stopping after dispatching the first valid 307 // Loop through |event_queue_| stopping after dispatching the first valid
275 // event. 308 // event.
276 while (!event_queue_.empty()) { 309 while (!event_queue_.empty()) {
277 std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front()); 310 std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front());
278 event_queue_.pop(); 311 event_queue_.pop();
279 if (!queued_event->processed_target) { 312 if (!queued_event->processed_target) {
280 event_dispatcher_.ProcessEvent(*queued_event->event); 313 event_dispatcher_.ProcessEvent(
314 *queued_event->event, EventDispatcher::AcceleratorMatchPhase::ANY);
281 return; 315 return;
282 } 316 }
283 if (queued_event->processed_target->IsValid()) { 317 if (queued_event->processed_target->IsValid()) {
284 DispatchInputEventToWindowImpl( 318 DispatchInputEventToWindowImpl(
285 queued_event->processed_target->window(), 319 queued_event->processed_target->window(),
286 queued_event->processed_target->client_id(), *queued_event->event, 320 queued_event->processed_target->client_id(), *queued_event->event,
287 queued_event->processed_target->accelerator()); 321 queued_event->processed_target->accelerator());
288 return; 322 return;
289 } 323 }
290 } 324 }
(...skipping 11 matching lines...) Expand all
302 DCHECK(event_dispatcher_.mouse_cursor_source_window()); 336 DCHECK(event_dispatcher_.mouse_cursor_source_window());
303 337
304 int32_t cursor_id = 0; 338 int32_t cursor_id = 0;
305 if (event_dispatcher_.GetCurrentMouseCursor(&cursor_id)) { 339 if (event_dispatcher_.GetCurrentMouseCursor(&cursor_id)) {
306 WindowManagerDisplayRoot* display_root = 340 WindowManagerDisplayRoot* display_root =
307 display_manager()->GetWindowManagerDisplayRoot(target); 341 display_manager()->GetWindowManagerDisplayRoot(target);
308 display_root->display()->UpdateNativeCursor(cursor_id); 342 display_root->display()->UpdateNativeCursor(cursor_id);
309 } 343 }
310 } 344 }
311 345
346 event_dispatch_phase_ = EventDispatchPhase::TARGET;
347
312 WindowTree* tree = window_server()->GetTreeWithId(client_id); 348 WindowTree* tree = window_server()->GetTreeWithId(client_id);
313 349
314 // TOOD(sad): Adjust this delay, possibly make this dynamic. 350 ScheduleInputEventTimeout(tree);
315 const base::TimeDelta max_delay = base::debug::BeingDebugged()
316 ? base::TimeDelta::FromDays(1)
317 : GetDefaultAckTimerDelay();
318 event_ack_timer_.Start(
319 FROM_HERE, max_delay,
320 base::Bind(&WindowManagerState::OnEventAckTimeout,
321 weak_factory_.GetWeakPtr(), tree->id()));
322 351
323 tree_awaiting_input_ack_ = tree;
324 if (accelerator) { 352 if (accelerator) {
325 event_awaiting_input_ack_ = ui::Event::Clone(event); 353 event_awaiting_input_ack_ = ui::Event::Clone(event);
326 post_target_accelerator_ = accelerator; 354 post_target_accelerator_ = accelerator;
327 } 355 }
328 356
329 // Ignore |tree| because it will receive the event via normal dispatch. 357 // Ignore |tree| because it will receive the event via normal dispatch.
330 window_server()->SendToEventObservers(event, user_id(), tree); 358 window_server()->SendToEventObservers(event, user_id(), tree);
331 359
332 tree->DispatchInputEvent(target, event); 360 tree->DispatchInputEvent(target, event);
333 } 361 }
(...skipping 20 matching lines...) Expand all
354 LOG(ERROR) << "ServerWindow hierarchy:\n" 382 LOG(ERROR) << "ServerWindow hierarchy:\n"
355 << display_root->root()->GetDebugWindowHierarchy(); 383 << display_root->root()->GetDebugWindowHierarchy();
356 } 384 }
357 } 385 }
358 return true; 386 return true;
359 } 387 }
360 #endif 388 #endif
361 return false; 389 return false;
362 } 390 }
363 391
392 void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree) {
393 // TOOD(sad): Adjust this delay, possibly make this dynamic.
394 const base::TimeDelta max_delay = base::debug::BeingDebugged()
395 ? base::TimeDelta::FromDays(1)
396 : GetDefaultAckTimerDelay();
397 event_ack_timer_.Start(FROM_HERE, max_delay,
398 base::Bind(&WindowManagerState::OnEventAckTimeout,
399 weak_factory_.GetWeakPtr(), tree->id()));
400
401 tree_awaiting_input_ack_ = tree;
402 }
403
364 //////////////////////////////////////////////////////////////////////////////// 404 ////////////////////////////////////////////////////////////////////////////////
365 // EventDispatcherDelegate: 405 // EventDispatcherDelegate:
366 406
367 void WindowManagerState::OnAccelerator(uint32_t accelerator_id, 407 void WindowManagerState::OnAccelerator(uint32_t accelerator_id,
368 const ui::Event& event) { 408 const ui::Event& event,
409 AcceleratorPhase phase) {
369 DCHECK(IsActive()); 410 DCHECK(IsActive());
370 if (HandleDebugAccelerator(accelerator_id)) 411 if (HandleDebugAccelerator(accelerator_id))
371 return; 412 return;
372 window_tree_->OnAccelerator(accelerator_id, event); 413 const bool needs_ack = phase == AcceleratorPhase::PRE;
414 if (needs_ack) {
415 DCHECK_EQ(EventDispatchPhase::NONE, event_dispatch_phase_);
416 event_dispatch_phase_ = EventDispatchPhase::PRE_TARGET_ACCELERATOR;
417 event_awaiting_input_ack_ = ui::Event::Clone(event);
418 ScheduleInputEventTimeout(window_tree_);
419 }
420 window_tree_->OnAccelerator(accelerator_id, event, needs_ack);
373 } 421 }
374 422
375 void WindowManagerState::SetFocusedWindowFromEventDispatcher( 423 void WindowManagerState::SetFocusedWindowFromEventDispatcher(
376 ServerWindow* new_focused_window) { 424 ServerWindow* new_focused_window) {
377 DCHECK(IsActive()); 425 DCHECK(IsActive());
378 window_server()->SetFocusedWindow(new_focused_window); 426 window_server()->SetFocusedWindow(new_focused_window);
379 } 427 }
380 428
381 ServerWindow* WindowManagerState::GetFocusedWindowForEventDispatcher() { 429 ServerWindow* WindowManagerState::GetFocusedWindowForEventDispatcher() {
382 return window_server()->GetFocusedWindow(); 430 return window_server()->GetFocusedWindow();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 return display_root ? display_root->root() : nullptr; 524 return display_root ? display_root->root() : nullptr;
477 } 525 }
478 526
479 void WindowManagerState::OnEventTargetNotFound(const ui::Event& event) { 527 void WindowManagerState::OnEventTargetNotFound(const ui::Event& event) {
480 window_server()->SendToEventObservers(event, user_id(), 528 window_server()->SendToEventObservers(event, user_id(),
481 nullptr /* ignore_tree */); 529 nullptr /* ignore_tree */);
482 } 530 }
483 531
484 } // namespace ws 532 } // namespace ws
485 } // namespace ui 533 } // namespace ui
OLDNEW
« 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