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 "mojo/services/public/cpp/view_manager/view.h"
10 #include "ui/aura/client/aura_constants.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_delegate.h"
15 #include "ui/base/ime/input_method_factory.h"
16 #include "ui/base/ime/text_input_client.h"
17 #include "ui/wm/core/base_focus_rules.h"
18 #include "ui/wm/core/focus_controller.h"
19
20 namespace mojo {
21 namespace {
22
23 // TODO: figure out what this should be.
24 class FocusRulesImpl : public wm::BaseFocusRules {
25 public:
FocusRulesImpl()26 FocusRulesImpl() {}
~FocusRulesImpl()27 virtual ~FocusRulesImpl() {}
28
SupportsChildActivation(aura::Window * window) const29 virtual bool SupportsChildActivation(aura::Window* window) const OVERRIDE {
30 return true;
31 }
32
33 private:
34 DISALLOW_COPY_AND_ASSIGN(FocusRulesImpl);
35 };
36
37 class MinimalInputEventFilter : public ui::internal::InputMethodDelegate,
38 public ui::EventHandler {
39 public:
MinimalInputEventFilter(aura::Window * root)40 explicit MinimalInputEventFilter(aura::Window* root)
41 : root_(root),
42 input_method_(
43 ui::CreateInputMethod(this, gfx::kNullAcceleratedWidget).Pass()) {
44 ui::InitializeInputMethodForTesting();
45 input_method_->Init(true);
46 root_->AddPreTargetHandler(this);
47 root_->SetProperty(aura::client::kRootWindowInputMethodKey,
48 input_method_.get());
49 }
50
~MinimalInputEventFilter()51 virtual ~MinimalInputEventFilter() {
52 root_->RemovePreTargetHandler(this);
53 root_->SetProperty(aura::client::kRootWindowInputMethodKey,
54 static_cast<ui::InputMethod*>(NULL));
55 }
56
57 private:
58 // ui::EventHandler:
OnKeyEvent(ui::KeyEvent * event)59 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
60 // See the comment in InputMethodEventFilter::OnKeyEvent() for details.
61 if (event->IsTranslated()) {
62 event->SetTranslated(false);
63 } else {
64 if (input_method_->DispatchKeyEvent(*event))
65 event->StopPropagation();
66 }
67 }
68
69 // ui::internal::InputMethodDelegate:
DispatchKeyEventPostIME(const ui::KeyEvent & event)70 virtual bool DispatchKeyEventPostIME(const ui::KeyEvent& event) OVERRIDE {
71 // See the comment in InputMethodEventFilter::DispatchKeyEventPostIME() for
72 // details.
73 ui::KeyEvent aura_event(event);
74 aura_event.SetTranslated(true);
75 ui::EventDispatchDetails details =
76 root_->GetHost()->dispatcher()->OnEventFromSource(&aura_event);
77 return aura_event.handled() || details.dispatcher_destroyed;
78 }
79
80 aura::Window* root_;
81 scoped_ptr<ui::InputMethod> input_method_;
82
83 DISALLOW_COPY_AND_ASSIGN(MinimalInputEventFilter);
84 };
85
86 } // namespace
87
NativeWidgetViewManager(views::internal::NativeWidgetDelegate * delegate,view_manager::Node * node)88 NativeWidgetViewManager::NativeWidgetViewManager(
89 views::internal::NativeWidgetDelegate* delegate, view_manager::Node* node)
90 : NativeWidgetAura(delegate),
91 node_(node) {
92 node_->active_view()->AddObserver(this);
93 window_tree_host_.reset(new WindowTreeHostMojo(node_, this));
94 window_tree_host_->InitHost();
95
96 ime_filter_.reset(
97 new MinimalInputEventFilter(window_tree_host_->window()));
98
99 focus_client_.reset(new wm::FocusController(new FocusRulesImpl));
100
101 aura::client::SetFocusClient(window_tree_host_->window(),
102 focus_client_.get());
103 aura::client::SetActivationClient(window_tree_host_->window(),
104 focus_client_.get());
105 window_tree_host_->window()->AddPreTargetHandler(focus_client_.get());
106 }
107
~NativeWidgetViewManager()108 NativeWidgetViewManager::~NativeWidgetViewManager() {
109 node_->active_view()->RemoveObserver(this);
110 }
111
InitNativeWidget(const views::Widget::InitParams & in_params)112 void NativeWidgetViewManager::InitNativeWidget(
113 const views::Widget::InitParams& in_params) {
114 views::Widget::InitParams params(in_params);
115 params.parent = window_tree_host_->window();
116 NativeWidgetAura::InitNativeWidget(params);
117 }
118
CompositorContentsChanged(const SkBitmap & bitmap)119 void NativeWidgetViewManager::CompositorContentsChanged(
120 const SkBitmap& bitmap) {
121 node_->active_view()->SetContents(bitmap);
122 }
123
OnViewInputEvent(view_manager::View * view,const EventPtr & event)124 void NativeWidgetViewManager::OnViewInputEvent(view_manager::View* view,
125 const EventPtr& event) {
126 scoped_ptr<ui::Event> ui_event(event.To<scoped_ptr<ui::Event> >());
127 if (ui_event.get())
128 window_tree_host_->SendEventToProcessor(ui_event.get());
129 }
130
131 } // namespace mojo
132