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 |