OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/mus/root_window_controller.h" | 5 #include "ash/mus/root_window_controller.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
11 #include <sstream> | 11 #include <sstream> |
12 #include <string> | 12 #include <string> |
13 #include <utility> | 13 #include <utility> |
14 #include <vector> | 14 #include <vector> |
15 | 15 |
16 #include "ash/common/shelf/shelf_layout_manager.h" | 16 #include "ash/common/shelf/shelf_layout_manager.h" |
17 #include "ash/common/wm/container_finder.h" | 17 #include "ash/common/wm/container_finder.h" |
18 #include "ash/common/wm/dock/docked_window_layout_manager.h" | 18 #include "ash/common/wm/dock/docked_window_layout_manager.h" |
19 #include "ash/common/wm/panels/panel_layout_manager.h" | 19 #include "ash/common/wm/panels/panel_layout_manager.h" |
20 #include "ash/common/wm/root_window_layout_manager.h" | 20 #include "ash/common/wm/root_window_layout_manager.h" |
21 #include "ash/mus/bridge/wm_root_window_controller_mus.h" | 21 #include "ash/mus/bridge/wm_root_window_controller_mus.h" |
22 #include "ash/mus/bridge/wm_shelf_mus.h" | 22 #include "ash/mus/bridge/wm_shelf_mus.h" |
23 #include "ash/mus/bridge/wm_shell_mus.h" | 23 #include "ash/mus/bridge/wm_shell_mus.h" |
24 #include "ash/mus/bridge/wm_window_mus.h" | 24 #include "ash/mus/bridge/wm_window_mus.h" |
25 #include "ash/mus/non_client_frame_controller.h" | 25 #include "ash/mus/non_client_frame_controller.h" |
26 #include "ash/mus/property_util.h" | 26 #include "ash/mus/property_util.h" |
27 #include "ash/mus/screenlock_layout.h" | 27 #include "ash/mus/screen_mus.h" |
28 #include "ash/mus/window_manager.h" | 28 #include "ash/mus/window_manager.h" |
29 #include "ash/public/cpp/shell_window_ids.h" | 29 #include "ash/public/cpp/shell_window_ids.h" |
30 #include "ash/wm/stacking_controller.h" | |
30 #include "base/bind.h" | 31 #include "base/bind.h" |
31 #include "base/command_line.h" | 32 #include "base/command_line.h" |
32 #include "base/memory/ptr_util.h" | 33 #include "base/memory/ptr_util.h" |
33 #include "mojo/public/cpp/bindings/type_converter.h" | 34 #include "mojo/public/cpp/bindings/type_converter.h" |
34 #include "services/service_manager/public/cpp/connector.h" | 35 #include "services/service_manager/public/cpp/connector.h" |
35 #include "services/ui/common/switches.h" | 36 #include "services/ui/common/switches.h" |
36 #include "services/ui/common/util.h" | 37 #include "services/ui/common/util.h" |
37 #include "services/ui/public/cpp/property_type_converters.h" | 38 #include "ui/aura/client/aura_constants.h" |
38 #include "services/ui/public/cpp/window.h" | 39 #include "ui/aura/mus/property_converter.h" |
39 #include "services/ui/public/cpp/window_property.h" | 40 #include "ui/aura/mus/property_utils.h" |
40 #include "services/ui/public/cpp/window_tree_client.h" | 41 #include "ui/aura/mus/window_tree_client.h" |
42 #include "ui/aura/mus/window_tree_host_mus.h" | |
43 #include "ui/aura/window.h" | |
44 #include "ui/base/ui_base_types.h" | |
41 #include "ui/display/display_list.h" | 45 #include "ui/display/display_list.h" |
42 #include "ui/display/screen_base.h" | |
43 | 46 |
44 namespace ash { | 47 namespace ash { |
45 namespace mus { | 48 namespace mus { |
46 | 49 |
47 RootWindowController::RootWindowController(WindowManager* window_manager, | 50 RootWindowController::RootWindowController( |
48 ui::Window* root, | 51 WindowManager* window_manager, |
49 const display::Display& display) | 52 std::unique_ptr<aura::WindowTreeHostMus> window_tree_host, |
53 const display::Display& display) | |
50 : window_manager_(window_manager), | 54 : window_manager_(window_manager), |
51 root_(root), | 55 window_tree_host_(std::move(window_tree_host)), |
52 window_count_(0), | 56 window_count_(0), |
53 display_(display), | 57 display_(display), |
54 wm_shelf_(base::MakeUnique<WmShelfMus>()) { | 58 wm_shelf_(base::MakeUnique<WmShelfMus>()) { |
55 wm_root_window_controller_ = base::MakeUnique<WmRootWindowControllerMus>( | 59 wm_root_window_controller_ = base::MakeUnique<WmRootWindowControllerMus>( |
56 window_manager_->shell(), this); | 60 window_manager_->shell(), this); |
57 wm_root_window_controller_->CreateContainers(); | 61 wm_root_window_controller_->CreateContainers(); |
58 wm_root_window_controller_->CreateLayoutManagers(); | 62 wm_root_window_controller_->CreateLayoutManagers(); |
59 CreateLayoutManagers(); | |
60 | 63 |
61 disconnected_app_handler_.reset(new DisconnectedAppHandler(root)); | 64 parenting_client_ = base::MakeUnique<StackingController>(); |
65 aura::client::SetWindowParentingClient(root(), parenting_client_.get()); | |
66 | |
67 disconnected_app_handler_.reset(new DisconnectedAppHandler(root())); | |
62 | 68 |
63 // Force a layout of the root, and its children, RootWindowLayout handles | 69 // Force a layout of the root, and its children, RootWindowLayout handles |
64 // both. | 70 // both. |
65 wm_root_window_controller_->root_window_layout_manager()->OnWindowResized(); | 71 wm_root_window_controller_->root_window_layout_manager()->OnWindowResized(); |
66 | 72 |
67 for (size_t i = 0; i < kNumActivatableShellWindowIds; ++i) { | 73 for (size_t i = 0; i < kNumActivatableShellWindowIds; ++i) { |
68 window_manager_->window_manager_client()->AddActivationParent( | 74 window_manager_->window_manager_client()->AddActivationParent( |
69 GetWindowByShellWindowId(kActivatableShellWindowIds[i])->mus_window()); | 75 GetWindowByShellWindowId(kActivatableShellWindowIds[i])->aura_window()); |
70 } | 76 } |
71 } | 77 } |
72 | 78 |
73 RootWindowController::~RootWindowController() { | 79 RootWindowController::~RootWindowController() { |
74 Shutdown(); | 80 Shutdown(); |
75 root_->Destroy(); | 81 wm_shelf_.reset(); |
James Cook
2016/12/05 19:21:44
I presume there's an ordering dependency in destru
sky
2016/12/05 21:39:20
Done.
| |
82 wm_root_window_controller_.reset(); | |
83 window_tree_host_.reset(); | |
76 } | 84 } |
77 | 85 |
78 void RootWindowController::Shutdown() { | 86 void RootWindowController::Shutdown() { |
79 // NOTE: Shutdown() may be called multiple times. | 87 // NOTE: Shutdown() may be called multiple times. |
80 wm_root_window_controller_->ResetRootForNewWindowsIfNecessary(); | 88 wm_root_window_controller_->ResetRootForNewWindowsIfNecessary(); |
81 wm_root_window_controller_->CloseChildWindows(); | 89 wm_root_window_controller_->CloseChildWindows(); |
82 } | 90 } |
83 | 91 |
84 service_manager::Connector* RootWindowController::GetConnector() { | 92 service_manager::Connector* RootWindowController::GetConnector() { |
85 return window_manager_->connector(); | 93 return window_manager_->connector(); |
86 } | 94 } |
87 | 95 |
88 ui::Window* RootWindowController::NewTopLevelWindow( | 96 aura::Window* RootWindowController::root() { |
97 return window_tree_host_->window(); | |
98 } | |
99 | |
100 const aura::Window* RootWindowController::root() const { | |
101 return window_tree_host_->window(); | |
102 } | |
103 | |
104 aura::Window* RootWindowController::NewTopLevelWindow( | |
105 ui::mojom::WindowType window_type, | |
89 std::map<std::string, std::vector<uint8_t>>* properties) { | 106 std::map<std::string, std::vector<uint8_t>>* properties) { |
90 const bool provide_non_client_frame = | 107 // TODO(sky): constrain and validate properties. |
91 GetWindowType(*properties) == ui::mojom::WindowType::WINDOW || | |
92 GetWindowType(*properties) == ui::mojom::WindowType::PANEL; | |
93 if (provide_non_client_frame) | |
94 (*properties)[ui::mojom::kWaitForUnderlay_Property].clear(); | |
95 | 108 |
96 // TODO(sky): constrain and validate properties before passing to server. | 109 int32_t container_id = kShellWindowId_Invalid; |
97 ui::Window* window = root_->window_tree()->NewWindow(properties); | 110 aura::Window* context = nullptr; |
98 window->SetBounds(CalculateDefaultBounds(window)); | 111 aura::Window* container_window = nullptr; |
99 | 112 if (GetInitialContainerId(*properties, &container_id)) { |
100 ui::Window* container_window = nullptr; | 113 container_window = GetWindowByShellWindowId(container_id)->aura_window(); |
101 int container_id = kShellWindowId_Invalid; | |
102 if (GetRequestedContainer(window, &container_id)) { | |
103 container_window = GetWindowByShellWindowId(container_id)->mus_window(); | |
104 } else { | 114 } else { |
105 gfx::Point origin = wm_root_window_controller_->ConvertPointToScreen( | 115 context = window_tree_host_->window(); |
James Cook
2016/12/05 19:21:44
Using root() here might be a little clearer.
sky
2016/12/05 21:39:19
Done.
| |
106 WmWindowMus::Get(root_), gfx::Point()); | |
107 gfx::Rect bounds_in_screen(origin, window->bounds().size()); | |
108 container_window = WmWindowMus::GetMusWindow(wm::GetDefaultParent( | |
109 WmWindowMus::Get(root_), WmWindowMus::Get(window), bounds_in_screen)); | |
110 } | |
111 DCHECK(WmWindowMus::Get(container_window)->IsContainer()); | |
112 | |
113 if (provide_non_client_frame) { | |
114 NonClientFrameController::Create(container_window, window, | |
115 window_manager_->window_manager_client()); | |
116 } else { | |
117 container_window->AddChild(window); | |
118 } | 116 } |
119 | 117 |
118 gfx::Rect bounds = CalculateDefaultBounds(container_window, properties); | |
120 window_count_++; | 119 window_count_++; |
121 | 120 |
121 const bool provide_non_client_frame = | |
122 window_type == ui::mojom::WindowType::WINDOW || | |
123 window_type == ui::mojom::WindowType::PANEL; | |
124 if (provide_non_client_frame) { | |
125 (*properties)[ui::mojom::kWaitForUnderlay_Property].clear(); | |
James Cook
2016/12/05 19:21:44
I know you didn't change this, but what's it for /
sky
2016/12/05 21:39:20
It's for mus to make sure mus has both parts of th
| |
126 // See NonClientFrameController for details on lifetime. | |
127 NonClientFrameController* non_client_frame_controller = | |
128 new NonClientFrameController(container_window, context, bounds, | |
129 window_type, properties, window_manager_); | |
130 return non_client_frame_controller->window(); | |
131 } | |
132 | |
133 aura::Window* window = new aura::Window(nullptr); | |
134 aura::SetWindowType(window, window_type); | |
135 // Apply properties before Init(), that way they are sent to the server at | |
136 // the time the window is created. | |
137 aura::PropertyConverter* property_converter = | |
138 window_manager_->property_converter(); | |
139 for (auto& property_pair : *properties) { | |
140 property_converter->SetPropertyFromTransportValue( | |
141 window, property_pair.first, &property_pair.second); | |
142 } | |
143 window->Init(ui::LAYER_TEXTURED); | |
144 window->SetBounds(bounds); | |
145 | |
146 if (container_window) { | |
147 container_window->AddChild(window); | |
148 } else { | |
149 WmWindowMus* root = WmWindowMus::Get(window_tree_host_->window()); | |
James Cook
2016/12/05 19:21:44
ditto, might be clearer to call root()
sky
2016/12/05 21:39:19
Done.
| |
150 gfx::Point origin = | |
151 wm_root_window_controller_->ConvertPointToScreen(root, gfx::Point()); | |
152 gfx::Rect bounds_in_screen(origin, bounds.size()); | |
153 static_cast<WmWindowMus*>( | |
154 ash::wm::GetDefaultParent(WmWindowMus::Get(context), | |
155 WmWindowMus::Get(window), bounds_in_screen)) | |
156 ->aura_window() | |
157 ->AddChild(window); | |
158 } | |
122 return window; | 159 return window; |
123 } | 160 } |
124 | 161 |
125 WmWindowMus* RootWindowController::GetWindowByShellWindowId(int id) { | 162 WmWindowMus* RootWindowController::GetWindowByShellWindowId(int id) { |
126 return WmWindowMus::AsWmWindowMus( | 163 return WmWindowMus::AsWmWindowMus( |
127 WmWindowMus::Get(root_)->GetChildByShellWindowId(id)); | 164 WmWindowMus::Get(root())->GetChildByShellWindowId(id)); |
128 } | 165 } |
129 | 166 |
130 void RootWindowController::SetWorkAreaInests(const gfx::Insets& insets) { | 167 void RootWindowController::SetWorkAreaInests(const gfx::Insets& insets) { |
131 gfx::Rect old_work_area = display_.work_area(); | 168 gfx::Rect old_work_area = display_.work_area(); |
132 display_.UpdateWorkAreaFromInsets(insets); | 169 display_.UpdateWorkAreaFromInsets(insets); |
133 | 170 |
134 if (old_work_area == display_.work_area()) | 171 if (old_work_area == display_.work_area()) |
135 return; | 172 return; |
136 | 173 |
137 window_manager_->screen()->display_list().UpdateDisplay(display_); | 174 window_manager_->screen()->display_list().UpdateDisplay(display_); |
138 | 175 |
139 // Push new display insets to service:ui if we have a connection. | 176 // Push new display insets to service:ui if we have a connection. |
140 auto* display_controller = window_manager_->GetDisplayController(); | 177 auto* display_controller = window_manager_->GetDisplayController(); |
141 if (display_controller) | 178 if (display_controller) |
142 display_controller->SetDisplayWorkArea(display_.id(), | 179 display_controller->SetDisplayWorkArea(display_.id(), |
143 display_.bounds().size(), insets); | 180 display_.bounds().size(), insets); |
144 } | 181 } |
145 | 182 |
146 void RootWindowController::SetDisplay(const display::Display& display) { | 183 void RootWindowController::SetDisplay(const display::Display& display) { |
147 DCHECK_EQ(display.id(), display_.id()); | 184 DCHECK_EQ(display.id(), display_.id()); |
148 display_ = display; | 185 display_ = display; |
149 window_manager_->screen()->display_list().UpdateDisplay(display_); | 186 window_manager_->screen()->display_list().UpdateDisplay(display_); |
150 } | 187 } |
151 | 188 |
152 gfx::Rect RootWindowController::CalculateDefaultBounds( | 189 gfx::Rect RootWindowController::CalculateDefaultBounds( |
153 ui::Window* window) const { | 190 aura::Window* container_window, |
154 if (window->HasSharedProperty( | 191 const std::map<std::string, std::vector<uint8_t>>* properties) const { |
155 ui::mojom::WindowManager::kInitialBounds_Property)) { | 192 gfx::Rect requested_bounds; |
156 return window->GetSharedProperty<gfx::Rect>( | 193 if (GetInitialBounds(*properties, &requested_bounds)) |
157 ui::mojom::WindowManager::kInitialBounds_Property); | 194 return requested_bounds; |
158 } | |
159 | 195 |
160 if (GetWindowShowState(window) == ui::mojom::ShowState::FULLSCREEN) { | 196 auto show_state_iter = |
161 return gfx::Rect(0, 0, root_->bounds().width(), root_->bounds().height()); | 197 properties->find(ui::mojom::WindowManager::kShowState_Property); |
198 if (show_state_iter != properties->end()) { | |
199 aura::PropertyConverter::PrimitiveType show_state = 0; | |
200 if (window_manager_->property_converter() | |
201 ->GetPropertyValueFromTransportValue( | |
202 ui::mojom::WindowManager::kShowState_Property, | |
203 show_state_iter->second, &show_state) && | |
204 static_cast<ui::WindowShowState>(show_state) == | |
205 ui::SHOW_STATE_FULLSCREEN) { | |
James Cook
2016/12/05 19:21:44
nit: This if() is ugly. Would it help to cache pro
sky
2016/12/05 21:39:19
Well, I made this function easier to parse, but I'
James Cook
2016/12/05 22:56:34
Better, one other idea above.
| |
206 gfx::Rect bounds(0, 0, root()->bounds().width(), | |
207 root()->bounds().height()); | |
208 if (!container_window) { | |
James Cook
2016/12/05 19:21:44
Why is fullscreen not using the root window bounds
sky
2016/12/05 21:39:19
It's because of differences in how NativeWidgetAur
| |
209 bounds.Offset(display_.bounds().origin().x(), | |
210 display_.bounds().origin().y()); | |
211 } | |
212 return bounds; | |
213 } | |
162 } | 214 } |
163 | 215 |
164 int width, height; | 216 int width, height; |
165 const gfx::Size pref = GetWindowPreferredSize(window); | 217 gfx::Size pref; |
166 if (pref.IsEmpty()) { | 218 if (GetWindowPreferredSize(*properties, &pref) && !pref.IsEmpty()) { |
167 width = root_->bounds().width() - 240; | |
168 height = root_->bounds().height() - 240; | |
169 } else { | |
170 // TODO(sky): likely want to constrain more than root size. | 219 // TODO(sky): likely want to constrain more than root size. |
171 const gfx::Size max_size = root_->bounds().size(); | 220 const gfx::Size max_size = root()->bounds().size(); |
172 width = std::max(0, std::min(max_size.width(), pref.width())); | 221 width = std::max(0, std::min(max_size.width(), pref.width())); |
173 height = std::max(0, std::min(max_size.height(), pref.height())); | 222 height = std::max(0, std::min(max_size.height(), pref.height())); |
223 } else { | |
224 width = root()->bounds().width() - 240; | |
225 height = root()->bounds().height() - 240; | |
174 } | 226 } |
175 return gfx::Rect(40 + (window_count_ % 4) * 40, 40 + (window_count_ % 4) * 40, | 227 return gfx::Rect(40 + (window_count_ % 4) * 40, 40 + (window_count_ % 4) * 40, |
176 width, height); | 228 width, height); |
177 } | 229 } |
178 | 230 |
179 void RootWindowController::CreateLayoutManagers() { | |
180 // Override the default layout managers for certain containers. | |
181 WmWindowMus* lock_screen_container = | |
182 GetWindowByShellWindowId(kShellWindowId_LockScreenContainer); | |
183 layout_managers_[lock_screen_container->mus_window()].reset( | |
184 new ScreenlockLayout(lock_screen_container->mus_window())); | |
185 } | |
186 | |
187 } // namespace mus | 231 } // namespace mus |
188 } // namespace ash | 232 } // namespace ash |
OLD | NEW |