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/wm/core/input_method_event_filter.h" 6 7 #include "ui/aura/client/aura_constants.h" 8 #include "ui/aura/window_tree_host.h" 9 #include "ui/base/ime/input_method.h" 10 #include "ui/base/ime/input_method_factory.h" 11 #include "ui/base/ime/text_input_client.h" 12 #include "ui/events/event.h" 13 #include "ui/events/event_processor.h" 14 15 namespace wm { 16 17 //////////////////////////////////////////////////////////////////////////////// 18 // InputMethodEventFilter, public: 19 20 InputMethodEventFilter::InputMethodEventFilter(gfx::AcceleratedWidget widget) 21 : input_method_(ui::CreateInputMethod(this, widget)) { 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 27 InputMethodEventFilter::~InputMethodEventFilter() { 28 } 29 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 39 void InputMethodEventFilter::OnKeyEvent(ui::KeyEvent* event) { 40 // We're processing key events as follows (details are simplified). 41 // 42 // At the beginning, key events have a ET_KEY_{PRESSED,RELEASED} event type, 43 // and they're passed from step 1 through step 3. 44 // 1. EventProcessor::OnEventFromSource() 45 // 2. InputMethodEventFilter::OnKeyEvent() 46 // 3. InputMethod::DispatchKeyEvent() 47 // where InputMethod may call DispatchKeyEventPostIME() if IME didn't consume 48 // the key event. Otherwise, step 4 through step 6 are skipped and we fall 49 // down to step 7 directly. 50 // 4. InputMethodEventFilter::DispatchKeyEventPostIME() 51 // where the key event is marked as TRANSLATED and the event type becomes 52 // ET_TRANSLATED_KEY_{PRESS,RELEASE}. Then, we dispatch the event again from 53 // the beginning. 54 // 5. EventProcessor::OnEventFromSource() [second time] 55 // 6. InputMethodEventFilter::OnKeyEvent() [second time] 56 // where we know that the event was already processed once by IME and 57 // re-dispatched, we don't pass the event to IME again. Instead we unmark the 58 // event as not translated (as same as the original state), and let the event 59 // dispatcher continue to dispatch the event to the rest event handlers. 60 // 7. EventHandler::OnKeyEvent() 61 if (event->IsTranslated()) { 62 // The |event| was already processed by IME, so we don't pass the event to 63 // IME again. Just let the event dispatcher continue to dispatch the event. 64 event->SetTranslated(false); 65 } else { 66 if (input_method_->DispatchKeyEvent(*event)) 67 event->StopPropagation(); 68 } 69 } 70 71 //////////////////////////////////////////////////////////////////////////////// 72 // InputMethodEventFilter, ui::InputMethodDelegate implementation: 73 74 bool InputMethodEventFilter::DispatchKeyEventPostIME( 75 const ui::KeyEvent& event) { 76 #if defined(OS_WIN) 77 DCHECK(!event.HasNativeEvent() || event.native_event().message != WM_CHAR); 78 #endif 79 // Since the underlying IME didn't consume the key event, we're going to 80 // dispatch the event again from the beginning of the tree of event targets. 81 // This time we have to skip dispatching the event to the IME, we mark the 82 // event as TRANSLATED so we can distinguish this event as a second time 83 // dispatched event. 84 // For the target where to dispatch the event, always tries the current 85 // focused text input client's attached window. And fallback to the target 86 // carried by event. 87 aura::Window* target_window = NULL; 88 ui::TextInputClient* input = input_method_->GetTextInputClient(); 89 if (input) 90 target_window = input->GetAttachedWindow(); 91 if (!target_window) 92 target_window = static_cast<aura::Window*>(event.target()); 93 if (!target_window) 94 return false; 95 ui::EventProcessor* target_dispatcher = 96 target_window->GetRootWindow()->GetHost()->event_processor(); 97 ui::KeyEvent aura_event(event); 98 aura_event.SetTranslated(true); 99 ui::EventDispatchDetails details = 100 target_dispatcher->OnEventFromSource(&aura_event); 101 CHECK(!details.dispatcher_destroyed); 102 return aura_event.handled(); 103 } 104 105 } // namespace wm 106