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"
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"
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())
22 ui::KeyEvent
event(key_event
);
23 aura::Window
* target
= *(tracker
->windows().begin());
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(
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(
40 base::Bind(&DispatchPressedEvent
, pressed_event
, base::Passed(&tracker
)));
45 KeyHoldDetector::KeyHoldDetector(scoped_ptr
<Delegate
> delegate
)
47 delegate_(delegate
.Pass()) {}
49 KeyHoldDetector::~KeyHoldDetector() {}
51 void KeyHoldDetector::OnKeyEvent(ui::KeyEvent
* event
) {
52 if (!delegate_
->ShouldProcessEvent(event
))
55 if (delegate_
->IsStartEvent(event
)) {
58 // Pass through posted event.
59 if (event
->flags() & ui::EF_IS_SYNTHESIZED
) {
60 event
->set_flags(event
->flags() & ~ui::EF_IS_SYNTHESIZED
);
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();
74 delegate_
->OnKeyHold(event
);
75 if (delegate_
->ShouldStopEventPropagation())
76 event
->StopPropagation();
79 } else if (event
->type() == ui::ET_KEY_RELEASED
) {
84 if (delegate_
->ShouldStopEventPropagation()) {
85 PostPressedEvent(event
);
86 event
->StopPropagation();
91 delegate_
->OnKeyUnhold(event
);
92 if (delegate_
->ShouldStopEventPropagation())
93 event
->StopPropagation();