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

Side by Side Diff: services/ui/ws/window_manager_state.cc

Issue 2208443002: Changes accelerators registered by mus to not interfere with those of client (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comment Created 4 years, 4 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') | no next file » | 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"
11 #include "services/ui/ws/display_manager.h" 11 #include "services/ui/ws/display_manager.h"
12 #include "services/ui/ws/platform_display.h" 12 #include "services/ui/ws/platform_display.h"
13 #include "services/ui/ws/server_window.h" 13 #include "services/ui/ws/server_window.h"
14 #include "services/ui/ws/user_display_manager.h" 14 #include "services/ui/ws/user_display_manager.h"
15 #include "services/ui/ws/user_id_tracker.h" 15 #include "services/ui/ws/user_id_tracker.h"
16 #include "services/ui/ws/window_manager_display_root.h" 16 #include "services/ui/ws/window_manager_display_root.h"
17 #include "services/ui/ws/window_server.h" 17 #include "services/ui/ws/window_server.h"
18 #include "services/ui/ws/window_tree.h" 18 #include "services/ui/ws/window_tree.h"
19 #include "ui/events/event.h" 19 #include "ui/events/event.h"
20 20
21 namespace ui { 21 namespace ui {
22 namespace ws { 22 namespace ws {
23 namespace { 23 namespace {
24 24
25 // Debug accelerator IDs start far above the highest valid Windows command ID
26 // (0xDFFF) and Chrome's highest IDC command ID.
27 const uint32_t kPrintWindowsDebugAcceleratorId = 1u << 31;
28
29 base::TimeDelta GetDefaultAckTimerDelay() { 25 base::TimeDelta GetDefaultAckTimerDelay() {
30 #if defined(NDEBUG) 26 #if defined(NDEBUG)
31 return base::TimeDelta::FromMilliseconds(100); 27 return base::TimeDelta::FromMilliseconds(100);
32 #else 28 #else
33 return base::TimeDelta::FromMilliseconds(1000); 29 return base::TimeDelta::FromMilliseconds(1000);
34 #endif 30 #endif
35 } 31 }
36 32
37 bool EventsCanBeCoalesced(const ui::Event& one, const ui::Event& two) { 33 bool EventsCanBeCoalesced(const ui::Event& one, const ui::Event& two) {
38 if (one.type() != two.type() || one.flags() != two.flags()) 34 if (one.type() != two.type() || one.flags() != two.flags())
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 if (!event_queue_.empty() && !event_queue_.back()->processed_target && 189 if (!event_queue_.empty() && !event_queue_.back()->processed_target &&
194 EventsCanBeCoalesced(*event_queue_.back()->event, event)) { 190 EventsCanBeCoalesced(*event_queue_.back()->event, event)) {
195 event_queue_.back()->event = CoalesceEvents( 191 event_queue_.back()->event = CoalesceEvents(
196 std::move(event_queue_.back()->event), ui::Event::Clone(event)); 192 std::move(event_queue_.back()->event), ui::Event::Clone(event));
197 return; 193 return;
198 } 194 }
199 QueueEvent(event, nullptr); 195 QueueEvent(event, nullptr);
200 return; 196 return;
201 } 197 }
202 198
203 event_dispatcher_.ProcessEvent(event, 199 ProcessEventImpl(event);
204 EventDispatcher::AcceleratorMatchPhase::ANY);
205 } 200 }
206 201
207 void WindowManagerState::OnEventAck(mojom::WindowTree* tree, 202 void WindowManagerState::OnEventAck(mojom::WindowTree* tree,
208 mojom::EventResult result) { 203 mojom::EventResult result) {
209 if (tree_awaiting_input_ack_ != tree || 204 if (tree_awaiting_input_ack_ != tree ||
210 event_dispatch_phase_ != EventDispatchPhase::TARGET) { 205 event_dispatch_phase_ != EventDispatchPhase::TARGET) {
211 // TODO(sad): The ack must have arrived after the timeout. We should do 206 // TODO(sad): The ack must have arrived after the timeout. We should do
212 // something here, and in OnEventAckTimeout(). 207 // something here, and in OnEventAckTimeout().
213 return; 208 return;
214 } 209 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 void WindowManagerState::OnEventAckTimeout(ClientSpecificId client_id) { 285 void WindowManagerState::OnEventAckTimeout(ClientSpecificId client_id) {
291 WindowTree* hung_tree = window_server()->GetTreeWithId(client_id); 286 WindowTree* hung_tree = window_server()->GetTreeWithId(client_id);
292 if (hung_tree && !hung_tree->janky()) 287 if (hung_tree && !hung_tree->janky())
293 window_tree_->ClientJankinessChanged(hung_tree); 288 window_tree_->ClientJankinessChanged(hung_tree);
294 if (event_dispatch_phase_ == EventDispatchPhase::PRE_TARGET_ACCELERATOR) 289 if (event_dispatch_phase_ == EventDispatchPhase::PRE_TARGET_ACCELERATOR)
295 OnAcceleratorAck(mojom::EventResult::UNHANDLED); 290 OnAcceleratorAck(mojom::EventResult::UNHANDLED);
296 else 291 else
297 OnEventAck(tree_awaiting_input_ack_, mojom::EventResult::UNHANDLED); 292 OnEventAck(tree_awaiting_input_ack_, mojom::EventResult::UNHANDLED);
298 } 293 }
299 294
295 void WindowManagerState::ProcessEventImpl(const ui::Event& event) {
296 // Debug accelerators are always checked and don't interfere with processing.
297 ProcessDebugAccelerator(event);
298 event_dispatcher_.ProcessEvent(event,
299 EventDispatcher::AcceleratorMatchPhase::ANY);
300 }
301
300 void WindowManagerState::QueueEvent( 302 void WindowManagerState::QueueEvent(
301 const ui::Event& event, 303 const ui::Event& event,
302 std::unique_ptr<ProcessedEventTarget> processed_event_target) { 304 std::unique_ptr<ProcessedEventTarget> processed_event_target) {
303 std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent); 305 std::unique_ptr<QueuedEvent> queued_event(new QueuedEvent);
304 queued_event->event = ui::Event::Clone(event); 306 queued_event->event = ui::Event::Clone(event);
305 queued_event->processed_target = std::move(processed_event_target); 307 queued_event->processed_target = std::move(processed_event_target);
306 event_queue_.push(std::move(queued_event)); 308 event_queue_.push(std::move(queued_event));
307 } 309 }
308 310
309 void WindowManagerState::ProcessNextEventFromQueue() { 311 void WindowManagerState::ProcessNextEventFromQueue() {
310 // Loop through |event_queue_| stopping after dispatching the first valid 312 // Loop through |event_queue_| stopping after dispatching the first valid
311 // event. 313 // event.
312 while (!event_queue_.empty()) { 314 while (!event_queue_.empty()) {
313 std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front()); 315 std::unique_ptr<QueuedEvent> queued_event = std::move(event_queue_.front());
314 event_queue_.pop(); 316 event_queue_.pop();
315 if (!queued_event->processed_target) { 317 if (!queued_event->processed_target) {
316 event_dispatcher_.ProcessEvent( 318 ProcessEventImpl(*queued_event->event);
317 *queued_event->event, EventDispatcher::AcceleratorMatchPhase::ANY);
318 return; 319 return;
319 } 320 }
320 if (queued_event->processed_target->IsValid()) { 321 if (queued_event->processed_target->IsValid()) {
321 DispatchInputEventToWindowImpl( 322 DispatchInputEventToWindowImpl(
322 queued_event->processed_target->window(), 323 queued_event->processed_target->window(),
323 queued_event->processed_target->client_id(), *queued_event->event, 324 queued_event->processed_target->client_id(), *queued_event->event,
324 queued_event->processed_target->accelerator()); 325 queued_event->processed_target->accelerator());
325 return; 326 return;
326 } 327 }
327 } 328 }
(...skipping 29 matching lines...) Expand all
357 post_target_accelerator_ = accelerator; 358 post_target_accelerator_ = accelerator;
358 } 359 }
359 360
360 // Ignore |tree| because it will receive the event via normal dispatch. 361 // Ignore |tree| because it will receive the event via normal dispatch.
361 window_server()->SendToEventObservers(event, user_id(), tree); 362 window_server()->SendToEventObservers(event, user_id(), tree);
362 363
363 tree->DispatchInputEvent(target, event); 364 tree->DispatchInputEvent(target, event);
364 } 365 }
365 366
366 void WindowManagerState::AddDebugAccelerators() { 367 void WindowManagerState::AddDebugAccelerators() {
367 // Always register the accelerators, even if they only work in debug, so that 368 const DebugAccelerator accelerator = {
368 // keyboard behavior is the same in release and debug builds. 369 DebugAcceleratorType::PRINT_WINDOWS, ui::VKEY_S,
369 mojom::EventMatcherPtr matcher = CreateKeyMatcher( 370 ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN};
370 ui::mojom::KeyboardCode::S, ui::mojom::kEventFlagControlDown | 371 debug_accelerators_.push_back(accelerator);
371 ui::mojom::kEventFlagAltDown |
372 ui::mojom::kEventFlagShiftDown);
373 event_dispatcher_.AddAccelerator(kPrintWindowsDebugAcceleratorId,
374 std::move(matcher));
375 } 372 }
376 373
377 bool WindowManagerState::HandleDebugAccelerator(uint32_t accelerator_id) { 374 void WindowManagerState::ProcessDebugAccelerator(const ui::Event& event) {
375 if (event.type() != ui::ET_KEY_PRESSED)
376 return;
377
378 const ui::KeyEvent& key_event = *event.AsKeyEvent();
379 for (const DebugAccelerator& accelerator : debug_accelerators_) {
380 if (accelerator.key_code == key_event.key_code() &&
381 accelerator.event_flags == key_event.flags()) {
382 HandleDebugAccelerator(accelerator.type);
383 break;
384 }
385 }
386 }
387
388 void WindowManagerState::HandleDebugAccelerator(DebugAcceleratorType type) {
378 #if !defined(NDEBUG) 389 #if !defined(NDEBUG)
379 if (accelerator_id == kPrintWindowsDebugAcceleratorId) { 390 // Error so it will be collected in system logs.
380 // Error so it will be collected in system logs. 391 for (Display* display : display_manager()->displays()) {
381 for (Display* display : display_manager()->displays()) { 392 WindowManagerDisplayRoot* display_root =
382 WindowManagerDisplayRoot* display_root = 393 display->GetWindowManagerDisplayRootForUser(user_id());
383 display->GetWindowManagerDisplayRootForUser(user_id()); 394 if (display_root) {
384 if (display_root) { 395 LOG(ERROR) << "ServerWindow hierarchy:\n"
385 LOG(ERROR) << "ServerWindow hierarchy:\n" 396 << display_root->root()->GetDebugWindowHierarchy();
386 << display_root->root()->GetDebugWindowHierarchy();
387 }
388 } 397 }
389 return true;
390 } 398 }
391 #endif 399 #endif
392 return false;
393 } 400 }
394 401
395 void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree) { 402 void WindowManagerState::ScheduleInputEventTimeout(WindowTree* tree) {
396 // TOOD(sad): Adjust this delay, possibly make this dynamic. 403 // TOOD(sad): Adjust this delay, possibly make this dynamic.
397 const base::TimeDelta max_delay = base::debug::BeingDebugged() 404 const base::TimeDelta max_delay = base::debug::BeingDebugged()
398 ? base::TimeDelta::FromDays(1) 405 ? base::TimeDelta::FromDays(1)
399 : GetDefaultAckTimerDelay(); 406 : GetDefaultAckTimerDelay();
400 event_ack_timer_.Start(FROM_HERE, max_delay, 407 event_ack_timer_.Start(FROM_HERE, max_delay,
401 base::Bind(&WindowManagerState::OnEventAckTimeout, 408 base::Bind(&WindowManagerState::OnEventAckTimeout,
402 weak_factory_.GetWeakPtr(), tree->id())); 409 weak_factory_.GetWeakPtr(), tree->id()));
403 410
404 tree_awaiting_input_ack_ = tree; 411 tree_awaiting_input_ack_ = tree;
405 } 412 }
406 413
407 //////////////////////////////////////////////////////////////////////////////// 414 ////////////////////////////////////////////////////////////////////////////////
408 // EventDispatcherDelegate: 415 // EventDispatcherDelegate:
409 416
410 void WindowManagerState::OnAccelerator(uint32_t accelerator_id, 417 void WindowManagerState::OnAccelerator(uint32_t accelerator_id,
411 const ui::Event& event, 418 const ui::Event& event,
412 AcceleratorPhase phase) { 419 AcceleratorPhase phase) {
413 DCHECK(IsActive()); 420 DCHECK(IsActive());
414 if (HandleDebugAccelerator(accelerator_id))
415 return;
416 const bool needs_ack = phase == AcceleratorPhase::PRE; 421 const bool needs_ack = phase == AcceleratorPhase::PRE;
417 if (needs_ack) { 422 if (needs_ack) {
418 DCHECK_EQ(EventDispatchPhase::NONE, event_dispatch_phase_); 423 DCHECK_EQ(EventDispatchPhase::NONE, event_dispatch_phase_);
419 event_dispatch_phase_ = EventDispatchPhase::PRE_TARGET_ACCELERATOR; 424 event_dispatch_phase_ = EventDispatchPhase::PRE_TARGET_ACCELERATOR;
420 event_awaiting_input_ack_ = ui::Event::Clone(event); 425 event_awaiting_input_ack_ = ui::Event::Clone(event);
421 ScheduleInputEventTimeout(window_tree_); 426 ScheduleInputEventTimeout(window_tree_);
422 } 427 }
423 window_tree_->OnAccelerator(accelerator_id, event, needs_ack); 428 window_tree_->OnAccelerator(accelerator_id, event, needs_ack);
424 } 429 }
425 430
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 return display_root ? display_root->root() : nullptr; 534 return display_root ? display_root->root() : nullptr;
530 } 535 }
531 536
532 void WindowManagerState::OnEventTargetNotFound(const ui::Event& event) { 537 void WindowManagerState::OnEventTargetNotFound(const ui::Event& event) {
533 window_server()->SendToEventObservers(event, user_id(), 538 window_server()->SendToEventObservers(event, user_id(),
534 nullptr /* ignore_tree */); 539 nullptr /* ignore_tree */);
535 } 540 }
536 541
537 } // namespace ws 542 } // namespace ws
538 } // namespace ui 543 } // namespace ui
OLDNEW
« no previous file with comments | « services/ui/ws/window_manager_state.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698