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 26namespace mojo { 27namespace { 28 29// TODO: figure out what this should be. 30class 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 43class 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 97NativeWidgetViewManager::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 120NativeWidgetViewManager::~NativeWidgetViewManager() { 121 if (view_) 122 view_->RemoveObserver(this); 123} 124 125void 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 132void NativeWidgetViewManager::CompositorContentsChanged( 133 const SkBitmap& bitmap) { 134 if (view_) 135 view_->SetContents(bitmap); 136} 137 138void NativeWidgetViewManager::OnViewDestroyed(View* view) { 139 DCHECK_EQ(view, view_); 140 view->RemoveObserver(this); 141 view_ = NULL; 142} 143 144void 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 150void 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