Home | History | Annotate | Download | only in corewm
      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/events/event.h"
     10 #include "ui/base/ime/input_method.h"
     11 #include "ui/base/ime/input_method_factory.h"
     12 
     13 namespace views {
     14 namespace corewm {
     15 
     16 ////////////////////////////////////////////////////////////////////////////////
     17 // InputMethodEventFilter, public:
     18 
     19 InputMethodEventFilter::InputMethodEventFilter(gfx::AcceleratedWidget widget)
     20     : input_method_(ui::CreateInputMethod(this, widget)),
     21       target_root_window_(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 
     27 InputMethodEventFilter::~InputMethodEventFilter() {
     28 }
     29 
     30 void InputMethodEventFilter::SetInputMethodPropertyInRootWindow(
     31     aura::RootWindow* 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   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_root_window_ here.
     49     aura::Window* target = static_cast<aura::Window*>(event->target());
     50     target_root_window_ = target->GetRootWindow();
     51     DCHECK(target_root_window_);
     52     bool handled = false;
     53     if (event->HasNativeEvent())
     54       handled = input_method_->DispatchKeyEvent(event->native_event());
     55     else
     56       handled = input_method_->DispatchFabricatedKeyEvent(*event);
     57     if (handled)
     58       event->StopPropagation();
     59   }
     60 }
     61 
     62 ////////////////////////////////////////////////////////////////////////////////
     63 // InputMethodEventFilter, ui::InputMethodDelegate implementation:
     64 
     65 bool InputMethodEventFilter::DispatchKeyEventPostIME(
     66     const base::NativeEvent& event) {
     67 #if defined(OS_WIN)
     68   DCHECK(event.message != WM_CHAR);
     69 #endif
     70   ui::TranslatedKeyEvent aura_event(event, false /* is_char */);
     71   return target_root_window_->AsRootWindowHostDelegate()->OnHostKeyEvent(
     72       &aura_event);
     73 }
     74 
     75 bool InputMethodEventFilter::DispatchFabricatedKeyEventPostIME(
     76     ui::EventType type,
     77     ui::KeyboardCode key_code,
     78     int flags) {
     79   ui::TranslatedKeyEvent aura_event(type == ui::ET_KEY_PRESSED, key_code,
     80                                     flags);
     81   return target_root_window_->AsRootWindowHostDelegate()->OnHostKeyEvent(
     82       &aura_event);
     83 }
     84 
     85 }  // namespace corewm
     86 }  // namespace views
     87