| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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 "mash/wm/window_manager.h" | |
| 6 | |
| 7 #include <stdint.h> | |
| 8 | |
| 9 #include <utility> | |
| 10 | |
| 11 #include "ash/common/wm/container_finder.h" | |
| 12 #include "ash/public/interfaces/container.mojom.h" | |
| 13 #include "components/mus/common/types.h" | |
| 14 #include "components/mus/public/cpp/property_type_converters.h" | |
| 15 #include "components/mus/public/cpp/window.h" | |
| 16 #include "components/mus/public/cpp/window_property.h" | |
| 17 #include "components/mus/public/cpp/window_tree_client.h" | |
| 18 #include "components/mus/public/interfaces/input_events.mojom.h" | |
| 19 #include "components/mus/public/interfaces/mus_constants.mojom.h" | |
| 20 #include "components/mus/public/interfaces/window_manager.mojom.h" | |
| 21 #include "mash/wm/bridge/wm_window_mus.h" | |
| 22 #include "mash/wm/non_client_frame_controller.h" | |
| 23 #include "mash/wm/property_util.h" | |
| 24 #include "mash/wm/root_window_controller.h" | |
| 25 | |
| 26 namespace mash { | |
| 27 namespace wm { | |
| 28 | |
| 29 WindowManager::WindowManager() | |
| 30 : root_controller_(nullptr), | |
| 31 window_manager_client_(nullptr), | |
| 32 binding_(this) {} | |
| 33 | |
| 34 WindowManager::~WindowManager() { | |
| 35 } | |
| 36 | |
| 37 void WindowManager::Initialize(RootWindowController* root_controller, | |
| 38 session::mojom::Session* session) { | |
| 39 DCHECK(root_controller); | |
| 40 DCHECK(!root_controller_); | |
| 41 root_controller_ = root_controller; | |
| 42 | |
| 43 // Observe all the containers so that windows can be added to/removed from the | |
| 44 // |disconnected_app_handler_|. | |
| 45 int count = static_cast<int>(ash::mojom::Container::COUNT); | |
| 46 for (int id = static_cast<int>(ash::mojom::Container::ROOT) + 1; id < count; | |
| 47 ++id) { | |
| 48 mus::Window* container = root_controller_->GetWindowForContainer( | |
| 49 static_cast<ash::mojom::Container>(id)); | |
| 50 Add(container); | |
| 51 | |
| 52 // Add any pre-existing windows in the container to | |
| 53 // |disconnected_app_handler_|. | |
| 54 for (auto child : container->children()) { | |
| 55 if (!root_controller_->WindowIsContainer(child)) | |
| 56 disconnected_app_handler_.Add(child); | |
| 57 } | |
| 58 } | |
| 59 | |
| 60 // The insets are roughly what is needed by CustomFrameView. The expectation | |
| 61 // is at some point we'll write our own NonClientFrameView and get the insets | |
| 62 // from it. | |
| 63 mus::mojom::FrameDecorationValuesPtr frame_decoration_values = | |
| 64 mus::mojom::FrameDecorationValues::New(); | |
| 65 const gfx::Insets client_area_insets = | |
| 66 NonClientFrameController::GetPreferredClientAreaInsets(); | |
| 67 frame_decoration_values->normal_client_area_insets = client_area_insets; | |
| 68 frame_decoration_values->maximized_client_area_insets = client_area_insets; | |
| 69 frame_decoration_values->max_title_bar_button_width = | |
| 70 NonClientFrameController::GetMaxTitleBarButtonWidth(); | |
| 71 window_manager_client_->SetFrameDecorationValues( | |
| 72 std::move(frame_decoration_values)); | |
| 73 | |
| 74 if (session) | |
| 75 session->AddScreenlockStateListener(binding_.CreateInterfacePtrAndBind()); | |
| 76 } | |
| 77 | |
| 78 mus::Window* WindowManager::NewTopLevelWindow( | |
| 79 std::map<std::string, std::vector<uint8_t>>* properties) { | |
| 80 DCHECK(root_controller_); | |
| 81 mus::Window* root = root_controller_->root(); | |
| 82 DCHECK(root); | |
| 83 | |
| 84 // TODO(sky): panels need a different frame, http:://crbug.com/614362. | |
| 85 const bool provide_non_client_frame = | |
| 86 GetWindowType(*properties) == mus::mojom::WindowType::WINDOW || | |
| 87 GetWindowType(*properties) == mus::mojom::WindowType::PANEL; | |
| 88 if (provide_non_client_frame) | |
| 89 (*properties)[mus::mojom::kWaitForUnderlay_Property].clear(); | |
| 90 | |
| 91 // TODO(sky): constrain and validate properties before passing to server. | |
| 92 mus::Window* window = root->window_tree()->NewWindow(properties); | |
| 93 window->SetBounds(CalculateDefaultBounds(window)); | |
| 94 | |
| 95 mus::Window* container_window = nullptr; | |
| 96 if (window->HasSharedProperty(ash::mojom::kWindowContainer_Property)) { | |
| 97 container_window = | |
| 98 root_controller_->GetWindowForContainer(GetRequestedContainer(window)); | |
| 99 } else { | |
| 100 // TODO(sky): window->bounds() isn't quite right. | |
| 101 container_window = WmWindowMus::GetMusWindow( | |
| 102 ash::wm::GetDefaultParent(WmWindowMus::Get(root_controller_->root()), | |
| 103 WmWindowMus::Get(window), window->bounds())); | |
| 104 } | |
| 105 DCHECK(root_controller_->WindowIsContainer(container_window)); | |
| 106 | |
| 107 if (provide_non_client_frame) { | |
| 108 NonClientFrameController::Create(root_controller_->GetConnector(), | |
| 109 container_window, window, | |
| 110 root_controller_->window_manager_client()); | |
| 111 } else { | |
| 112 container_window->AddChild(window); | |
| 113 } | |
| 114 | |
| 115 root_controller_->IncrementWindowCount(); | |
| 116 | |
| 117 return window; | |
| 118 } | |
| 119 | |
| 120 gfx::Rect WindowManager::CalculateDefaultBounds(mus::Window* window) const { | |
| 121 if (window->HasSharedProperty( | |
| 122 mus::mojom::WindowManager::kInitialBounds_Property)) { | |
| 123 return window->GetSharedProperty<gfx::Rect>( | |
| 124 mus::mojom::WindowManager::kInitialBounds_Property); | |
| 125 } | |
| 126 | |
| 127 DCHECK(root_controller_); | |
| 128 int width, height; | |
| 129 const gfx::Size pref = GetWindowPreferredSize(window); | |
| 130 const mus::Window* root = root_controller_->root(); | |
| 131 if (pref.IsEmpty()) { | |
| 132 width = root->bounds().width() - 240; | |
| 133 height = root->bounds().height() - 240; | |
| 134 } else { | |
| 135 // TODO(sky): likely want to constrain more than root size. | |
| 136 const gfx::Size max_size = GetMaximizedWindowBounds().size(); | |
| 137 width = std::max(0, std::min(max_size.width(), pref.width())); | |
| 138 height = std::max(0, std::min(max_size.height(), pref.height())); | |
| 139 } | |
| 140 return gfx::Rect(40 + (root_controller_->window_count() % 4) * 40, | |
| 141 40 + (root_controller_->window_count() % 4) * 40, width, | |
| 142 height); | |
| 143 } | |
| 144 | |
| 145 gfx::Rect WindowManager::GetMaximizedWindowBounds() const { | |
| 146 DCHECK(root_controller_); | |
| 147 return gfx::Rect(root_controller_->root()->bounds().size()); | |
| 148 } | |
| 149 | |
| 150 void WindowManager::OnTreeChanging(const TreeChangeParams& params) { | |
| 151 DCHECK(root_controller_); | |
| 152 if (params.old_parent == params.receiver && | |
| 153 root_controller_->WindowIsContainer(params.old_parent)) | |
| 154 disconnected_app_handler_.Remove(params.target); | |
| 155 | |
| 156 if (params.new_parent == params.receiver && | |
| 157 root_controller_->WindowIsContainer(params.new_parent)) | |
| 158 disconnected_app_handler_.Add(params.target); | |
| 159 | |
| 160 mus::WindowTracker::OnTreeChanging(params); | |
| 161 } | |
| 162 | |
| 163 void WindowManager::SetWindowManagerClient(mus::WindowManagerClient* client) { | |
| 164 window_manager_client_ = client; | |
| 165 } | |
| 166 | |
| 167 bool WindowManager::OnWmSetBounds(mus::Window* window, gfx::Rect* bounds) { | |
| 168 // TODO(sky): this indirectly sets bounds, which is against what | |
| 169 // OnWmSetBounds() recommends doing. Remove that restriction, or fix this. | |
| 170 WmWindowMus::Get(window)->SetBounds(*bounds); | |
| 171 *bounds = window->bounds(); | |
| 172 return true; | |
| 173 } | |
| 174 | |
| 175 bool WindowManager::OnWmSetProperty( | |
| 176 mus::Window* window, | |
| 177 const std::string& name, | |
| 178 std::unique_ptr<std::vector<uint8_t>>* new_data) { | |
| 179 // TODO(sky): constrain this to set of keys we know about, and allowed | |
| 180 // values. | |
| 181 return name == mus::mojom::WindowManager::kShowState_Property || | |
| 182 name == mus::mojom::WindowManager::kPreferredSize_Property || | |
| 183 name == mus::mojom::WindowManager::kResizeBehavior_Property || | |
| 184 name == mus::mojom::WindowManager::kWindowAppIcon_Property || | |
| 185 name == mus::mojom::WindowManager::kWindowTitle_Property; | |
| 186 } | |
| 187 | |
| 188 mus::Window* WindowManager::OnWmCreateTopLevelWindow( | |
| 189 std::map<std::string, std::vector<uint8_t>>* properties) { | |
| 190 return NewTopLevelWindow(properties); | |
| 191 } | |
| 192 | |
| 193 void WindowManager::OnWmClientJankinessChanged( | |
| 194 const std::set<mus::Window*>& client_windows, | |
| 195 bool janky) { | |
| 196 for (auto window : client_windows) | |
| 197 SetWindowIsJanky(window, janky); | |
| 198 } | |
| 199 | |
| 200 void WindowManager::OnAccelerator(uint32_t id, const ui::Event& event) { | |
| 201 root_controller_->OnAccelerator(id, std::move(event)); | |
| 202 } | |
| 203 | |
| 204 void WindowManager::ScreenlockStateChanged(bool locked) { | |
| 205 // Hide USER_PRIVATE_CONTAINER windows when the screen is locked. | |
| 206 mus::Window* window = root_controller_->GetWindowForContainer( | |
| 207 ash::mojom::Container::USER_PRIVATE); | |
| 208 window->SetVisible(!locked); | |
| 209 } | |
| 210 | |
| 211 } // namespace wm | |
| 212 } // namespace mash | |
| OLD | NEW |