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