| OLD | NEW |
| (Empty) |
| 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/services/window_manager/window_manager_app.h" | |
| 6 | |
| 7 #include "base/message_loop/message_loop.h" | |
| 8 #include "base/stl_util.h" | |
| 9 #include "mojo/converters/geometry/geometry_type_converters.h" | |
| 10 #include "mojo/converters/input_events/input_events_type_converters.h" | |
| 11 #include "mojo/public/cpp/application/application_connection.h" | |
| 12 #include "mojo/public/cpp/application/application_impl.h" | |
| 13 #include "mojo/public/interfaces/application/shell.mojom.h" | |
| 14 #include "mojo/services/public/cpp/view_manager/view.h" | |
| 15 #include "mojo/services/public/cpp/view_manager/view_manager.h" | |
| 16 #include "mojo/services/window_manager/focus_controller.h" | |
| 17 #include "mojo/services/window_manager/focus_rules.h" | |
| 18 #include "mojo/services/window_manager/view_event_dispatcher.h" | |
| 19 #include "mojo/services/window_manager/view_target.h" | |
| 20 #include "mojo/services/window_manager/view_targeter.h" | |
| 21 #include "mojo/services/window_manager/window_manager_delegate.h" | |
| 22 #include "ui/base/hit_test.h" | |
| 23 | |
| 24 namespace mojo { | |
| 25 | |
| 26 namespace { | |
| 27 | |
| 28 Id GetIdForView(View* view) { | |
| 29 return view ? view->id() : 0; | |
| 30 } | |
| 31 | |
| 32 } // namespace | |
| 33 | |
| 34 // Used for calls to Embed() that occur before we've connected to the | |
| 35 // ViewManager. | |
| 36 struct WindowManagerApp::PendingEmbed { | |
| 37 String url; | |
| 38 InterfaceRequest<mojo::ServiceProvider> service_provider; | |
| 39 }; | |
| 40 | |
| 41 //////////////////////////////////////////////////////////////////////////////// | |
| 42 // WindowManagerApp, public: | |
| 43 | |
| 44 WindowManagerApp::WindowManagerApp( | |
| 45 ViewManagerDelegate* view_manager_delegate, | |
| 46 WindowManagerDelegate* window_manager_delegate) | |
| 47 : shell_(nullptr), | |
| 48 native_viewport_event_dispatcher_factory_(this), | |
| 49 wrapped_view_manager_delegate_(view_manager_delegate), | |
| 50 window_manager_delegate_(window_manager_delegate), | |
| 51 view_manager_(nullptr), | |
| 52 root_(nullptr) { | |
| 53 } | |
| 54 | |
| 55 WindowManagerApp::~WindowManagerApp() { | |
| 56 STLDeleteElements(&connections_); | |
| 57 } | |
| 58 | |
| 59 void WindowManagerApp::AddConnection(WindowManagerImpl* connection) { | |
| 60 DCHECK(connections_.find(connection) == connections_.end()); | |
| 61 connections_.insert(connection); | |
| 62 } | |
| 63 | |
| 64 void WindowManagerApp::RemoveConnection(WindowManagerImpl* connection) { | |
| 65 DCHECK(connections_.find(connection) != connections_.end()); | |
| 66 connections_.erase(connection); | |
| 67 } | |
| 68 | |
| 69 void WindowManagerApp::SetCapture(Id view) { | |
| 70 // TODO(erg): Capture. Another pile of worms that is mixed in here. | |
| 71 | |
| 72 // capture_client_->capture_client()->SetCapture(GetWindowForViewId(view)); | |
| 73 | |
| 74 // TODO(beng): notify connected clients that capture has changed, probably | |
| 75 // by implementing some capture-client observer. | |
| 76 } | |
| 77 | |
| 78 void WindowManagerApp::FocusWindow(Id view_id) { | |
| 79 View* view = view_manager_->GetViewById(view_id); | |
| 80 DCHECK(view); | |
| 81 focus_controller_->FocusView(view); | |
| 82 } | |
| 83 | |
| 84 void WindowManagerApp::ActivateWindow(Id view_id) { | |
| 85 View* view = view_manager_->GetViewById(view_id); | |
| 86 DCHECK(view); | |
| 87 focus_controller_->ActivateView(view); | |
| 88 } | |
| 89 | |
| 90 bool WindowManagerApp::IsReady() const { | |
| 91 return view_manager_ && root_; | |
| 92 } | |
| 93 | |
| 94 void WindowManagerApp::InitFocus(scoped_ptr<mojo::FocusRules> rules) { | |
| 95 focus_controller_.reset(new mojo::FocusController(rules.Pass())); | |
| 96 focus_controller_->AddObserver(this); | |
| 97 | |
| 98 DCHECK(root_); | |
| 99 SetFocusController(root_, focus_controller_.get()); | |
| 100 } | |
| 101 | |
| 102 void WindowManagerApp::Embed( | |
| 103 const String& url, | |
| 104 InterfaceRequest<ServiceProvider> service_provider) { | |
| 105 if (view_manager_) { | |
| 106 window_manager_delegate_->Embed(url, service_provider.Pass()); | |
| 107 return; | |
| 108 } | |
| 109 scoped_ptr<PendingEmbed> pending_embed(new PendingEmbed); | |
| 110 pending_embed->url = url; | |
| 111 pending_embed->service_provider = service_provider.Pass(); | |
| 112 pending_embeds_.push_back(pending_embed.release()); | |
| 113 } | |
| 114 | |
| 115 //////////////////////////////////////////////////////////////////////////////// | |
| 116 // WindowManagerApp, ApplicationDelegate implementation: | |
| 117 | |
| 118 void WindowManagerApp::Initialize(ApplicationImpl* impl) { | |
| 119 shell_ = impl->shell(); | |
| 120 LaunchViewManager(impl); | |
| 121 } | |
| 122 | |
| 123 bool WindowManagerApp::ConfigureIncomingConnection( | |
| 124 ApplicationConnection* connection) { | |
| 125 connection->AddService(static_cast<InterfaceFactory<WindowManager>*>(this)); | |
| 126 return true; | |
| 127 } | |
| 128 | |
| 129 //////////////////////////////////////////////////////////////////////////////// | |
| 130 // WindowManagerApp, ViewManagerDelegate implementation: | |
| 131 | |
| 132 void WindowManagerApp::OnEmbed(ViewManager* view_manager, | |
| 133 View* root, | |
| 134 ServiceProviderImpl* exported_services, | |
| 135 scoped_ptr<ServiceProvider> imported_services) { | |
| 136 DCHECK(!view_manager_ && !root_); | |
| 137 view_manager_ = view_manager; | |
| 138 root_ = root; | |
| 139 | |
| 140 view_event_dispatcher_.reset(new ViewEventDispatcher()); | |
| 141 | |
| 142 RegisterSubtree(root_); | |
| 143 | |
| 144 // TODO(erg): Also move the capture client over. | |
| 145 // | |
| 146 // capture_client_.reset( | |
| 147 // new wm::ScopedCaptureClient(window_tree_host_->window())); | |
| 148 | |
| 149 if (wrapped_view_manager_delegate_) { | |
| 150 wrapped_view_manager_delegate_->OnEmbed( | |
| 151 view_manager, root, exported_services, imported_services.Pass()); | |
| 152 } | |
| 153 | |
| 154 for (PendingEmbed* pending_embed : pending_embeds_) | |
| 155 Embed(pending_embed->url, pending_embed->service_provider.Pass()); | |
| 156 pending_embeds_.clear(); | |
| 157 } | |
| 158 | |
| 159 void WindowManagerApp::OnViewManagerDisconnected( | |
| 160 ViewManager* view_manager) { | |
| 161 DCHECK_EQ(view_manager_, view_manager); | |
| 162 if (wrapped_view_manager_delegate_) | |
| 163 wrapped_view_manager_delegate_->OnViewManagerDisconnected(view_manager); | |
| 164 view_manager_ = nullptr; | |
| 165 base::MessageLoop::current()->Quit(); | |
| 166 } | |
| 167 | |
| 168 //////////////////////////////////////////////////////////////////////////////// | |
| 169 // WindowManagerApp, ViewObserver implementation: | |
| 170 | |
| 171 void WindowManagerApp::OnTreeChanged( | |
| 172 const ViewObserver::TreeChangeParams& params) { | |
| 173 if (params.receiver != root_) | |
| 174 return; | |
| 175 DCHECK(params.old_parent || params.new_parent); | |
| 176 if (!params.target) | |
| 177 return; | |
| 178 | |
| 179 if (params.new_parent) { | |
| 180 if (registered_view_id_set_.find(params.target->id()) == | |
| 181 registered_view_id_set_.end()) { | |
| 182 RegisteredViewIdSet::const_iterator it = | |
| 183 registered_view_id_set_.find(params.new_parent->id()); | |
| 184 DCHECK(it != registered_view_id_set_.end()); | |
| 185 RegisterSubtree(params.target); | |
| 186 } | |
| 187 } else if (params.old_parent) { | |
| 188 UnregisterSubtree(params.target); | |
| 189 } | |
| 190 } | |
| 191 | |
| 192 void WindowManagerApp::OnViewDestroying(View* view) { | |
| 193 if (view != root_) { | |
| 194 Unregister(view); | |
| 195 return; | |
| 196 } | |
| 197 root_ = nullptr; | |
| 198 if (focus_controller_) | |
| 199 focus_controller_->RemoveObserver(this); | |
| 200 } | |
| 201 | |
| 202 //////////////////////////////////////////////////////////////////////////////// | |
| 203 // WindowManagerApp, ui::EventHandler implementation: | |
| 204 | |
| 205 void WindowManagerApp::OnEvent(ui::Event* event) { | |
| 206 if (!window_manager_client_) | |
| 207 return; | |
| 208 | |
| 209 View* view = static_cast<ViewTarget*>(event->target())->view(); | |
| 210 if (!view) | |
| 211 return; | |
| 212 | |
| 213 if (focus_controller_) | |
| 214 focus_controller_->OnEvent(event); | |
| 215 | |
| 216 window_manager_client_->DispatchInputEventToView(view->id(), | |
| 217 Event::From(*event)); | |
| 218 } | |
| 219 | |
| 220 //////////////////////////////////////////////////////////////////////////////// | |
| 221 // WindowManagerApp, mojo::FocusControllerObserver implementation: | |
| 222 | |
| 223 void WindowManagerApp::OnViewFocused(View* gained_focus, | |
| 224 View* lost_focus) { | |
| 225 for (Connections::const_iterator it = connections_.begin(); | |
| 226 it != connections_.end(); ++it) { | |
| 227 (*it)->NotifyViewFocused(GetIdForView(gained_focus), | |
| 228 GetIdForView(lost_focus)); | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 void WindowManagerApp::OnViewActivated(View* gained_active, | |
| 233 View* lost_active) { | |
| 234 for (Connections::const_iterator it = connections_.begin(); | |
| 235 it != connections_.end(); ++it) { | |
| 236 (*it)->NotifyWindowActivated(GetIdForView(gained_active), | |
| 237 GetIdForView(lost_active)); | |
| 238 } | |
| 239 if (gained_active) | |
| 240 gained_active->MoveToFront(); | |
| 241 } | |
| 242 | |
| 243 //////////////////////////////////////////////////////////////////////////////// | |
| 244 // WindowManagerApp, private: | |
| 245 | |
| 246 void WindowManagerApp::RegisterSubtree(View* view) { | |
| 247 view->AddObserver(this); | |
| 248 DCHECK(registered_view_id_set_.find(view->id()) == | |
| 249 registered_view_id_set_.end()); | |
| 250 // All events pass through the root during dispatch, so we only need a handler | |
| 251 // installed there. | |
| 252 if (view == root_) { | |
| 253 ViewTarget* target = ViewTarget::TargetFromView(view); | |
| 254 target->SetEventTargeter(scoped_ptr<ViewTargeter>(new ViewTargeter())); | |
| 255 target->AddPreTargetHandler(this); | |
| 256 view_event_dispatcher_->SetRootViewTarget(target); | |
| 257 } | |
| 258 registered_view_id_set_.insert(view->id()); | |
| 259 View::Children::const_iterator it = view->children().begin(); | |
| 260 for (; it != view->children().end(); ++it) | |
| 261 RegisterSubtree(*it); | |
| 262 } | |
| 263 | |
| 264 void WindowManagerApp::UnregisterSubtree(View* view) { | |
| 265 for (View* child : view->children()) | |
| 266 UnregisterSubtree(child); | |
| 267 Unregister(view); | |
| 268 } | |
| 269 | |
| 270 void WindowManagerApp::Unregister(View* view) { | |
| 271 RegisteredViewIdSet::iterator it = registered_view_id_set_.find(view->id()); | |
| 272 if (it == registered_view_id_set_.end()) { | |
| 273 // Because we unregister in OnViewDestroying() we can still get a subsequent | |
| 274 // OnTreeChanged for the same view. Ignore this one. | |
| 275 return; | |
| 276 } | |
| 277 view->RemoveObserver(this); | |
| 278 DCHECK(it != registered_view_id_set_.end()); | |
| 279 registered_view_id_set_.erase(it); | |
| 280 } | |
| 281 | |
| 282 void WindowManagerApp::DispatchInputEventToView(View* view, EventPtr event) { | |
| 283 window_manager_client_->DispatchInputEventToView(view->id(), event.Pass()); | |
| 284 } | |
| 285 | |
| 286 void WindowManagerApp::SetViewportSize(const gfx::Size& size) { | |
| 287 window_manager_client_->SetViewportSize(Size::From(size)); | |
| 288 } | |
| 289 | |
| 290 void WindowManagerApp::LaunchViewManager(ApplicationImpl* app) { | |
| 291 // TODO(sky): figure out logic if this connection goes away. | |
| 292 view_manager_client_factory_.reset( | |
| 293 new ViewManagerClientFactory(shell_, this)); | |
| 294 | |
| 295 MessagePipe pipe; | |
| 296 ApplicationConnection* view_manager_app = | |
| 297 app->ConnectToApplication("mojo:view_manager"); | |
| 298 ServiceProvider* view_manager_service_provider = | |
| 299 view_manager_app->GetServiceProvider(); | |
| 300 view_manager_service_provider->ConnectToService(ViewManagerService::Name_, | |
| 301 pipe.handle1.Pass()); | |
| 302 view_manager_client_ = ViewManagerClientFactory::WeakBindViewManagerToPipe( | |
| 303 pipe.handle0.Pass(), shell_, this).Pass(); | |
| 304 | |
| 305 view_manager_app->AddService(&native_viewport_event_dispatcher_factory_); | |
| 306 view_manager_app->AddService( | |
| 307 static_cast<InterfaceFactory<WindowManagerInternal>*>(this)); | |
| 308 | |
| 309 view_manager_app->ConnectToService(&window_manager_client_); | |
| 310 } | |
| 311 | |
| 312 void WindowManagerApp::Create(ApplicationConnection* connection, | |
| 313 InterfaceRequest<WindowManagerInternal> request) { | |
| 314 if (wm_internal_binding_.get()) { | |
| 315 VLOG(1) << | |
| 316 "WindowManager allows only one WindowManagerInternal connection."; | |
| 317 return; | |
| 318 } | |
| 319 wm_internal_binding_.reset( | |
| 320 new Binding<WindowManagerInternal>(this, request.Pass())); | |
| 321 } | |
| 322 | |
| 323 void WindowManagerApp::Create(ApplicationConnection* connection, | |
| 324 InterfaceRequest<WindowManager> request) { | |
| 325 WindowManagerImpl* wm = new WindowManagerImpl(this, false); | |
| 326 wm->Bind(request.PassMessagePipe()); | |
| 327 // WindowManagerImpl is deleted when the connection has an error, or from our | |
| 328 // destructor. | |
| 329 } | |
| 330 | |
| 331 void WindowManagerApp::CreateWindowManagerForViewManagerClient( | |
| 332 uint16_t connection_id, | |
| 333 ScopedMessagePipeHandle window_manager_pipe) { | |
| 334 WindowManagerImpl* wm = new WindowManagerImpl(this, true); | |
| 335 wm->Bind(window_manager_pipe.Pass()); | |
| 336 // WindowManagerImpl is deleted when the connection has an error, or from our | |
| 337 // destructor. | |
| 338 } | |
| 339 | |
| 340 } // namespace mojo | |
| OLD | NEW |