cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / ash / accelerators / key_hold_detector.cc
blob99a9abb52152bb652291611c2824b241e79ac880
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/accelerators/key_hold_detector.h"
7 #include "ash/shell.h"
8 #include "base/message_loop/message_loop.h"
9 #include "ui/aura/window_tracker.h"
10 #include "ui/aura/window_tree_host.h"
11 #include "ui/events/event_dispatcher.h"
12 #include "ui/events/event_processor.h"
14 namespace ash {
15 namespace {
17 void DispatchPressedEvent(const ui::KeyEvent& key_event,
18 scoped_ptr<aura::WindowTracker> tracker) {
19 // The target window may be gone.
20 if (tracker->windows().empty())
21 return;
22 ui::KeyEvent event(key_event);
23 aura::Window* target = *(tracker->windows().begin());
24 ignore_result(
25 target->GetHost()->event_processor()->OnEventFromSource(&event));
28 void PostPressedEvent(ui::KeyEvent* event) {
29 // Modify RELEASED event to PRESSED event.
30 const ui::KeyEvent pressed_event(
31 ui::ET_KEY_PRESSED,
32 event->key_code(),
33 event->code(),
34 event->flags() | ui::EF_SHIFT_DOWN | ui::EF_IS_SYNTHESIZED);
35 scoped_ptr<aura::WindowTracker> tracker(new aura::WindowTracker);
36 tracker->Add(static_cast<aura::Window*>(event->target()));
38 base::MessageLoopForUI::current()->PostTask(
39 FROM_HERE,
40 base::Bind(&DispatchPressedEvent, pressed_event, base::Passed(&tracker)));
43 } // namespace
45 KeyHoldDetector::KeyHoldDetector(scoped_ptr<Delegate> delegate)
46 : state_(INITIAL),
47 delegate_(delegate.Pass()) {}
49 KeyHoldDetector::~KeyHoldDetector() {}
51 void KeyHoldDetector::OnKeyEvent(ui::KeyEvent* event) {
52 if (!delegate_->ShouldProcessEvent(event))
53 return;
55 if (delegate_->IsStartEvent(event)) {
56 switch (state_) {
57 case INITIAL:
58 // Pass through posted event.
59 if (event->flags() & ui::EF_IS_SYNTHESIZED) {
60 event->set_flags(event->flags() & ~ui::EF_IS_SYNTHESIZED);
61 return;
63 state_ = PRESSED;
64 if (delegate_->ShouldStopEventPropagation()) {
65 // Don't process ET_KEY_PRESSED event yet. The ET_KEY_PRESSED
66 // event will be generated upon ET_KEY_RELEASEED event below.
67 event->StopPropagation();
69 break;
70 case PRESSED:
71 state_ = HOLD;
72 // pass through
73 case HOLD:
74 delegate_->OnKeyHold(event);
75 if (delegate_->ShouldStopEventPropagation())
76 event->StopPropagation();
77 break;
79 } else if (event->type() == ui::ET_KEY_RELEASED) {
80 switch (state_) {
81 case INITIAL:
82 break;
83 case PRESSED: {
84 if (delegate_->ShouldStopEventPropagation()) {
85 PostPressedEvent(event);
86 event->StopPropagation();
88 break;
90 case HOLD: {
91 delegate_->OnKeyUnhold(event);
92 if (delegate_->ShouldStopEventPropagation())
93 event->StopPropagation();
94 break;
97 state_ = INITIAL;
101 } // namespace ash