| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ash/mus/root_window_controller.h" | |
| 6 | |
| 7 #include <stdint.h> | |
| 8 | |
| 9 #include <algorithm> | |
| 10 #include <map> | |
| 11 #include <sstream> | |
| 12 #include <string> | |
| 13 #include <utility> | |
| 14 #include <vector> | |
| 15 | |
| 16 #include "ash/common/shelf/shelf_layout_manager.h" | |
| 17 #include "ash/common/shelf/wm_shelf.h" | |
| 18 #include "ash/common/wm/container_finder.h" | |
| 19 #include "ash/common/wm/dock/docked_window_layout_manager.h" | |
| 20 #include "ash/common/wm/panels/panel_layout_manager.h" | |
| 21 #include "ash/common/wm/root_window_layout_manager.h" | |
| 22 #include "ash/common/wm_window.h" | |
| 23 #include "ash/mus/bridge/wm_shell_mus.h" | |
| 24 #include "ash/mus/disconnected_app_handler.h" | |
| 25 #include "ash/mus/non_client_frame_controller.h" | |
| 26 #include "ash/mus/property_util.h" | |
| 27 #include "ash/mus/screen_mus.h" | |
| 28 #include "ash/mus/window_manager.h" | |
| 29 #include "ash/public/cpp/shell_window_ids.h" | |
| 30 #include "ash/root_window_settings.h" | |
| 31 #include "base/bind.h" | |
| 32 #include "base/command_line.h" | |
| 33 #include "base/memory/ptr_util.h" | |
| 34 #include "mojo/public/cpp/bindings/type_converter.h" | |
| 35 #include "services/service_manager/public/cpp/connector.h" | |
| 36 #include "services/ui/common/switches.h" | |
| 37 #include "services/ui/common/util.h" | |
| 38 #include "ui/aura/client/aura_constants.h" | |
| 39 #include "ui/aura/mus/property_converter.h" | |
| 40 #include "ui/aura/mus/property_utils.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/aura/window_property.h" | |
| 45 #include "ui/base/ui_base_types.h" | |
| 46 #include "ui/display/display_list.h" | |
| 47 | |
| 48 DECLARE_WINDOW_PROPERTY_TYPE(ash::mus::RootWindowController*); | |
| 49 | |
| 50 namespace ash { | |
| 51 namespace mus { | |
| 52 namespace { | |
| 53 | |
| 54 DEFINE_LOCAL_WINDOW_PROPERTY_KEY(ash::mus::RootWindowController*, | |
| 55 kRootWindowControllerKey, | |
| 56 nullptr); | |
| 57 | |
| 58 bool IsFullscreen(aura::PropertyConverter* property_converter, | |
| 59 const std::vector<uint8_t>& transport_data) { | |
| 60 using ui::mojom::WindowManager; | |
| 61 aura::PropertyConverter::PrimitiveType show_state = 0; | |
| 62 return property_converter->GetPropertyValueFromTransportValue( | |
| 63 WindowManager::kShowState_Property, transport_data, &show_state) && | |
| 64 (static_cast<ui::WindowShowState>(show_state) == | |
| 65 ui::SHOW_STATE_FULLSCREEN); | |
| 66 } | |
| 67 | |
| 68 } // namespace | |
| 69 | |
| 70 RootWindowController::RootWindowController( | |
| 71 WindowManager* window_manager, | |
| 72 std::unique_ptr<aura::WindowTreeHostMus> window_tree_host, | |
| 73 const display::Display& display, | |
| 74 ash::RootWindowController::RootWindowType root_window_type) | |
| 75 : window_manager_(window_manager), | |
| 76 window_tree_host_(window_tree_host.get()), | |
| 77 window_count_(0), | |
| 78 display_(display) { | |
| 79 RootWindowSettings* root_window_settings = | |
| 80 InitRootWindowSettings(window_tree_host->window()); | |
| 81 root_window_settings->display_id = display.id(); | |
| 82 window_tree_host->window()->SetProperty(kRootWindowControllerKey, this); | |
| 83 ash_root_window_controller_ = base::WrapUnique( | |
| 84 new ash::RootWindowController(nullptr, window_tree_host.release())); | |
| 85 ash_root_window_controller_->Init(root_window_type); | |
| 86 | |
| 87 // TODO: To avoid lots of IPC AddActivationParent() should take an array. | |
| 88 // http://crbug.com/682048. | |
| 89 for (size_t i = 0; i < kNumActivatableShellWindowIds; ++i) { | |
| 90 window_manager_->window_manager_client()->AddActivationParent( | |
| 91 GetWindowByShellWindowId(kActivatableShellWindowIds[i])->aura_window()); | |
| 92 } | |
| 93 } | |
| 94 | |
| 95 RootWindowController::~RootWindowController() { | |
| 96 Shutdown(); | |
| 97 ash_root_window_controller_.reset(); | |
| 98 } | |
| 99 | |
| 100 // static | |
| 101 RootWindowController* RootWindowController::ForWindow(aura::Window* window) { | |
| 102 return window->GetRootWindow()->GetProperty(kRootWindowControllerKey); | |
| 103 } | |
| 104 | |
| 105 void RootWindowController::Shutdown() { | |
| 106 // NOTE: Shutdown() may be called multiple times. | |
| 107 ash_root_window_controller_->Shutdown(); | |
| 108 } | |
| 109 | |
| 110 service_manager::Connector* RootWindowController::GetConnector() { | |
| 111 return window_manager_->connector(); | |
| 112 } | |
| 113 | |
| 114 aura::Window* RootWindowController::root() { | |
| 115 return window_tree_host_->window(); | |
| 116 } | |
| 117 | |
| 118 const aura::Window* RootWindowController::root() const { | |
| 119 return window_tree_host_->window(); | |
| 120 } | |
| 121 | |
| 122 aura::Window* RootWindowController::NewTopLevelWindow( | |
| 123 ui::mojom::WindowType window_type, | |
| 124 std::map<std::string, std::vector<uint8_t>>* properties) { | |
| 125 // TODO(sky): constrain and validate properties. | |
| 126 | |
| 127 int32_t container_id = kShellWindowId_Invalid; | |
| 128 aura::Window* context = nullptr; | |
| 129 aura::Window* container_window = nullptr; | |
| 130 if (GetInitialContainerId(*properties, &container_id)) | |
| 131 container_window = GetWindowByShellWindowId(container_id)->aura_window(); | |
| 132 else | |
| 133 context = root(); | |
| 134 | |
| 135 gfx::Rect bounds = CalculateDefaultBounds(container_window, properties); | |
| 136 window_count_++; | |
| 137 | |
| 138 const bool provide_non_client_frame = | |
| 139 window_type == ui::mojom::WindowType::WINDOW || | |
| 140 window_type == ui::mojom::WindowType::PANEL; | |
| 141 if (provide_non_client_frame) { | |
| 142 // See NonClientFrameController for details on lifetime. | |
| 143 NonClientFrameController* non_client_frame_controller = | |
| 144 new NonClientFrameController(container_window, context, bounds, | |
| 145 window_type, properties, window_manager_); | |
| 146 DisconnectedAppHandler::Create(non_client_frame_controller->window()); | |
| 147 return non_client_frame_controller->window(); | |
| 148 } | |
| 149 | |
| 150 aura::Window* window = new aura::Window(nullptr); | |
| 151 aura::SetWindowType(window, window_type); | |
| 152 // Apply properties before Init(), that way they are sent to the server at | |
| 153 // the time the window is created. | |
| 154 aura::PropertyConverter* property_converter = | |
| 155 window_manager_->property_converter(); | |
| 156 for (auto& property_pair : *properties) { | |
| 157 property_converter->SetPropertyFromTransportValue( | |
| 158 window, property_pair.first, &property_pair.second); | |
| 159 } | |
| 160 window->Init(ui::LAYER_TEXTURED); | |
| 161 window->SetBounds(bounds); | |
| 162 DisconnectedAppHandler::Create(window); | |
| 163 | |
| 164 if (container_window) { | |
| 165 container_window->AddChild(window); | |
| 166 } else { | |
| 167 WmWindow* root = WmWindow::Get(this->root()); | |
| 168 gfx::Point origin = | |
| 169 root->ConvertPointToTarget(root->GetRootWindow(), gfx::Point()); | |
| 170 origin += display_.bounds().OffsetFromOrigin(); | |
| 171 gfx::Rect bounds_in_screen(origin, bounds.size()); | |
| 172 ash::wm::GetDefaultParent(WmWindow::Get(context), WmWindow::Get(window), | |
| 173 bounds_in_screen) | |
| 174 ->aura_window() | |
| 175 ->AddChild(window); | |
| 176 } | |
| 177 return window; | |
| 178 } | |
| 179 | |
| 180 WmWindow* RootWindowController::GetWindowByShellWindowId(int id) { | |
| 181 return WmWindow::Get(root())->GetChildByShellWindowId(id); | |
| 182 } | |
| 183 | |
| 184 void RootWindowController::SetWorkAreaInests(const gfx::Insets& insets) { | |
| 185 gfx::Rect old_work_area = display_.work_area(); | |
| 186 display_.UpdateWorkAreaFromInsets(insets); | |
| 187 | |
| 188 if (old_work_area == display_.work_area()) | |
| 189 return; | |
| 190 | |
| 191 window_manager_->screen()->display_list().UpdateDisplay(display_); | |
| 192 | |
| 193 // Push new display insets to service:ui if we have a connection. | |
| 194 auto* display_controller = window_manager_->GetDisplayController(); | |
| 195 if (display_controller) { | |
| 196 display_controller->SetDisplayWorkArea(display_.id(), | |
| 197 display_.bounds().size(), insets); | |
| 198 } | |
| 199 } | |
| 200 | |
| 201 void RootWindowController::SetDisplay(const display::Display& display) { | |
| 202 DCHECK_EQ(display.id(), display_.id()); | |
| 203 display_ = display; | |
| 204 window_manager_->screen()->display_list().UpdateDisplay(display_); | |
| 205 } | |
| 206 | |
| 207 gfx::Rect RootWindowController::CalculateDefaultBounds( | |
| 208 aura::Window* container_window, | |
| 209 const std::map<std::string, std::vector<uint8_t>>* properties) const { | |
| 210 gfx::Rect requested_bounds; | |
| 211 if (GetInitialBounds(*properties, &requested_bounds)) | |
| 212 return requested_bounds; | |
| 213 | |
| 214 auto show_state_iter = | |
| 215 properties->find(ui::mojom::WindowManager::kShowState_Property); | |
| 216 if (show_state_iter != properties->end()) { | |
| 217 if (IsFullscreen(window_manager_->property_converter(), | |
| 218 show_state_iter->second)) { | |
| 219 gfx::Rect bounds(0, 0, root()->bounds().width(), | |
| 220 root()->bounds().height()); | |
| 221 if (!container_window) { | |
| 222 bounds.Offset(display_.bounds().origin().x(), | |
| 223 display_.bounds().origin().y()); | |
| 224 } | |
| 225 return bounds; | |
| 226 } | |
| 227 } | |
| 228 | |
| 229 int width, height; | |
| 230 gfx::Size pref; | |
| 231 if (GetWindowPreferredSize(*properties, &pref) && !pref.IsEmpty()) { | |
| 232 // TODO(sky): likely want to constrain more than root size. | |
| 233 const gfx::Size max_size = root()->bounds().size(); | |
| 234 width = std::max(0, std::min(max_size.width(), pref.width())); | |
| 235 height = std::max(0, std::min(max_size.height(), pref.height())); | |
| 236 } else { | |
| 237 width = root()->bounds().width() - 240; | |
| 238 height = root()->bounds().height() - 240; | |
| 239 } | |
| 240 return gfx::Rect(40 + (window_count_ % 4) * 40, 40 + (window_count_ % 4) * 40, | |
| 241 width, height); | |
| 242 } | |
| 243 | |
| 244 } // namespace mus | |
| 245 } // namespace ash | |
| OLD | NEW |