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

Side by Side Diff: ash/wm/workspace/workspace_layout_manager.cc

Issue 149303003: [Refactor] Move the logic to update bounds for show type from WorkspaceLayoutManager to DefaultState (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: handle show_inactive Created 6 years, 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/wm/workspace/workspace_layout_manager.h" 5 #include "ash/wm/workspace/workspace_layout_manager.h"
6 6
7 #include "ash/display/display_controller.h" 7 #include "ash/display/display_controller.h"
8 #include "ash/root_window_controller.h" 8 #include "ash/root_window_controller.h"
9 #include "ash/screen_util.h" 9 #include "ash/screen_util.h"
10 #include "ash/session_state_delegate.h" 10 #include "ash/session_state_delegate.h"
11 #include "ash/shelf/shelf_layout_manager.h" 11 #include "ash/shelf/shelf_layout_manager.h"
12 #include "ash/shell.h" 12 #include "ash/shell.h"
13 #include "ash/wm/always_on_top_controller.h" 13 #include "ash/wm/always_on_top_controller.h"
14 #include "ash/wm/window_animations.h" 14 #include "ash/wm/window_animations.h"
15 #include "ash/wm/window_positioner.h" 15 #include "ash/wm/window_positioner.h"
16 #include "ash/wm/window_properties.h" 16 #include "ash/wm/window_properties.h"
17 #include "ash/wm/window_state.h" 17 #include "ash/wm/window_state.h"
18 #include "ash/wm/window_util.h" 18 #include "ash/wm/window_util.h"
19 #include "ash/wm/workspace/workspace_window_resizer.h"
20 #include "ui/aura/client/activation_client.h" 19 #include "ui/aura/client/activation_client.h"
21 #include "ui/aura/client/aura_constants.h" 20 #include "ui/aura/client/aura_constants.h"
22 #include "ui/aura/window.h" 21 #include "ui/aura/window.h"
23 #include "ui/aura/window_observer.h" 22 #include "ui/aura/window_observer.h"
24 #include "ui/base/ui_base_types.h" 23 #include "ui/base/ui_base_types.h"
25 #include "ui/compositor/layer.h" 24 #include "ui/compositor/layer.h"
26 #include "ui/compositor/scoped_layer_animation_settings.h"
27 #include "ui/events/event.h" 25 #include "ui/events/event.h"
28 #include "ui/gfx/screen.h" 26 #include "ui/gfx/screen.h"
29 #include "ui/views/corewm/window_util.h" 27 #include "ui/views/corewm/window_util.h"
30 28
31 using aura::Window; 29 using aura::Window;
32 30
33 namespace ash { 31 namespace ash {
34 32
35 namespace internal { 33 namespace internal {
36 34
37 namespace { 35 namespace {
38 36
39 // This specifies how much percent 30% of a window rect (width / height) 37 // This specifies how much percent 30% of a window rect (width / height)
40 // must be visible when the window is added to the workspace. 38 // must be visible when the window is added to the workspace.
41 const float kMinimumPercentOnScreenArea = 0.3f; 39 const float kMinimumPercentOnScreenArea = 0.3f;
42 40
43 void MoveToDisplayForRestore(wm::WindowState* window_state) {
44 if (!window_state->HasRestoreBounds())
45 return;
46 const gfx::Rect& restore_bounds = window_state->GetRestoreBoundsInScreen();
47
48 // Move only if the restore bounds is outside of
49 // the display. There is no information about in which
50 // display it should be restored, so this is best guess.
51 // TODO(oshima): Restore information should contain the
52 // work area information like WindowResizer does for the
53 // last window location.
54 gfx::Rect display_area = Shell::GetScreen()->GetDisplayNearestWindow(
55 window_state->window()).bounds();
56
57 if (!display_area.Intersects(restore_bounds)) {
58 const gfx::Display& display =
59 Shell::GetScreen()->GetDisplayMatching(restore_bounds);
60 DisplayController* display_controller =
61 Shell::GetInstance()->display_controller();
62 aura::Window* new_root =
63 display_controller->GetRootWindowForDisplayId(display.id());
64 if (new_root != window_state->window()->GetRootWindow()) {
65 aura::Window* new_container =
66 Shell::GetContainer(new_root, window_state->window()->parent()->id());
67 new_container->AddChild(window_state->window());
68 }
69 }
70 }
71
72 gfx::Rect BoundsWithScreenEdgeVisible(
73 aura::Window* window,
74 const gfx::Rect& restore_bounds) {
75 gfx::Rect max_bounds =
76 ash::ScreenUtil::GetMaximizedWindowBoundsInParent(window);
77 // If the restore_bounds are more than 1 grid step away from the size the
78 // window would be when maximized, inset it.
79 max_bounds.Inset(ash::internal::WorkspaceWindowResizer::kScreenEdgeInset,
80 ash::internal::WorkspaceWindowResizer::kScreenEdgeInset);
81 if (restore_bounds.Contains(max_bounds))
82 return max_bounds;
83 return restore_bounds;
84 }
85
86 } // namespace 41 } // namespace
87 42
88 WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window) 43 WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window)
89 : shelf_(NULL), 44 : shelf_(NULL),
90 window_(window), 45 window_(window),
91 root_window_(window->GetRootWindow()), 46 root_window_(window->GetRootWindow()),
92 work_area_in_parent_(ScreenUtil::ConvertRectFromScreen( 47 work_area_in_parent_(ScreenUtil::ConvertRectFromScreen(
93 window_, 48 window_,
94 Shell::GetScreen()->GetDisplayNearestWindow(window_).work_area())), 49 Shell::GetScreen()->GetDisplayNearestWindow(window_).work_area())),
95 is_fullscreen_(GetRootWindowController( 50 is_fullscreen_(GetRootWindowController(
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 120
166 void WorkspaceLayoutManager::SetChildBounds( 121 void WorkspaceLayoutManager::SetChildBounds(
167 Window* child, 122 Window* child,
168 const gfx::Rect& requested_bounds) { 123 const gfx::Rect& requested_bounds) {
169 wm::WindowState* window_state = wm::GetWindowState(child); 124 wm::WindowState* window_state = wm::GetWindowState(child);
170 if (window_state->is_dragged()) { 125 if (window_state->is_dragged()) {
171 SetChildBoundsDirect(child, requested_bounds); 126 SetChildBoundsDirect(child, requested_bounds);
172 } else if (window_state->IsSnapped()) { 127 } else if (window_state->IsSnapped()) {
173 gfx::Rect child_bounds(requested_bounds); 128 gfx::Rect child_bounds(requested_bounds);
174 wm::AdjustBoundsSmallerThan(work_area_in_parent_.size(), &child_bounds); 129 wm::AdjustBoundsSmallerThan(work_area_in_parent_.size(), &child_bounds);
175 AdjustSnappedBounds(window_state, &child_bounds); 130 window_state->AdjustSnappedBounds(&child_bounds);
176 SetChildBoundsDirect(child, child_bounds); 131 SetChildBoundsDirect(child, child_bounds);
177 } else if (!SetMaximizedOrFullscreenBounds(window_state)) { 132 } else if (!SetMaximizedOrFullscreenBounds(window_state)) {
178 // Some windows rely on this to set their initial bounds. 133 // Some windows rely on this to set their initial bounds.
179 // Non-maximized/full-screen windows have their size constrained to the 134 // Non-maximized/full-screen windows have their size constrained to the
180 // work-area. 135 // work-area.
181 gfx::Rect child_bounds(requested_bounds); 136 gfx::Rect child_bounds(requested_bounds);
182 wm::AdjustBoundsSmallerThan(work_area_in_parent_.size(), &child_bounds); 137 wm::AdjustBoundsSmallerThan(work_area_in_parent_.size(), &child_bounds);
183 SetChildBoundsDirect(child, child_bounds); 138 SetChildBoundsDirect(child, child_bounds);
184 } 139 }
185 UpdateShelfVisibility(); 140 UpdateShelfVisibility();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 if (window_state && window_state->IsMinimized() && 195 if (window_state && window_state->IsMinimized() &&
241 !gained_active->IsVisible()) { 196 !gained_active->IsVisible()) {
242 window_state->Unminimize(); 197 window_state->Unminimize();
243 DCHECK(!window_state->IsMinimized()); 198 DCHECK(!window_state->IsMinimized());
244 } 199 }
245 } 200 }
246 201
247 ////////////////////////////////////////////////////////////////////////////// 202 //////////////////////////////////////////////////////////////////////////////
248 // WorkspaceLayoutManager, wm::WindowStateObserver implementation: 203 // WorkspaceLayoutManager, wm::WindowStateObserver implementation:
249 204
250 void WorkspaceLayoutManager::OnWindowShowTypeChanged( 205 void WorkspaceLayoutManager::OnPostWindowShowTypeChange(
251 wm::WindowState* window_state, 206 wm::WindowState* window_state,
252 wm::WindowShowType old_type) { 207 wm::WindowShowType old_type) {
253 if (old_type != wm::SHOW_TYPE_MINIMIZED &&
254 !window_state->HasRestoreBounds() &&
255 window_state->IsMaximizedOrFullscreen() &&
256 !wm::IsMaximizedOrFullscreenWindowShowType(old_type)) {
257 window_state->SaveCurrentBoundsForRestore();
258 }
259 // When restoring from a minimized state, we want to restore to the previous
260 // bounds. However, we want to maintain the restore bounds. (The restore
261 // bounds are set if a user maximized the window in one axis by double
262 // clicking the window border for example).
263 gfx::Rect restore;
264 if (old_type == wm::SHOW_TYPE_MINIMIZED &&
265 window_state->IsNormalShowState() &&
266 window_state->HasRestoreBounds() &&
267 !window_state->unminimize_to_restore_bounds()) {
268 restore = window_state->GetRestoreBoundsInScreen();
269 window_state->SaveCurrentBoundsForRestore();
270 }
271
272 UpdateBoundsFromShowType(window_state, old_type);
273 ShowTypeChanged(window_state, old_type);
274
275 if (window_state->IsNormalShowState())
276 window_state->ClearRestoreBounds();
277
278 // Set the restore rectangle to the previously set restore rectangle.
279 if (!restore.IsEmpty())
280 window_state->SetRestoreBoundsInScreen(restore);
281 208
282 // Notify observers that fullscreen state may be changing. 209 // Notify observers that fullscreen state may be changing.
283 if (window_state->IsFullscreen() || old_type == wm::SHOW_TYPE_FULLSCREEN) 210 if (window_state->IsFullscreen() || old_type == wm::SHOW_TYPE_FULLSCREEN)
284 UpdateFullscreenState(); 211 UpdateFullscreenState();
285 212
286 UpdateShelfVisibility(); 213 UpdateShelfVisibility();
287 } 214 }
288 215
289 void WorkspaceLayoutManager::ShowTypeChanged(
290 wm::WindowState* window_state,
291 wm::WindowShowType last_show_type) {
292 if (window_state->IsMinimized()) {
293 // Save the previous show state so that we can correctly restore it.
294 window_state->window()->SetProperty(aura::client::kRestoreShowStateKey,
295 wm::ToWindowShowState(last_show_type));
296 views::corewm::SetWindowVisibilityAnimationType(
297 window_state->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
298
299 // Hide the window.
300 window_state->window()->Hide();
301 // Activate another window.
302 if (window_state->IsActive())
303 window_state->Deactivate();
304 } else if ((window_state->window()->TargetVisibility() ||
305 last_show_type == wm::SHOW_TYPE_MINIMIZED) &&
306 !window_state->window()->layer()->visible()) {
307 // The layer may be hidden if the window was previously minimized. Make
308 // sure it's visible.
309 window_state->window()->Show();
310 if (last_show_type == wm::SHOW_TYPE_MINIMIZED &&
311 !window_state->IsMaximizedOrFullscreen()) {
312 window_state->set_unminimize_to_restore_bounds(false);
313 }
314 }
315 }
316
317 ////////////////////////////////////////////////////////////////////////////// 216 //////////////////////////////////////////////////////////////////////////////
318 // WorkspaceLayoutManager, private: 217 // WorkspaceLayoutManager, private:
319 218
320 void WorkspaceLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange( 219 void WorkspaceLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(
321 AdjustWindowReason reason) { 220 AdjustWindowReason reason) {
322 work_area_in_parent_ = ScreenUtil::ConvertRectFromScreen( 221 work_area_in_parent_ = ScreenUtil::ConvertRectFromScreen(
323 window_, 222 window_,
324 Shell::GetScreen()->GetDisplayNearestWindow(window_).work_area()); 223 Shell::GetScreen()->GetDisplayNearestWindow(window_).work_area());
325 224
326 // Don't do any adjustments of the insets while we are in screen locked mode. 225 // Don't do any adjustments of the insets while we are in screen locked mode.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED: 267 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED:
369 // The work area may be smaller than the full screen. Put as much of the 268 // The work area may be smaller than the full screen. Put as much of the
370 // window as possible within the display area. 269 // window as possible within the display area.
371 bounds.AdjustToFit(work_area_in_parent_); 270 bounds.AdjustToFit(work_area_in_parent_);
372 break; 271 break;
373 case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED: 272 case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED:
374 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( 273 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
375 work_area_in_parent_, &bounds); 274 work_area_in_parent_, &bounds);
376 break; 275 break;
377 } 276 }
378 //AdjustSnappedBounds(window_state, &bounds); 277 window_state->AdjustSnappedBounds(&bounds);
379 if (window_state->window()->bounds() != bounds) 278 if (window_state->window()->bounds() != bounds)
380 SetChildBoundsAnimated(window_state->window(), bounds); 279 window_state->SetBoundsDirectAnimated(bounds);
381 } 280 }
382 281
383 void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded( 282 void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded(
384 wm::WindowState* window_state) { 283 wm::WindowState* window_state) {
385 // Don't adjust window bounds if the bounds are empty as this 284 // Don't adjust window bounds if the bounds are empty as this
386 // happens when a new views::Widget is created. 285 // happens when a new views::Widget is created.
387 // When a window is dragged and dropped onto a different 286 // When a window is dragged and dropped onto a different
388 // root window, the bounds will be updated after they are added 287 // root window, the bounds will be updated after they are added
389 // to the root window. 288 // to the root window.
390 if (window_state->window()->bounds().IsEmpty() || 289 if (window_state->window()->bounds().IsEmpty() ||
391 window_state->is_dragged() || 290 window_state->is_dragged() ||
392 SetMaximizedOrFullscreenBounds(window_state)) { 291 SetMaximizedOrFullscreenBounds(window_state)) {
393 return; 292 return;
394 } 293 }
395 294
396 Window* window = window_state->window(); 295 Window* window = window_state->window();
397 gfx::Rect bounds = window->bounds(); 296 gfx::Rect bounds = window->bounds();
398 297
399 // Use entire display instead of workarea because the workarea can 298 // Use entire display instead of workarea because the workarea can
400 // be further shrunk by the docked area. The logic ensures 30% 299 // be further shrunk by the docked area. The logic ensures 30%
401 // visibility which should be enough to see where the window gets 300 // visibility which should be enough to see where the window gets
402 // moved. 301 // moved.
403 gfx::Rect display_area = ScreenUtil::GetDisplayBoundsInParent(window); 302 gfx::Rect display_area = ScreenUtil::GetDisplayBoundsInParent(window);
404 303
405 int min_width = bounds.width() * kMinimumPercentOnScreenArea; 304 int min_width = bounds.width() * kMinimumPercentOnScreenArea;
406 int min_height = bounds.height() * kMinimumPercentOnScreenArea; 305 int min_height = bounds.height() * kMinimumPercentOnScreenArea;
407 ash::wm::AdjustBoundsToEnsureWindowVisibility( 306 ash::wm::AdjustBoundsToEnsureWindowVisibility(
408 display_area, min_width, min_height, &bounds); 307 display_area, min_width, min_height, &bounds);
409 AdjustSnappedBounds(window_state, &bounds); 308 window_state->AdjustSnappedBounds(&bounds);
410 if (window->bounds() != bounds) 309 if (window->bounds() != bounds)
411 window->SetBounds(bounds); 310 window->SetBounds(bounds);
412 } 311 }
413 312
414 void WorkspaceLayoutManager::UpdateShelfVisibility() { 313 void WorkspaceLayoutManager::UpdateShelfVisibility() {
415 if (shelf_) 314 if (shelf_)
416 shelf_->UpdateVisibilityState(); 315 shelf_->UpdateVisibilityState();
417 } 316 }
418 317
419 void WorkspaceLayoutManager::UpdateFullscreenState() { 318 void WorkspaceLayoutManager::UpdateFullscreenState() {
420 bool is_fullscreen = GetRootWindowController( 319 bool is_fullscreen = GetRootWindowController(
421 window_->GetRootWindow())->GetWindowForFullscreenMode() != NULL; 320 window_->GetRootWindow())->GetWindowForFullscreenMode() != NULL;
422 if (is_fullscreen != is_fullscreen_) { 321 if (is_fullscreen != is_fullscreen_) {
423 ash::Shell::GetInstance()->NotifyFullscreenStateChange( 322 ash::Shell::GetInstance()->NotifyFullscreenStateChange(
424 is_fullscreen, window_->GetRootWindow()); 323 is_fullscreen, window_->GetRootWindow());
425 is_fullscreen_ = is_fullscreen; 324 is_fullscreen_ = is_fullscreen;
426 } 325 }
427 } 326 }
428 327
429 void WorkspaceLayoutManager::UpdateBoundsFromShowType(
430 wm::WindowState* window_state,
431 wm::WindowShowType old_show_type) {
432 aura::Window* window = window_state->window();
433 if (window_state->IsMaximizedOrFullscreen())
434 MoveToDisplayForRestore(window_state);
435
436 wm::WindowShowType show_type = window_state->window_show_type();
437 gfx::Rect bounds_in_parent;
438 switch (show_type) {
439 case wm::SHOW_TYPE_DEFAULT:
440 case wm::SHOW_TYPE_NORMAL:
441 case wm::SHOW_TYPE_LEFT_SNAPPED:
442 case wm::SHOW_TYPE_RIGHT_SNAPPED:
443 if (window_state->HasRestoreBounds())
444 bounds_in_parent = window_state->GetRestoreBoundsInParent();
445 else
446 bounds_in_parent = window->bounds();
447 // Make sure that part of the window is always visible.
448 wm::AdjustBoundsToEnsureMinimumWindowVisibility(
449 work_area_in_parent_, &bounds_in_parent);
450
451 if (show_type == wm::SHOW_TYPE_LEFT_SNAPPED ||
452 show_type == wm::SHOW_TYPE_RIGHT_SNAPPED) {
453 AdjustSnappedBounds(window_state, &bounds_in_parent);
454 } else {
455 bounds_in_parent = BoundsWithScreenEdgeVisible(
456 window,
457 bounds_in_parent);
458 }
459 break;
460
461 case wm::SHOW_TYPE_MAXIMIZED:
462 bounds_in_parent = ScreenUtil::GetMaximizedWindowBoundsInParent(window);
463 break;
464
465 case wm::SHOW_TYPE_FULLSCREEN:
466 bounds_in_parent = ScreenUtil::GetDisplayBoundsInParent(window);
467 break;
468
469 case wm::SHOW_TYPE_MINIMIZED:
470 case wm::SHOW_TYPE_INACTIVE:
471 case wm::SHOW_TYPE_DETACHED:
472 case wm::SHOW_TYPE_END:
473 case wm::SHOW_TYPE_AUTO_POSITIONED:
474 return;
475 }
476
477 if (old_show_type == wm::SHOW_TYPE_MINIMIZED ||
478 (window_state->IsFullscreen() &&
479 !window_state->animate_to_fullscreen())) {
480 SetChildBoundsDirect(window, bounds_in_parent);
481 } else if (window_state->IsMaximizedOrFullscreen() ||
482 IsMaximizedOrFullscreenWindowShowType(old_show_type)) {
483 CrossFadeToBounds(window, bounds_in_parent);
484 } else {
485 SetChildBoundsAnimated(window, bounds_in_parent);
486 }
487 }
488
489 bool WorkspaceLayoutManager::SetMaximizedOrFullscreenBounds( 328 bool WorkspaceLayoutManager::SetMaximizedOrFullscreenBounds(
490 wm::WindowState* window_state) { 329 wm::WindowState* window_state) {
491 DCHECK(!window_state->is_dragged()); 330 DCHECK(!window_state->is_dragged());
492 331
493 if (window_state->IsMaximized()) { 332 if (window_state->IsMaximized()) {
494 SetChildBoundsDirect( 333 SetChildBoundsDirect(
495 window_state->window(), ScreenUtil::GetMaximizedWindowBoundsInParent( 334 window_state->window(), ScreenUtil::GetMaximizedWindowBoundsInParent(
496 window_state->window())); 335 window_state->window()));
497 return true; 336 return true;
498 } 337 }
499 if (window_state->IsFullscreen()) { 338 if (window_state->IsFullscreen()) {
500 SetChildBoundsDirect( 339 SetChildBoundsDirect(
501 window_state->window(), 340 window_state->window(),
502 ScreenUtil::GetDisplayBoundsInParent(window_state->window())); 341 ScreenUtil::GetDisplayBoundsInParent(window_state->window()));
503 return true; 342 return true;
504 } 343 }
505 return false; 344 return false;
506 } 345 }
507 346
508 void WorkspaceLayoutManager::AdjustSnappedBounds(wm::WindowState* window_state,
509 gfx::Rect* bounds) {
510 if (window_state->is_dragged() || !window_state->IsSnapped())
511 return;
512 gfx::Rect maximized_bounds = ScreenUtil::GetMaximizedWindowBoundsInParent(
513 window_state->window());
514 if (window_state->window_show_type() == wm::SHOW_TYPE_LEFT_SNAPPED)
515 bounds->set_x(maximized_bounds.x());
516 else if (window_state->window_show_type() == wm::SHOW_TYPE_RIGHT_SNAPPED)
517 bounds->set_x(maximized_bounds.right() - bounds->width());
518 bounds->set_y(maximized_bounds.y());
519 // TODO(varkha): Set width to 50% here for snapped windows.
520 bounds->set_height(maximized_bounds.height());
521 }
522
523 void WorkspaceLayoutManager::SetChildBoundsAnimated(Window* child,
524 const gfx::Rect& bounds) {
525 const int kBoundsChangeSlideDurationMs = 120;
526
527 ui::Layer* layer = child->layer();
528 ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator());
529 slide_settings.SetPreemptionStrategy(
530 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
531 slide_settings.SetTransitionDuration(
532 base::TimeDelta::FromMilliseconds(kBoundsChangeSlideDurationMs));
533 SetChildBoundsDirect(child, bounds);
534 }
535
536 } // namespace internal 347 } // namespace internal
537 } // namespace ash 348 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/workspace/workspace_layout_manager.h ('k') | ash/wm/workspace/workspace_layout_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698