Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: components/mus/ws/display.cc

Issue 2119963002: Move mus to //services/ui (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/mus/ws/display.h ('k') | components/mus/ws/display_binding.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 "components/mus/ws/display.h"
6
7 #include <set>
8 #include <vector>
9
10 #include "base/debug/debugger.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "components/mus/common/types.h"
13 #include "components/mus/ws/display_binding.h"
14 #include "components/mus/ws/display_manager.h"
15 #include "components/mus/ws/focus_controller.h"
16 #include "components/mus/ws/platform_display.h"
17 #include "components/mus/ws/platform_display_init_params.h"
18 #include "components/mus/ws/user_activity_monitor.h"
19 #include "components/mus/ws/window_manager_display_root.h"
20 #include "components/mus/ws/window_manager_state.h"
21 #include "components/mus/ws/window_manager_window_tree_factory.h"
22 #include "components/mus/ws/window_server.h"
23 #include "components/mus/ws/window_server_delegate.h"
24 #include "components/mus/ws/window_tree.h"
25 #include "components/mus/ws/window_tree_binding.h"
26 #include "mojo/common/common_type_converters.h"
27 #include "services/shell/public/interfaces/connector.mojom.h"
28 #include "ui/base/cursor/cursor.h"
29
30 namespace mus {
31 namespace ws {
32
33 Display::Display(WindowServer* window_server,
34 const PlatformDisplayInitParams& platform_display_init_params)
35 : id_(window_server->display_manager()->GetAndAdvanceNextDisplayId()),
36 window_server_(window_server),
37 platform_display_(PlatformDisplay::Create(platform_display_init_params)),
38 last_cursor_(ui::kCursorNone) {
39 platform_display_->Init(this);
40
41 window_server_->window_manager_window_tree_factory_set()->AddObserver(this);
42 window_server_->user_id_tracker()->AddObserver(this);
43 }
44
45 Display::~Display() {
46 window_server_->user_id_tracker()->RemoveObserver(this);
47
48 window_server_->window_manager_window_tree_factory_set()->RemoveObserver(
49 this);
50
51 if (!focus_controller_) {
52 focus_controller_->RemoveObserver(this);
53 focus_controller_.reset();
54 }
55
56 for (ServerWindow* window : windows_needing_frame_destruction_)
57 window->RemoveObserver(this);
58
59 // If there is a |binding_| then the tree was created specifically for this
60 // display (which corresponds to a WindowTreeHost).
61 if (binding_ && !window_manager_display_root_map_.empty()) {
62 window_server_->DestroyTree(window_manager_display_root_map_.begin()
63 ->second->window_manager_state()
64 ->window_tree());
65 }
66 }
67
68 void Display::Init(std::unique_ptr<DisplayBinding> binding) {
69 init_called_ = true;
70 binding_ = std::move(binding);
71 display_manager()->AddDisplay(this);
72 InitWindowManagerDisplayRootsIfNecessary();
73 }
74
75 DisplayManager* Display::display_manager() {
76 return window_server_->display_manager();
77 }
78
79 const DisplayManager* Display::display_manager() const {
80 return window_server_->display_manager();
81 }
82
83 mojom::DisplayPtr Display::ToMojomDisplay() const {
84 mojom::DisplayPtr display_ptr = mojom::Display::New();
85 display_ptr = mojom::Display::New();
86 display_ptr->id = id_;
87 // TODO(sky): Display should know it's origin.
88 display_ptr->bounds.SetRect(0, 0, root_->bounds().size().width(),
89 root_->bounds().size().height());
90 // TODO(sky): window manager needs an API to set the work area.
91 display_ptr->work_area = display_ptr->bounds;
92 display_ptr->device_pixel_ratio = platform_display_->GetDeviceScaleFactor();
93 display_ptr->rotation = platform_display_->GetRotation();
94 // TODO(sky): make this real.
95 display_ptr->is_primary = true;
96 // TODO(sky): make this real.
97 display_ptr->touch_support = mojom::TouchSupport::UNKNOWN;
98 display_ptr->frame_decoration_values = mojom::FrameDecorationValues::New();
99 return display_ptr;
100 }
101
102 void Display::SchedulePaint(const ServerWindow* window,
103 const gfx::Rect& bounds) {
104 DCHECK(root_->Contains(window));
105 platform_display_->SchedulePaint(window, bounds);
106 }
107
108 void Display::ScheduleSurfaceDestruction(ServerWindow* window) {
109 if (!platform_display_->IsFramePending()) {
110 window->DestroySurfacesScheduledForDestruction();
111 return;
112 }
113 if (windows_needing_frame_destruction_.count(window))
114 return;
115 windows_needing_frame_destruction_.insert(window);
116 window->AddObserver(this);
117 }
118
119 mojom::Rotation Display::GetRotation() const {
120 return platform_display_->GetRotation();
121 }
122
123 gfx::Size Display::GetSize() const {
124 return root_->bounds().size();
125 }
126
127 int64_t Display::GetPlatformDisplayId() const {
128 return platform_display_->GetDisplayId();
129 }
130
131 ServerWindow* Display::GetRootWithId(const WindowId& id) {
132 if (id == root_->id())
133 return root_.get();
134 for (auto& pair : window_manager_display_root_map_) {
135 if (pair.second->root()->id() == id)
136 return pair.second->root();
137 }
138 return nullptr;
139 }
140
141 WindowManagerDisplayRoot* Display::GetWindowManagerDisplayRootWithRoot(
142 const ServerWindow* window) {
143 for (auto& pair : window_manager_display_root_map_) {
144 if (pair.second->root() == window)
145 return pair.second.get();
146 }
147 return nullptr;
148 }
149
150 const WindowManagerDisplayRoot* Display::GetWindowManagerDisplayRootForUser(
151 const UserId& user_id) const {
152 auto iter = window_manager_display_root_map_.find(user_id);
153 return iter == window_manager_display_root_map_.end() ? nullptr
154 : iter->second.get();
155 }
156
157 const WindowManagerDisplayRoot* Display::GetActiveWindowManagerDisplayRoot()
158 const {
159 return GetWindowManagerDisplayRootForUser(
160 window_server_->user_id_tracker()->active_id());
161 }
162
163 bool Display::SetFocusedWindow(ServerWindow* new_focused_window) {
164 ServerWindow* old_focused_window = focus_controller_->GetFocusedWindow();
165 if (old_focused_window == new_focused_window)
166 return true;
167 DCHECK(!new_focused_window || root_window()->Contains(new_focused_window));
168 return focus_controller_->SetFocusedWindow(new_focused_window);
169 }
170
171 ServerWindow* Display::GetFocusedWindow() {
172 return focus_controller_->GetFocusedWindow();
173 }
174
175 void Display::ActivateNextWindow() {
176 // TODO(sky): this is wrong, needs to figure out the next window to activate
177 // and then route setting through WindowServer.
178 focus_controller_->ActivateNextWindow();
179 }
180
181 void Display::AddActivationParent(ServerWindow* window) {
182 activation_parents_.Add(window);
183 }
184
185 void Display::RemoveActivationParent(ServerWindow* window) {
186 activation_parents_.Remove(window);
187 }
188
189 void Display::UpdateTextInputState(ServerWindow* window,
190 const ui::TextInputState& state) {
191 // Do not need to update text input for unfocused windows.
192 if (!platform_display_ || focus_controller_->GetFocusedWindow() != window)
193 return;
194 platform_display_->UpdateTextInputState(state);
195 }
196
197 void Display::SetImeVisibility(ServerWindow* window, bool visible) {
198 // Do not need to show or hide IME for unfocused window.
199 if (focus_controller_->GetFocusedWindow() != window)
200 return;
201 platform_display_->SetImeVisibility(visible);
202 }
203
204 void Display::OnWillDestroyTree(WindowTree* tree) {
205 for (auto it = window_manager_display_root_map_.begin();
206 it != window_manager_display_root_map_.end(); ++it) {
207 if (it->second->window_manager_state()->window_tree() == tree) {
208 window_manager_display_root_map_.erase(it);
209 break;
210 }
211 }
212 }
213
214 void Display::UpdateNativeCursor(int32_t cursor_id) {
215 if (cursor_id != last_cursor_) {
216 platform_display_->SetCursorById(cursor_id);
217 last_cursor_ = cursor_id;
218 }
219 }
220
221 void Display::SetSize(const gfx::Size& size) {
222 platform_display_->SetViewportSize(size);
223 }
224
225 void Display::SetTitle(const mojo::String& title) {
226 platform_display_->SetTitle(title.To<base::string16>());
227 }
228
229 void Display::InitWindowManagerDisplayRootsIfNecessary() {
230 if (!init_called_ || !root_)
231 return;
232
233 display_manager()->OnDisplayAcceleratedWidgetAvailable(this);
234 if (binding_) {
235 std::unique_ptr<WindowManagerDisplayRoot> display_root_ptr(
236 new WindowManagerDisplayRoot(this));
237 WindowManagerDisplayRoot* display_root = display_root_ptr.get();
238 // For this case we never create additional displays roots, so any
239 // id works.
240 window_manager_display_root_map_[shell::mojom::kRootUserID] =
241 std::move(display_root_ptr);
242 WindowTree* window_tree = binding_->CreateWindowTree(display_root->root());
243 display_root->window_manager_state_ = window_tree->window_manager_state();
244 } else {
245 CreateWindowManagerDisplayRootsFromFactories();
246 }
247 }
248
249 void Display::CreateWindowManagerDisplayRootsFromFactories() {
250 std::vector<WindowManagerWindowTreeFactory*> factories =
251 window_server_->window_manager_window_tree_factory_set()->GetFactories();
252 for (WindowManagerWindowTreeFactory* factory : factories) {
253 if (factory->window_tree())
254 CreateWindowManagerDisplayRootFromFactory(factory);
255 }
256 }
257
258 void Display::CreateWindowManagerDisplayRootFromFactory(
259 WindowManagerWindowTreeFactory* factory) {
260 std::unique_ptr<WindowManagerDisplayRoot> display_root_ptr(
261 new WindowManagerDisplayRoot(this));
262 WindowManagerDisplayRoot* display_root = display_root_ptr.get();
263 window_manager_display_root_map_[factory->user_id()] =
264 std::move(display_root_ptr);
265 display_root->window_manager_state_ =
266 factory->window_tree()->window_manager_state();
267 const bool is_active =
268 factory->user_id() == window_server_->user_id_tracker()->active_id();
269 display_root->root()->SetVisible(is_active);
270 display_root->window_manager_state()->window_tree()->AddRootForWindowManager(
271 display_root->root());
272 }
273
274 ServerWindow* Display::GetRootWindow() {
275 return root_.get();
276 }
277
278 void Display::OnEvent(const ui::Event& event) {
279 WindowManagerDisplayRoot* display_root = GetActiveWindowManagerDisplayRoot();
280 if (display_root)
281 display_root->window_manager_state()->ProcessEvent(event);
282 window_server_
283 ->GetUserActivityMonitorForUser(
284 window_server_->user_id_tracker()->active_id())
285 ->OnUserActivity();
286 }
287
288 void Display::OnNativeCaptureLost() {
289 WindowManagerDisplayRoot* display_root = GetActiveWindowManagerDisplayRoot();
290 if (display_root)
291 display_root->window_manager_state()->SetCapture(nullptr, kInvalidClientId);
292 }
293
294 void Display::OnDisplayClosed() {
295 display_manager()->DestroyDisplay(this);
296 }
297
298 void Display::OnViewportMetricsChanged(const ViewportMetrics& old_metrics,
299 const ViewportMetrics& new_metrics) {
300 if (!root_) {
301 root_.reset(window_server_->CreateServerWindow(
302 display_manager()->GetAndAdvanceNextRootId(),
303 ServerWindow::Properties()));
304 root_->SetBounds(gfx::Rect(new_metrics.size_in_pixels));
305 root_->SetVisible(true);
306 focus_controller_.reset(new FocusController(this, root_.get()));
307 focus_controller_->AddObserver(this);
308 InitWindowManagerDisplayRootsIfNecessary();
309 } else {
310 root_->SetBounds(gfx::Rect(new_metrics.size_in_pixels));
311 const gfx::Rect wm_bounds(root_->bounds().size());
312 for (auto& pair : window_manager_display_root_map_)
313 pair.second->root()->SetBounds(wm_bounds);
314 }
315 display_manager()->OnDisplayUpdate(this);
316 }
317
318 void Display::OnCompositorFrameDrawn() {
319 std::set<ServerWindow*> windows;
320 windows.swap(windows_needing_frame_destruction_);
321 for (ServerWindow* window : windows) {
322 window->RemoveObserver(this);
323 window->DestroySurfacesScheduledForDestruction();
324 }
325 }
326
327 bool Display::CanHaveActiveChildren(ServerWindow* window) const {
328 return window && activation_parents_.Contains(window);
329 }
330
331 void Display::OnActivationChanged(ServerWindow* old_active_window,
332 ServerWindow* new_active_window) {
333 DCHECK_NE(new_active_window, old_active_window);
334 if (new_active_window && new_active_window->parent()) {
335 // Raise the new active window.
336 // TODO(sad): Let the WM dictate whether to raise the window or not?
337 new_active_window->parent()->StackChildAtTop(new_active_window);
338 }
339 }
340
341 void Display::OnFocusChanged(FocusControllerChangeSource change_source,
342 ServerWindow* old_focused_window,
343 ServerWindow* new_focused_window) {
344 // TODO(sky): focus is global, not per windowtreehost. Move.
345
346 // There are up to four clients that need to be notified:
347 // . the client containing |old_focused_window|.
348 // . the client with |old_focused_window| as its root.
349 // . the client containing |new_focused_window|.
350 // . the client with |new_focused_window| as its root.
351 // Some of these client may be the same. The following takes care to notify
352 // each only once.
353 WindowTree* owning_tree_old = nullptr;
354 WindowTree* embedded_tree_old = nullptr;
355
356 if (old_focused_window) {
357 owning_tree_old =
358 window_server_->GetTreeWithId(old_focused_window->id().client_id);
359 if (owning_tree_old) {
360 owning_tree_old->ProcessFocusChanged(old_focused_window,
361 new_focused_window);
362 }
363 embedded_tree_old = window_server_->GetTreeWithRoot(old_focused_window);
364 if (embedded_tree_old) {
365 DCHECK_NE(owning_tree_old, embedded_tree_old);
366 embedded_tree_old->ProcessFocusChanged(old_focused_window,
367 new_focused_window);
368 }
369 }
370 WindowTree* owning_tree_new = nullptr;
371 WindowTree* embedded_tree_new = nullptr;
372 if (new_focused_window) {
373 owning_tree_new =
374 window_server_->GetTreeWithId(new_focused_window->id().client_id);
375 if (owning_tree_new && owning_tree_new != owning_tree_old &&
376 owning_tree_new != embedded_tree_old) {
377 owning_tree_new->ProcessFocusChanged(old_focused_window,
378 new_focused_window);
379 }
380 embedded_tree_new = window_server_->GetTreeWithRoot(new_focused_window);
381 if (embedded_tree_new && embedded_tree_new != owning_tree_old &&
382 embedded_tree_new != embedded_tree_old) {
383 DCHECK_NE(owning_tree_new, embedded_tree_new);
384 embedded_tree_new->ProcessFocusChanged(old_focused_window,
385 new_focused_window);
386 }
387 }
388
389 // WindowManagers are always notified of focus changes.
390 WindowManagerDisplayRoot* display_root = GetActiveWindowManagerDisplayRoot();
391 if (display_root) {
392 WindowTree* wm_tree = display_root->window_manager_state()->window_tree();
393 if (wm_tree != owning_tree_old && wm_tree != embedded_tree_old &&
394 wm_tree != owning_tree_new && wm_tree != embedded_tree_new) {
395 wm_tree->ProcessFocusChanged(old_focused_window, new_focused_window);
396 }
397 }
398
399 UpdateTextInputState(new_focused_window,
400 new_focused_window->text_input_state());
401 }
402
403 void Display::OnWindowDestroyed(ServerWindow* window) {
404 windows_needing_frame_destruction_.erase(window);
405 window->RemoveObserver(this);
406 }
407
408 void Display::OnUserIdRemoved(const UserId& id) {
409 window_manager_display_root_map_.erase(id);
410 }
411
412 void Display::OnWindowManagerWindowTreeFactoryReady(
413 WindowManagerWindowTreeFactory* factory) {
414 if (!binding_)
415 CreateWindowManagerDisplayRootFromFactory(factory);
416 }
417
418 } // namespace ws
419 } // namespace mus
OLDNEW
« no previous file with comments | « components/mus/ws/display.h ('k') | components/mus/ws/display_binding.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698