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"
12 #include "ash/shell.h"
13 #include "base/message_loop/message_loop.h"
14 #include "ui/aura/window_tracker.h"
15 #include "ui/aura/window_tree_host.h"
16 #include "ui/events/event_dispatcher.h"
17 #include "ui/events/event_processor.h"
22 void DispatchPressedEvent(const ui::KeyEvent
& key_event
,
23 scoped_ptr
<aura::WindowTracker
> tracker
) {
24 // The target window may be gone.
25 if (tracker
->windows().empty())
27 ui::KeyEvent
event(key_event
);
28 aura::Window
* target
= *(tracker
->windows().begin());
30 target
->GetHost()->event_processor()->OnEventFromSource(&event
));
33 void PostPressedEvent(ui::KeyEvent
* event
) {
34 // Modify RELEASED event to PRESSED event.
35 const ui::KeyEvent
pressed_event(
39 event
->flags() | ui::EF_SHIFT_DOWN
| ui::EF_IS_SYNTHESIZED
);
40 scoped_ptr
<aura::WindowTracker
> tracker(new aura::WindowTracker
);
41 tracker
->Add(static_cast<aura::Window
*>(event
->target()));
43 base::MessageLoopForUI::current()->PostTask(
45 base::Bind(&DispatchPressedEvent
, pressed_event
, base::Passed(&tracker
)));
50 KeyHoldDetector::KeyHoldDetector(scoped_ptr
<Delegate
> delegate
)
52 delegate_(delegate
.Pass()) {}
54 KeyHoldDetector::~KeyHoldDetector() {}
56 void KeyHoldDetector::OnKeyEvent(ui::KeyEvent
* event
) {
57 if (!delegate_
->ShouldProcessEvent(event
))
60 if (delegate_
->IsStartEvent(event
)) {
63 // Pass through posted event.
64 if (event
->flags() & ui::EF_IS_SYNTHESIZED
) {
65 event
->set_flags(event
->flags() & ~ui::EF_IS_SYNTHESIZED
);
69 // Don't process ET_KEY_PRESSED event yet. The ET_KEY_PRESSED
70 // event will be generated upon ET_KEY_RELEASEED event below.
71 event
->StopPropagation();
77 delegate_
->OnKeyHold(event
);
78 event
->StopPropagation();
81 } else if (event
->type() == ui::ET_KEY_RELEASED
) {
86 PostPressedEvent(event
);
87 event
->StopPropagation();
91 delegate_
->OnKeyUnhold(event
);
92 event
->StopPropagation();