Home | History | Annotate | Download | only in views
      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.
      4 
      5 #include "mojo/views/native_widget_view_manager.h"
      6 
      7 #include "mojo/aura/window_tree_host_mojo.h"
      8 #include "mojo/services/public/cpp/input_events/input_events_type_converters.h"
      9 #include "ui/aura/client/aura_constants.h"
     10 #include "ui/aura/client/default_capture_client.h"
     11 #include "ui/aura/window.h"
     12 #include "ui/aura/window_event_dispatcher.h"
     13 #include "ui/base/ime/input_method.h"
     14 #include "ui/base/ime/input_method_base.h"
     15 #include "ui/base/ime/input_method_delegate.h"
     16 #include "ui/base/ime/input_method_factory.h"
     17 #include "ui/base/ime/text_input_client.h"
     18 #include "ui/wm/core/base_focus_rules.h"
     19 #include "ui/wm/core/capture_controller.h"
     20 #include "ui/wm/core/focus_controller.h"
     21 
     22 #if defined(OS_LINUX)
     23 #include "mojo/views/input_method_mojo_linux.h"
     24 #endif
     25 
     26 namespace mojo {
     27 namespace {
     28 
     29 // TODO: figure out what this should be.
     30 class FocusRulesImpl : public wm::BaseFocusRules {
     31  public:
     32   FocusRulesImpl() {}
     33   virtual ~FocusRulesImpl() {}
     34 
     35   virtual bool SupportsChildActivation(aura::Window* window) const OVERRIDE {
     36     return true;
     37   }
     38 
     39  private:
     40   DISALLOW_COPY_AND_ASSIGN(FocusRulesImpl);
     41 };
     42 
     43 class MinimalInputEventFilter : public ui::internal::InputMethodDelegate,
     44                                 public ui::EventHandler {
     45  public:
     46   explicit MinimalInputEventFilter(aura::Window* root)
     47       : root_(root) {
     48     ui::InitializeInputMethodForTesting();
     49 #if defined(OS_LINUX)
     50     input_method_.reset(new InputMethodMojoLinux(this));
     51 #else
     52     input_method_ = ui::CreateInputMethod(this, gfx::kNullAcceleratedWidget);
     53 #endif
     54     input_method_->Init(true);
     55     root_->AddPreTargetHandler(this);
     56     root_->SetProperty(aura::client::kRootWindowInputMethodKey,
     57                        input_method_.get());
     58   }
     59 
     60   virtual ~MinimalInputEventFilter() {
     61     root_->RemovePreTargetHandler(this);
     62     root_->SetProperty(aura::client::kRootWindowInputMethodKey,
     63                        static_cast<ui::InputMethod*>(NULL));
     64   }
     65 
     66  private:
     67   // ui::EventHandler:
     68   virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
     69     // See the comment in InputMethodEventFilter::OnKeyEvent() for details.
     70     if (event->IsTranslated()) {
     71       event->SetTranslated(false);
     72     } else {
     73       if (input_method_->DispatchKeyEvent(*event))
     74         event->StopPropagation();
     75     }
     76   }
     77 
     78   // ui::internal::InputMethodDelegate:
     79   virtual bool DispatchKeyEventPostIME(const ui::KeyEvent& event) OVERRIDE {
     80     // See the comment in InputMethodEventFilter::DispatchKeyEventPostIME() for
     81     // details.
     82     ui::KeyEvent aura_event(event);
     83     aura_event.SetTranslated(true);
     84     ui::EventDispatchDetails details =
     85         root_->GetHost()->dispatcher()->OnEventFromSource(&aura_event);
     86     return aura_event.handled() || details.dispatcher_destroyed;
     87   }
     88 
     89   aura::Window* root_;
     90   scoped_ptr<ui::InputMethod> input_method_;
     91 
     92   DISALLOW_COPY_AND_ASSIGN(MinimalInputEventFilter);
     93 };
     94 
     95 }  // namespace
     96 
     97 NativeWidgetViewManager::NativeWidgetViewManager(
     98     views::internal::NativeWidgetDelegate* delegate, View* view)
     99     : NativeWidgetAura(delegate),
    100       view_(view) {
    101   view_->AddObserver(this);
    102   window_tree_host_.reset(new WindowTreeHostMojo(view_, this));
    103   window_tree_host_->InitHost();
    104 
    105   ime_filter_.reset(
    106       new MinimalInputEventFilter(window_tree_host_->window()));
    107 
    108   focus_client_.reset(new wm::FocusController(new FocusRulesImpl));
    109 
    110   aura::client::SetFocusClient(window_tree_host_->window(),
    111                                focus_client_.get());
    112   aura::client::SetActivationClient(window_tree_host_->window(),
    113                                     focus_client_.get());
    114   window_tree_host_->window()->AddPreTargetHandler(focus_client_.get());
    115 
    116   capture_client_.reset(
    117       new aura::client::DefaultCaptureClient(window_tree_host_->window()));
    118 }
    119 
    120 NativeWidgetViewManager::~NativeWidgetViewManager() {
    121   if (view_)
    122     view_->RemoveObserver(this);
    123 }
    124 
    125 void NativeWidgetViewManager::InitNativeWidget(
    126     const views::Widget::InitParams& in_params) {
    127   views::Widget::InitParams params(in_params);
    128   params.parent = window_tree_host_->window();
    129   NativeWidgetAura::InitNativeWidget(params);
    130 }
    131 
    132 void NativeWidgetViewManager::CompositorContentsChanged(
    133     const SkBitmap& bitmap) {
    134   if (view_)
    135     view_->SetContents(bitmap);
    136 }
    137 
    138 void NativeWidgetViewManager::OnViewDestroyed(View* view) {
    139   DCHECK_EQ(view, view_);
    140   view->RemoveObserver(this);
    141   view_ = NULL;
    142 }
    143 
    144 void NativeWidgetViewManager::OnViewBoundsChanged(View* view,
    145                                                   const gfx::Rect& old_bounds,
    146                                                   const gfx::Rect& new_bounds) {
    147   GetWidget()->SetBounds(gfx::Rect(view->bounds().size()));
    148 }
    149 
    150 void NativeWidgetViewManager::OnViewInputEvent(View* view,
    151                                                const EventPtr& event) {
    152   scoped_ptr<ui::Event> ui_event(event.To<scoped_ptr<ui::Event> >());
    153   if (ui_event)
    154     window_tree_host_->SendEventToProcessor(ui_event.get());
    155 }
    156 
    157 }  // namespace mojo
    158