Chromium Code Reviews| 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 { |
| 49 namespace { | |
| 46 | 50 |
| 47 RootWindowController::RootWindowController(WindowManager* window_manager, | 51 bool IsFullscreen(aura::PropertyConverter* property_converter, |
| 48 ui::Window* root, | 52 const std::vector<uint8_t>& transport_data) { |
| 49 const display::Display& display) | 53 using ui::mojom::WindowManager; |
| 54 aura::PropertyConverter::PrimitiveType show_state = 0; | |
| 55 return property_converter->GetPropertyValueFromTransportValue( | |
|
James Cook
2016/12/05 22:56:34
if (!property_converter->....)
return false;
ret
sky
2016/12/06 00:56:16
I thought if that as well, but I think which you l
| |
| 56 WindowManager::kShowState_Property, transport_data, &show_state) && | |
| 57 (static_cast<ui::WindowShowState>(show_state) == | |
| 58 ui::SHOW_STATE_FULLSCREEN); | |
| 59 } | |
| 60 | |
| 61 } // namespace | |
| 62 | |
| 63 RootWindowController::RootWindowController( | |
| 64 WindowManager* window_manager, | |
| 65 std::unique_ptr<aura::WindowTreeHostMus> window_tree_host, | |
| 66 const display::Display& display) | |
| 50 : window_manager_(window_manager), | 67 : window_manager_(window_manager), |
| 51 root_(root), | 68 window_tree_host_(std::move(window_tree_host)), |
| 52 window_count_(0), | 69 window_count_(0), |
| 53 display_(display), | 70 display_(display), |
| 54 wm_shelf_(base::MakeUnique<WmShelfMus>()) { | 71 wm_shelf_(base::MakeUnique<WmShelfMus>()) { |
| 55 wm_root_window_controller_ = base::MakeUnique<WmRootWindowControllerMus>( | 72 wm_root_window_controller_ = base::MakeUnique<WmRootWindowControllerMus>( |
| 56 window_manager_->shell(), this); | 73 window_manager_->shell(), this); |
| 57 wm_root_window_controller_->CreateContainers(); | 74 wm_root_window_controller_->CreateContainers(); |
| 58 wm_root_window_controller_->CreateLayoutManagers(); | 75 wm_root_window_controller_->CreateLayoutManagers(); |
| 59 CreateLayoutManagers(); | |
| 60 | 76 |
| 61 disconnected_app_handler_.reset(new DisconnectedAppHandler(root)); | 77 parenting_client_ = base::MakeUnique<StackingController>(); |
| 78 aura::client::SetWindowParentingClient(root(), parenting_client_.get()); | |
| 79 | |
| 80 disconnected_app_handler_.reset(new DisconnectedAppHandler(root())); | |
| 62 | 81 |
| 63 // Force a layout of the root, and its children, RootWindowLayout handles | 82 // Force a layout of the root, and its children, RootWindowLayout handles |
| 64 // both. | 83 // both. |
| 65 wm_root_window_controller_->root_window_layout_manager()->OnWindowResized(); | 84 wm_root_window_controller_->root_window_layout_manager()->OnWindowResized(); |
| 66 | 85 |
| 67 for (size_t i = 0; i < kNumActivatableShellWindowIds; ++i) { | 86 for (size_t i = 0; i < kNumActivatableShellWindowIds; ++i) { |
| 68 window_manager_->window_manager_client()->AddActivationParent( | 87 window_manager_->window_manager_client()->AddActivationParent( |
| 69 GetWindowByShellWindowId(kActivatableShellWindowIds[i])->mus_window()); | 88 GetWindowByShellWindowId(kActivatableShellWindowIds[i])->aura_window()); |
| 70 } | 89 } |
| 71 } | 90 } |
| 72 | 91 |
| 73 RootWindowController::~RootWindowController() { | 92 RootWindowController::~RootWindowController() { |
| 74 Shutdown(); | 93 Shutdown(); |
| 75 root_->Destroy(); | 94 // Destroy WindowTreeHost last as it owns the root Window. |
| 95 wm_shelf_.reset(); | |
| 96 wm_root_window_controller_.reset(); | |
| 97 window_tree_host_.reset(); | |
| 76 } | 98 } |
| 77 | 99 |
| 78 void RootWindowController::Shutdown() { | 100 void RootWindowController::Shutdown() { |
| 79 // NOTE: Shutdown() may be called multiple times. | 101 // NOTE: Shutdown() may be called multiple times. |
| 80 wm_root_window_controller_->ResetRootForNewWindowsIfNecessary(); | 102 wm_root_window_controller_->ResetRootForNewWindowsIfNecessary(); |
| 81 wm_root_window_controller_->CloseChildWindows(); | 103 wm_root_window_controller_->CloseChildWindows(); |
| 82 } | 104 } |
| 83 | 105 |
| 84 service_manager::Connector* RootWindowController::GetConnector() { | 106 service_manager::Connector* RootWindowController::GetConnector() { |
| 85 return window_manager_->connector(); | 107 return window_manager_->connector(); |
| 86 } | 108 } |
| 87 | 109 |
| 88 ui::Window* RootWindowController::NewTopLevelWindow( | 110 aura::Window* RootWindowController::root() { |
| 111 return window_tree_host_->window(); | |
| 112 } | |
| 113 | |
| 114 const aura::Window* RootWindowController::root() const { | |
| 115 return window_tree_host_->window(); | |
| 116 } | |
| 117 | |
| 118 aura::Window* RootWindowController::NewTopLevelWindow( | |
| 119 ui::mojom::WindowType window_type, | |
| 89 std::map<std::string, std::vector<uint8_t>>* properties) { | 120 std::map<std::string, std::vector<uint8_t>>* properties) { |
| 121 // TODO(sky): constrain and validate properties. | |
| 122 | |
| 123 int32_t container_id = kShellWindowId_Invalid; | |
| 124 aura::Window* context = nullptr; | |
| 125 aura::Window* container_window = nullptr; | |
| 126 if (GetInitialContainerId(*properties, &container_id)) | |
| 127 container_window = GetWindowByShellWindowId(container_id)->aura_window(); | |
| 128 else | |
| 129 context = root(); | |
| 130 | |
| 131 gfx::Rect bounds = CalculateDefaultBounds(container_window, properties); | |
| 132 window_count_++; | |
| 133 | |
| 90 const bool provide_non_client_frame = | 134 const bool provide_non_client_frame = |
| 91 GetWindowType(*properties) == ui::mojom::WindowType::WINDOW || | 135 window_type == ui::mojom::WindowType::WINDOW || |
| 92 GetWindowType(*properties) == ui::mojom::WindowType::PANEL; | 136 window_type == ui::mojom::WindowType::PANEL; |
| 93 if (provide_non_client_frame) | 137 if (provide_non_client_frame) { |
| 94 (*properties)[ui::mojom::kWaitForUnderlay_Property].clear(); | 138 (*properties)[ui::mojom::kWaitForUnderlay_Property].clear(); |
| 95 | 139 // See NonClientFrameController for details on lifetime. |
| 96 // TODO(sky): constrain and validate properties before passing to server. | 140 NonClientFrameController* non_client_frame_controller = |
| 97 ui::Window* window = root_->window_tree()->NewWindow(properties); | 141 new NonClientFrameController(container_window, context, bounds, |
| 98 window->SetBounds(CalculateDefaultBounds(window)); | 142 window_type, properties, window_manager_); |
| 99 | 143 return non_client_frame_controller->window(); |
| 100 ui::Window* container_window = nullptr; | |
| 101 int container_id = kShellWindowId_Invalid; | |
| 102 if (GetRequestedContainer(window, &container_id)) { | |
| 103 container_window = GetWindowByShellWindowId(container_id)->mus_window(); | |
| 104 } else { | |
| 105 gfx::Point origin = wm_root_window_controller_->ConvertPointToScreen( | |
| 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 } | 144 } |
| 119 | 145 |
| 120 window_count_++; | 146 aura::Window* window = new aura::Window(nullptr); |
| 147 aura::SetWindowType(window, window_type); | |
| 148 // Apply properties before Init(), that way they are sent to the server at | |
| 149 // the time the window is created. | |
| 150 aura::PropertyConverter* property_converter = | |
| 151 window_manager_->property_converter(); | |
| 152 for (auto& property_pair : *properties) { | |
| 153 property_converter->SetPropertyFromTransportValue( | |
| 154 window, property_pair.first, &property_pair.second); | |
| 155 } | |
| 156 window->Init(ui::LAYER_TEXTURED); | |
| 157 window->SetBounds(bounds); | |
| 121 | 158 |
| 159 if (container_window) { | |
| 160 container_window->AddChild(window); | |
| 161 } else { | |
| 162 WmWindowMus* root = WmWindowMus::Get(this->root()); | |
| 163 gfx::Point origin = | |
| 164 wm_root_window_controller_->ConvertPointToScreen(root, gfx::Point()); | |
| 165 gfx::Rect bounds_in_screen(origin, bounds.size()); | |
| 166 static_cast<WmWindowMus*>( | |
| 167 ash::wm::GetDefaultParent(WmWindowMus::Get(context), | |
| 168 WmWindowMus::Get(window), bounds_in_screen)) | |
| 169 ->aura_window() | |
| 170 ->AddChild(window); | |
| 171 } | |
| 122 return window; | 172 return window; |
| 123 } | 173 } |
| 124 | 174 |
| 125 WmWindowMus* RootWindowController::GetWindowByShellWindowId(int id) { | 175 WmWindowMus* RootWindowController::GetWindowByShellWindowId(int id) { |
| 126 return WmWindowMus::AsWmWindowMus( | 176 return WmWindowMus::AsWmWindowMus( |
| 127 WmWindowMus::Get(root_)->GetChildByShellWindowId(id)); | 177 WmWindowMus::Get(root())->GetChildByShellWindowId(id)); |
| 128 } | 178 } |
| 129 | 179 |
| 130 void RootWindowController::SetWorkAreaInests(const gfx::Insets& insets) { | 180 void RootWindowController::SetWorkAreaInests(const gfx::Insets& insets) { |
| 131 gfx::Rect old_work_area = display_.work_area(); | 181 gfx::Rect old_work_area = display_.work_area(); |
| 132 display_.UpdateWorkAreaFromInsets(insets); | 182 display_.UpdateWorkAreaFromInsets(insets); |
| 133 | 183 |
| 134 if (old_work_area == display_.work_area()) | 184 if (old_work_area == display_.work_area()) |
| 135 return; | 185 return; |
| 136 | 186 |
| 137 window_manager_->screen()->display_list().UpdateDisplay(display_); | 187 window_manager_->screen()->display_list().UpdateDisplay(display_); |
| 138 | 188 |
| 139 // Push new display insets to service:ui if we have a connection. | 189 // Push new display insets to service:ui if we have a connection. |
| 140 auto* display_controller = window_manager_->GetDisplayController(); | 190 auto* display_controller = window_manager_->GetDisplayController(); |
| 141 if (display_controller) | 191 if (display_controller) |
| 142 display_controller->SetDisplayWorkArea(display_.id(), | 192 display_controller->SetDisplayWorkArea(display_.id(), |
| 143 display_.bounds().size(), insets); | 193 display_.bounds().size(), insets); |
| 144 } | 194 } |
| 145 | 195 |
| 146 void RootWindowController::SetDisplay(const display::Display& display) { | 196 void RootWindowController::SetDisplay(const display::Display& display) { |
| 147 DCHECK_EQ(display.id(), display_.id()); | 197 DCHECK_EQ(display.id(), display_.id()); |
| 148 display_ = display; | 198 display_ = display; |
| 149 window_manager_->screen()->display_list().UpdateDisplay(display_); | 199 window_manager_->screen()->display_list().UpdateDisplay(display_); |
| 150 } | 200 } |
| 151 | 201 |
| 152 gfx::Rect RootWindowController::CalculateDefaultBounds( | 202 gfx::Rect RootWindowController::CalculateDefaultBounds( |
| 153 ui::Window* window) const { | 203 aura::Window* container_window, |
| 154 if (window->HasSharedProperty( | 204 const std::map<std::string, std::vector<uint8_t>>* properties) const { |
| 155 ui::mojom::WindowManager::kInitialBounds_Property)) { | 205 gfx::Rect requested_bounds; |
| 156 return window->GetSharedProperty<gfx::Rect>( | 206 if (GetInitialBounds(*properties, &requested_bounds)) |
| 157 ui::mojom::WindowManager::kInitialBounds_Property); | 207 return requested_bounds; |
| 158 } | |
| 159 | 208 |
| 160 if (GetWindowShowState(window) == ui::mojom::ShowState::FULLSCREEN) { | 209 auto show_state_iter = |
| 161 return gfx::Rect(0, 0, root_->bounds().width(), root_->bounds().height()); | 210 properties->find(ui::mojom::WindowManager::kShowState_Property); |
| 211 if (show_state_iter != properties->end()) { | |
| 212 if (IsFullscreen(window_manager_->property_converter(), | |
| 213 show_state_iter->second)) { | |
| 214 gfx::Rect bounds(0, 0, root()->bounds().width(), | |
| 215 root()->bounds().height()); | |
| 216 if (!container_window) { | |
| 217 bounds.Offset(display_.bounds().origin().x(), | |
| 218 display_.bounds().origin().y()); | |
| 219 } | |
| 220 return bounds; | |
| 221 } | |
| 162 } | 222 } |
| 163 | 223 |
| 164 int width, height; | 224 int width, height; |
| 165 const gfx::Size pref = GetWindowPreferredSize(window); | 225 gfx::Size pref; |
| 166 if (pref.IsEmpty()) { | 226 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. | 227 // TODO(sky): likely want to constrain more than root size. |
| 171 const gfx::Size max_size = root_->bounds().size(); | 228 const gfx::Size max_size = root()->bounds().size(); |
| 172 width = std::max(0, std::min(max_size.width(), pref.width())); | 229 width = std::max(0, std::min(max_size.width(), pref.width())); |
| 173 height = std::max(0, std::min(max_size.height(), pref.height())); | 230 height = std::max(0, std::min(max_size.height(), pref.height())); |
| 231 } else { | |
| 232 width = root()->bounds().width() - 240; | |
| 233 height = root()->bounds().height() - 240; | |
| 174 } | 234 } |
| 175 return gfx::Rect(40 + (window_count_ % 4) * 40, 40 + (window_count_ % 4) * 40, | 235 return gfx::Rect(40 + (window_count_ % 4) * 40, 40 + (window_count_ % 4) * 40, |
| 176 width, height); | 236 width, height); |
| 177 } | 237 } |
| 178 | 238 |
| 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 | 239 } // namespace mus |
| 188 } // namespace ash | 240 } // namespace ash |
| OLD | NEW |