1 // Copyright (c) 2012 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.
4
5 #include "ui/views/corewm/input_method_event_filter.h"
6
7 #include "ui/aura/client/aura_constants.h"
8 #include "ui/aura/root_window.h"
9 #include "ui/base/ime/input_method.h"
10 #include "ui/base/ime/input_method_factory.h"
11 #include "ui/events/event.h"
12
13 namespace views {
14 namespace corewm {
15
16 ////////////////////////////////////////////////////////////////////////////////
17 // InputMethodEventFilter, public:
18
InputMethodEventFilter(gfx::AcceleratedWidget widget)19 InputMethodEventFilter::InputMethodEventFilter(gfx::AcceleratedWidget widget)
20 : input_method_(ui::CreateInputMethod(this, widget)),
21 target_dispatcher_(NULL) {
22 // TODO(yusukes): Check if the root window is currently focused and pass the
23 // result to Init().
24 input_method_->Init(true);
25 }
26
~InputMethodEventFilter()27 InputMethodEventFilter::~InputMethodEventFilter() {
28 }
29
SetInputMethodPropertyInRootWindow(aura::Window * root_window)30 void InputMethodEventFilter::SetInputMethodPropertyInRootWindow(
31 aura::Window* root_window) {
32 root_window->SetProperty(aura::client::kRootWindowInputMethodKey,
33 input_method_.get());
34 }
35
36 ////////////////////////////////////////////////////////////////////////////////
37 // InputMethodEventFilter, EventFilter implementation:
38
OnKeyEvent(ui::KeyEvent * event)39 void InputMethodEventFilter::OnKeyEvent(ui::KeyEvent* event) {
40 const ui::EventType type = event->type();
41 if (type == ui::ET_TRANSLATED_KEY_PRESS ||
42 type == ui::ET_TRANSLATED_KEY_RELEASE) {
43 // The |event| is already handled by this object, change the type of the
44 // event to ui::ET_KEY_* and pass it to the next filter.
45 static_cast<ui::TranslatedKeyEvent*>(event)->ConvertToKeyEvent();
46 } else {
47 // If the focused window is changed, all requests to IME will be
48 // discarded so it's safe to update the target_dispatcher_ here.
49 aura::Window* target = static_cast<aura::Window*>(event->target());
50 target_dispatcher_ = target->GetRootWindow()->GetDispatcher();
51 DCHECK(target_dispatcher_);
52 if (input_method_->DispatchKeyEvent(*event))
53 event->StopPropagation();
54 }
55 }
56
57 ////////////////////////////////////////////////////////////////////////////////
58 // InputMethodEventFilter, ui::InputMethodDelegate implementation:
59
DispatchKeyEventPostIME(const base::NativeEvent & event)60 bool InputMethodEventFilter::DispatchKeyEventPostIME(
61 const base::NativeEvent& event) {
62 #if defined(OS_WIN)
63 DCHECK(event.message != WM_CHAR);
64 #endif
65 ui::TranslatedKeyEvent aura_event(event, false /* is_char */);
66 return target_dispatcher_->AsRootWindowHostDelegate()->OnHostKeyEvent(
67 &aura_event);
68 }
69
DispatchFabricatedKeyEventPostIME(ui::EventType type,ui::KeyboardCode key_code,int flags)70 bool InputMethodEventFilter::DispatchFabricatedKeyEventPostIME(
71 ui::EventType type,
72 ui::KeyboardCode key_code,
73 int flags) {
74 ui::TranslatedKeyEvent aura_event(type == ui::ET_KEY_PRESSED, key_code,
75 flags);
76 return target_dispatcher_->AsRootWindowHostDelegate()->OnHostKeyEvent(
77 &aura_event);
78 }
79
80 } // namespace corewm
81 } // namespace views
82