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.
5 #include "mojo/services/view_manager/display_manager.h"
7 #include "base/auto_reset.h"
8 #include "base/scoped_observer.h"
9 #include "mojo/public/cpp/application/application_connection.h"
10 #include "mojo/services/public/interfaces/gpu/gpu.mojom.h"
11 #include "mojo/services/view_manager/connection_manager.h"
12 #include "mojo/services/view_manager/display_manager_delegate.h"
13 #include "mojo/services/view_manager/screen_impl.h"
14 #include "mojo/services/view_manager/window_tree_host_impl.h"
15 #include "ui/aura/client/default_capture_client.h"
16 #include "ui/aura/client/focus_client.h"
17 #include "ui/aura/client/window_tree_client.h"
18 #include "ui/aura/window.h"
19 #include "ui/aura/window_delegate.h"
20 #include "ui/base/cursor/cursor.h"
21 #include "ui/base/hit_test.h"
22 #include "ui/compositor/layer.h"
23 #include "ui/gfx/canvas.h"
24 #include "ui/gfx/image/image_skia.h"
25 #include "ui/gfx/native_widget_types.h"
31 gfx::Rect
ConvertRectToRoot(const ServerView
* view
, const gfx::Rect
& bounds
) {
32 gfx::Point
origin(bounds
.origin());
33 while (view
->parent()) {
34 origin
+= view
->bounds().OffsetFromOrigin();
35 view
= view
->parent();
37 return gfx::Rect(origin
, bounds
.size());
40 void PaintViewTree(gfx::Canvas
* canvas
,
41 const ServerView
* view
,
42 const gfx::Point
& origin
) {
46 canvas
->DrawImageInt(gfx::ImageSkia::CreateFrom1xBitmap(view
->bitmap()),
49 std::vector
<const ServerView
*> children(view
->GetChildren());
50 for (size_t i
= 0; i
< children
.size(); ++i
) {
52 canvas
, children
[i
], origin
+ children
[i
]->bounds().OffsetFromOrigin());
58 class DisplayManager::RootWindowDelegateImpl
: public aura::WindowDelegate
{
60 explicit RootWindowDelegateImpl(const ServerView
* root_view
)
61 : root_view_(root_view
) {}
62 virtual ~RootWindowDelegateImpl() {}
64 // aura::WindowDelegate:
65 virtual gfx::Size
GetMinimumSize() const OVERRIDE
{
68 virtual gfx::Size
GetMaximumSize() const OVERRIDE
{
71 virtual void OnBoundsChanged(const gfx::Rect
& old_bounds
,
72 const gfx::Rect
& new_bounds
) OVERRIDE
{
74 virtual gfx::NativeCursor
GetCursor(const gfx::Point
& point
) OVERRIDE
{
75 return gfx::kNullCursor
;
77 virtual int GetNonClientComponent(const gfx::Point
& point
) const OVERRIDE
{
80 virtual bool ShouldDescendIntoChildForEventHandling(
82 const gfx::Point
& location
) OVERRIDE
{
85 virtual bool CanFocus() OVERRIDE
{
88 virtual void OnCaptureLost() OVERRIDE
{
90 virtual void OnPaint(gfx::Canvas
* canvas
) OVERRIDE
{
91 PaintViewTree(canvas
, root_view_
, gfx::Point());
93 virtual void OnDeviceScaleFactorChanged(float device_scale_factor
) OVERRIDE
{
95 virtual void OnWindowDestroying(aura::Window
* window
) OVERRIDE
{
97 virtual void OnWindowDestroyed(aura::Window
* window
) OVERRIDE
{
99 virtual void OnWindowTargetVisibilityChanged(bool visible
) OVERRIDE
{
101 virtual bool HasHitTestMask() const OVERRIDE
{
104 virtual void GetHitTestMask(gfx::Path
* mask
) const OVERRIDE
{
108 const ServerView
* root_view_
;
110 DISALLOW_COPY_AND_ASSIGN(RootWindowDelegateImpl
);
113 // TODO(sky): Remove once aura is removed from the service.
114 class FocusClientImpl
: public aura::client::FocusClient
{
117 virtual ~FocusClientImpl() {}
120 // Overridden from aura::client::FocusClient:
121 virtual void AddObserver(
122 aura::client::FocusChangeObserver
* observer
) OVERRIDE
{}
123 virtual void RemoveObserver(
124 aura::client::FocusChangeObserver
* observer
) OVERRIDE
{}
125 virtual void FocusWindow(aura::Window
* window
) OVERRIDE
{}
126 virtual void ResetFocusWithinActiveWindow(aura::Window
* window
) OVERRIDE
{}
127 virtual aura::Window
* GetFocusedWindow() OVERRIDE
{ return NULL
; }
129 DISALLOW_COPY_AND_ASSIGN(FocusClientImpl
);
132 class WindowTreeClientImpl
: public aura::client::WindowTreeClient
{
134 explicit WindowTreeClientImpl(aura::Window
* window
) : window_(window
) {
135 aura::client::SetWindowTreeClient(window_
, this);
138 virtual ~WindowTreeClientImpl() {
139 aura::client::SetWindowTreeClient(window_
, NULL
);
142 // Overridden from aura::client::WindowTreeClient:
143 virtual aura::Window
* GetDefaultParent(aura::Window
* context
,
144 aura::Window
* window
,
145 const gfx::Rect
& bounds
) OVERRIDE
{
146 if (!capture_client_
) {
147 capture_client_
.reset(
148 new aura::client::DefaultCaptureClient(window_
->GetRootWindow()));
154 aura::Window
* window_
;
156 scoped_ptr
<aura::client::DefaultCaptureClient
> capture_client_
;
158 DISALLOW_COPY_AND_ASSIGN(WindowTreeClientImpl
);
161 DisplayManager::DisplayManager(
162 ApplicationConnection
* app_connection
,
163 ConnectionManager
* connection_manager
,
164 DisplayManagerDelegate
* delegate
,
165 const Callback
<void()>& native_viewport_closed_callback
)
166 : delegate_(delegate
),
167 connection_manager_(connection_manager
),
170 screen_
.reset(ScreenImpl::Create());
171 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, screen_
.get());
172 NativeViewportPtr viewport
;
173 app_connection
->ConnectToService(
174 "mojo:mojo_native_viewport_service", &viewport
);
176 // TODO(jamesr): Should be mojo:mojo_gpu_service
177 app_connection
->ConnectToService("mojo:mojo_native_viewport_service",
179 window_tree_host_
.reset(new WindowTreeHostImpl(
183 base::Bind(&DisplayManager::OnCompositorCreated
, base::Unretained(this)),
184 native_viewport_closed_callback
,
185 base::Bind(&ConnectionManager::DispatchViewInputEventToWindowManager
,
186 base::Unretained(connection_manager_
))));
189 DisplayManager::~DisplayManager() {
190 window_tree_client_
.reset();
191 window_tree_host_
.reset();
192 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, NULL
);
195 void DisplayManager::SchedulePaint(const ServerView
* view
,
196 const gfx::Rect
& bounds
) {
198 root_window_
->SchedulePaintInRect(ConvertRectToRoot(view
, bounds
));
201 void DisplayManager::OnCompositorCreated() {
202 base::AutoReset
<bool> resetter(&in_setup_
, true);
203 window_tree_host_
->InitHost();
205 window_delegate_
.reset(
206 new RootWindowDelegateImpl(connection_manager_
->root()));
207 root_window_
= new aura::Window(window_delegate_
.get());
208 root_window_
->Init(aura::WINDOW_LAYER_TEXTURED
);
209 root_window_
->Show();
210 root_window_
->SetBounds(
211 gfx::Rect(window_tree_host_
->window()->bounds().size()));
212 window_tree_host_
->window()->AddChild(root_window_
);
214 connection_manager_
->root()->SetBounds(
215 gfx::Rect(window_tree_host_
->window()->bounds().size()));
217 window_tree_client_
.reset(
218 new WindowTreeClientImpl(window_tree_host_
->window()));
220 focus_client_
.reset(new FocusClientImpl
);
221 aura::client::SetFocusClient(window_tree_host_
->window(),
222 focus_client_
.get());
224 window_tree_host_
->Show();
226 delegate_
->OnDisplayManagerWindowTreeHostCreated();
229 } // namespace service