• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
FocusRulesImpl()32   FocusRulesImpl() {}
~FocusRulesImpl()33   virtual ~FocusRulesImpl() {}
34 
SupportsChildActivation(aura::Window * window) const35   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:
MinimalInputEventFilter(aura::Window * root)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 
~MinimalInputEventFilter()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:
OnKeyEvent(ui::KeyEvent * event)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:
DispatchKeyEventPostIME(const ui::KeyEvent & event)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 
NativeWidgetViewManager(views::internal::NativeWidgetDelegate * delegate,View * view)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 
~NativeWidgetViewManager()120 NativeWidgetViewManager::~NativeWidgetViewManager() {
121   if (view_)
122     view_->RemoveObserver(this);
123 }
124 
InitNativeWidget(const views::Widget::InitParams & in_params)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 
CompositorContentsChanged(const SkBitmap & bitmap)132 void NativeWidgetViewManager::CompositorContentsChanged(
133     const SkBitmap& bitmap) {
134   if (view_)
135     view_->SetContents(bitmap);
136 }
137 
OnViewDestroyed(View * view)138 void NativeWidgetViewManager::OnViewDestroyed(View* view) {
139   DCHECK_EQ(view, view_);
140   view->RemoveObserver(this);
141   view_ = NULL;
142 }
143 
OnViewBoundsChanged(View * view,const gfx::Rect & old_bounds,const gfx::Rect & new_bounds)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 
OnViewInputEvent(View * view,const EventPtr & event)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