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

Side by Side Diff: ash/wm/common/dock/docked_window_layout_manager.cc

Issue 1921353002: Moves handful of files to ash/wm/common (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@shell_ids
Patch Set: merge to trunk Created 4 years, 8 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/dock/docked_window_layout_manager.h" 5 #include "ash/wm/common/dock/docked_window_layout_manager.h"
6 6
7 #include "ash/wm/common/shelf/wm_shelf.h" 7 #include "ash/wm/common/shelf/wm_shelf.h"
8 #include "ash/wm/common/shelf/wm_shelf_constants.h" 8 #include "ash/wm/common/shelf/wm_shelf_constants.h"
9 #include "ash/wm/common/shelf/wm_shelf_observer.h" 9 #include "ash/wm/common/shelf/wm_shelf_observer.h"
10 #include "ash/wm/common/window_animation_types.h" 10 #include "ash/wm/common/window_animation_types.h"
11 #include "ash/wm/common/window_parenting_utils.h" 11 #include "ash/wm/common/window_parenting_utils.h"
12 #include "ash/wm/common/window_resizer.h"
13 #include "ash/wm/common/window_state.h"
12 #include "ash/wm/common/wm_globals.h" 14 #include "ash/wm/common/wm_globals.h"
13 #include "ash/wm/common/wm_root_window_controller.h" 15 #include "ash/wm/common/wm_root_window_controller.h"
14 #include "ash/wm/common/wm_shell_window_ids.h" 16 #include "ash/wm/common/wm_shell_window_ids.h"
15 #include "ash/wm/common/wm_window.h" 17 #include "ash/wm/common/wm_window.h"
16 #include "ash/wm/window_resizer.h"
17 #include "ash/wm/window_state.h"
18 #include "base/auto_reset.h" 18 #include "base/auto_reset.h"
19 #include "base/metrics/histogram.h" 19 #include "base/metrics/histogram.h"
20 #include "grit/ash_resources.h" 20 #include "grit/ash_resources.h"
21 #include "third_party/skia/include/core/SkColor.h" 21 #include "third_party/skia/include/core/SkColor.h"
22 #include "third_party/skia/include/core/SkPaint.h" 22 #include "third_party/skia/include/core/SkPaint.h"
23 #include "ui/base/resource/resource_bundle.h" 23 #include "ui/base/resource/resource_bundle.h"
24 #include "ui/compositor/paint_recorder.h" 24 #include "ui/compositor/paint_recorder.h"
25 #include "ui/compositor/scoped_layer_animation_settings.h" 25 #include "ui/compositor/scoped_layer_animation_settings.h"
26 #include "ui/gfx/canvas.h" 26 #include "ui/gfx/canvas.h"
27 #include "ui/gfx/display.h" 27 #include "ui/gfx/display.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 private: 74 private:
75 // views::Widget: 75 // views::Widget:
76 void OnNativeWidgetVisibilityChanged(bool visible) override { 76 void OnNativeWidgetVisibilityChanged(bool visible) override {
77 views::Widget::OnNativeWidgetVisibilityChanged(visible); 77 views::Widget::OnNativeWidgetVisibilityChanged(visible);
78 UpdateBackground(); 78 UpdateBackground();
79 } 79 }
80 80
81 void OnNativeWidgetPaint(const ui::PaintContext& context) override { 81 void OnNativeWidgetPaint(const ui::PaintContext& context) override {
82 gfx::Rect local_window_bounds(GetWindowBoundsInScreen().size()); 82 gfx::Rect local_window_bounds(GetWindowBoundsInScreen().size());
83 ui::PaintRecorder recorder(context, local_window_bounds.size()); 83 ui::PaintRecorder recorder(context, local_window_bounds.size());
84 const gfx::ImageSkia& shelf_background( 84 const gfx::ImageSkia& shelf_background(alignment_ == DOCKED_ALIGNMENT_LEFT
85 alignment_ == DOCKED_ALIGNMENT_LEFT ? 85 ? shelf_background_left_
86 shelf_background_left_ : shelf_background_right_); 86 : shelf_background_right_);
87 SkPaint paint; 87 SkPaint paint;
88 paint.setAlpha(alpha_); 88 paint.setAlpha(alpha_);
89 recorder.canvas()->DrawImageInt( 89 recorder.canvas()->DrawImageInt(
90 shelf_background, 0, 0, shelf_background.width(), 90 shelf_background, 0, 0, shelf_background.width(),
91 shelf_background.height(), 91 shelf_background.height(),
92 alignment_ == DOCKED_ALIGNMENT_LEFT 92 alignment_ == DOCKED_ALIGNMENT_LEFT
93 ? local_window_bounds.width() - shelf_background.width() 93 ? local_window_bounds.width() - shelf_background.width()
94 : 0, 94 : 0,
95 0, shelf_background.width(), local_window_bounds.height(), false, 95 0, shelf_background.width(), local_window_bounds.height(), false,
96 paint); 96 paint);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 // added to the container, and UpdateStacking only manages user windows, not 153 // added to the container, and UpdateStacking only manages user windows, not
154 // the background widget. 154 // the background widget.
155 parent->StackChildAtBottom(wm_window); 155 parent->StackChildAtBottom(wm_window);
156 } 156 }
157 157
158 // Transitions to |visible_background_type_| if the widget is visible and to 158 // Transitions to |visible_background_type_| if the widget is visible and to
159 // SHELF_BACKGROUND_DEFAULT if it is not. 159 // SHELF_BACKGROUND_DEFAULT if it is not.
160 void UpdateBackground() { 160 void UpdateBackground() {
161 wm::ShelfBackgroundType background_type = 161 wm::ShelfBackgroundType background_type =
162 IsVisible() ? visible_background_type_ : wm::SHELF_BACKGROUND_DEFAULT; 162 IsVisible() ? visible_background_type_ : wm::SHELF_BACKGROUND_DEFAULT;
163 BackgroundAnimatorChangeType change_type = IsVisible() ? 163 BackgroundAnimatorChangeType change_type =
164 visible_background_change_type_ : BACKGROUND_CHANGE_IMMEDIATE; 164 IsVisible() ? visible_background_change_type_
165 : BACKGROUND_CHANGE_IMMEDIATE;
165 166
166 float target_opacity = 167 float target_opacity =
167 (background_type == wm::SHELF_BACKGROUND_MAXIMIZED) ? 1.0f : 0.0f; 168 (background_type == wm::SHELF_BACKGROUND_MAXIMIZED) ? 1.0f : 0.0f;
168 std::unique_ptr<ui::ScopedLayerAnimationSettings> 169 std::unique_ptr<ui::ScopedLayerAnimationSettings>
169 opaque_background_animation; 170 opaque_background_animation;
170 if (change_type != BACKGROUND_CHANGE_IMMEDIATE) { 171 if (change_type != BACKGROUND_CHANGE_IMMEDIATE) {
171 opaque_background_animation.reset(new ui::ScopedLayerAnimationSettings( 172 opaque_background_animation.reset(new ui::ScopedLayerAnimationSettings(
172 opaque_background_.GetAnimator())); 173 opaque_background_.GetAnimator()));
173 opaque_background_animation->SetTransitionDuration( 174 opaque_background_animation->SetTransitionDuration(
174 base::TimeDelta::FromMilliseconds(wm::kTimeToSwitchBackgroundMs)); 175 base::TimeDelta::FromMilliseconds(wm::kTimeToSwitchBackgroundMs));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 241
241 // Returns width that is as close as possible to |target_width| while being 242 // Returns width that is as close as possible to |target_width| while being
242 // consistent with docked min and max restrictions and respects the |window|'s 243 // consistent with docked min and max restrictions and respects the |window|'s
243 // minimum and maximum size. 244 // minimum and maximum size.
244 int GetWindowWidthCloseTo(const wm::WmWindow* window, int target_width) { 245 int GetWindowWidthCloseTo(const wm::WmWindow* window, int target_width) {
245 if (!window->GetWindowState()->CanResize()) { 246 if (!window->GetWindowState()->CanResize()) {
246 DCHECK_LE(window->GetBounds().width(), 247 DCHECK_LE(window->GetBounds().width(),
247 DockedWindowLayoutManager::kMaxDockWidth); 248 DockedWindowLayoutManager::kMaxDockWidth);
248 return window->GetBounds().width(); 249 return window->GetBounds().width();
249 } 250 }
250 int width = std::max(DockedWindowLayoutManager::kMinDockWidth, 251 int width = std::max(
251 std::min(target_width, 252 DockedWindowLayoutManager::kMinDockWidth,
252 DockedWindowLayoutManager::kMaxDockWidth)); 253 std::min(target_width, DockedWindowLayoutManager::kMaxDockWidth));
253 width = std::max(width, window->GetMinimumSize().width()); 254 width = std::max(width, window->GetMinimumSize().width());
254 if (window->GetMaximumSize().width() != 0) 255 if (window->GetMaximumSize().width() != 0)
255 width = std::min(width, window->GetMaximumSize().width()); 256 width = std::min(width, window->GetMaximumSize().width());
256 DCHECK_LE(width, DockedWindowLayoutManager::kMaxDockWidth); 257 DCHECK_LE(width, DockedWindowLayoutManager::kMaxDockWidth);
257 return width; 258 return width;
258 } 259 }
259 260
260 // Returns height that is as close as possible to |target_height| while 261 // Returns height that is as close as possible to |target_height| while
261 // respecting the |window|'s minimum and maximum size. 262 // respecting the |window|'s minimum and maximum size.
262 int GetWindowHeightCloseTo(const wm::WmWindow* window, int target_height) { 263 int GetWindowHeightCloseTo(const wm::WmWindow* window, int target_height) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 wm::WmWindow* dragged_window_; 354 wm::WmWindow* dragged_window_;
354 wm::WmWindow* docked_container_; 355 wm::WmWindow* docked_container_;
355 float delta_; 356 float delta_;
356 }; 357 };
357 358
358 //////////////////////////////////////////////////////////////////////////////// 359 ////////////////////////////////////////////////////////////////////////////////
359 // A class that observes shelf for bounds changes. 360 // A class that observes shelf for bounds changes.
360 class DockedWindowLayoutManager::ShelfWindowObserver 361 class DockedWindowLayoutManager::ShelfWindowObserver
361 : public wm::WmWindowObserver { 362 : public wm::WmWindowObserver {
362 public: 363 public:
363 explicit ShelfWindowObserver( 364 explicit ShelfWindowObserver(DockedWindowLayoutManager* docked_layout_manager)
364 DockedWindowLayoutManager* docked_layout_manager)
365 : docked_layout_manager_(docked_layout_manager) { 365 : docked_layout_manager_(docked_layout_manager) {
366 DCHECK(docked_layout_manager_->shelf()->GetWindow()); 366 DCHECK(docked_layout_manager_->shelf()->GetWindow());
367 docked_layout_manager_->shelf()->GetWindow()->AddObserver(this); 367 docked_layout_manager_->shelf()->GetWindow()->AddObserver(this);
368 } 368 }
369 369
370 ~ShelfWindowObserver() override { 370 ~ShelfWindowObserver() override {
371 if (docked_layout_manager_->shelf() && 371 if (docked_layout_manager_->shelf() &&
372 docked_layout_manager_->shelf()->GetWindow()) { 372 docked_layout_manager_->shelf()->GetWindow()) {
373 docked_layout_manager_->shelf()->GetWindow()->RemoveObserver(this); 373 docked_layout_manager_->shelf()->GetWindow()->RemoveObserver(this);
374 } 374 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 void DockedWindowLayoutManager::StartDragging(wm::WmWindow* window) { 460 void DockedWindowLayoutManager::StartDragging(wm::WmWindow* window) {
461 DCHECK(!dragged_window_); 461 DCHECK(!dragged_window_);
462 dragged_window_ = window; 462 dragged_window_ = window;
463 DCHECK(!IsPopupOrTransient(window)); 463 DCHECK(!IsPopupOrTransient(window));
464 // Start observing a window unless it is docked container's child in which 464 // Start observing a window unless it is docked container's child in which
465 // case it is already observed. 465 // case it is already observed.
466 wm::WindowState* dragged_state = dragged_window_->GetWindowState(); 466 wm::WindowState* dragged_state = dragged_window_->GetWindowState();
467 if (dragged_window_->GetParent() != dock_container_) { 467 if (dragged_window_->GetParent() != dock_container_) {
468 dragged_window_->AddObserver(this); 468 dragged_window_->AddObserver(this);
469 dragged_state->AddObserver(this); 469 dragged_state->AddObserver(this);
470 } else if (!IsAnyWindowDocked() && 470 } else if (!IsAnyWindowDocked() && dragged_state->drag_details() &&
471 dragged_state->drag_details() &&
472 !(dragged_state->drag_details()->bounds_change & 471 !(dragged_state->drag_details()->bounds_change &
473 WindowResizer::kBoundsChange_Resizes)) { 472 WindowResizer::kBoundsChange_Resizes)) {
474 // If there are no other docked windows clear alignment when a docked window 473 // If there are no other docked windows clear alignment when a docked window
475 // is moved (but not when it is resized or the window could get undocked 474 // is moved (but not when it is resized or the window could get undocked
476 // when resized away from the edge while docked). 475 // when resized away from the edge while docked).
477 alignment_ = DOCKED_ALIGNMENT_NONE; 476 alignment_ = DOCKED_ALIGNMENT_NONE;
478 } 477 }
479 is_dragged_from_dock_ = window->GetParent() == dock_container_; 478 is_dragged_from_dock_ = window->GetParent() == dock_container_;
480 DCHECK(!is_dragged_window_docked_); 479 DCHECK(!is_dragged_window_docked_);
481 480
482 // Resize all windows that are flush with the dock edge together if one of 481 // Resize all windows that are flush with the dock edge together if one of
483 // them gets resized. 482 // them gets resized.
(...skipping 24 matching lines...) Expand all
508 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); 507 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED);
509 is_dragged_from_dock_ = false; 508 is_dragged_from_dock_ = false;
510 } 509 }
511 510
512 void DockedWindowLayoutManager::FinishDragging(DockedAction action, 511 void DockedWindowLayoutManager::FinishDragging(DockedAction action,
513 DockedActionSource source) { 512 DockedActionSource source) {
514 DCHECK(dragged_window_); 513 DCHECK(dragged_window_);
515 DCHECK(!IsPopupOrTransient(dragged_window_)); 514 DCHECK(!IsPopupOrTransient(dragged_window_));
516 if (is_dragged_window_docked_) 515 if (is_dragged_window_docked_)
517 OnDraggedWindowUndocked(); 516 OnDraggedWindowUndocked();
518 DCHECK (!is_dragged_window_docked_); 517 DCHECK(!is_dragged_window_docked_);
519 // Stop observing a window unless it is docked container's child in which 518 // Stop observing a window unless it is docked container's child in which
520 // case it needs to keep being observed after the drag completes. 519 // case it needs to keep being observed after the drag completes.
521 if (dragged_window_->GetParent() != dock_container_) { 520 if (dragged_window_->GetParent() != dock_container_) {
522 dragged_window_->RemoveObserver(this); 521 dragged_window_->RemoveObserver(this);
523 dragged_window_->GetWindowState()->RemoveObserver(this); 522 dragged_window_->GetWindowState()->RemoveObserver(this);
524 if (last_active_window_ == dragged_window_) 523 if (last_active_window_ == dragged_window_)
525 last_active_window_ = nullptr; 524 last_active_window_ = nullptr;
526 } else { 525 } else {
527 // If this is the first window that got docked by a move update alignment. 526 // If this is the first window that got docked by a move update alignment.
528 if (alignment_ == DOCKED_ALIGNMENT_NONE) 527 if (alignment_ == DOCKED_ALIGNMENT_NONE)
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 return DOCKED_ALIGNMENT_NONE; 586 return DOCKED_ALIGNMENT_NONE;
588 } 587 }
589 588
590 bool DockedWindowLayoutManager::CanDockWindow( 589 bool DockedWindowLayoutManager::CanDockWindow(
591 wm::WmWindow* window, 590 wm::WmWindow* window,
592 DockedAlignment desired_alignment) { 591 DockedAlignment desired_alignment) {
593 // Don't allow interactive docking of windows with transient parents such as 592 // Don't allow interactive docking of windows with transient parents such as
594 // modal browser dialogs. Prevent docking of panels attached to shelf during 593 // modal browser dialogs. Prevent docking of panels attached to shelf during
595 // the drag. 594 // the drag.
596 wm::WindowState* window_state = window->GetWindowState(); 595 wm::WindowState* window_state = window->GetWindowState();
597 bool should_attach_to_shelf = window_state->drag_details() && 596 bool should_attach_to_shelf =
597 window_state->drag_details() &&
598 window_state->drag_details()->should_attach_to_shelf; 598 window_state->drag_details()->should_attach_to_shelf;
599 if (IsPopupOrTransient(window) || should_attach_to_shelf) 599 if (IsPopupOrTransient(window) || should_attach_to_shelf)
600 return false; 600 return false;
601 // If a window is wide and cannot be resized down to maximum width allowed 601 // If a window is wide and cannot be resized down to maximum width allowed
602 // then it cannot be docked. 602 // then it cannot be docked.
603 // TODO(varkha). Prevent windows from changing size programmatically while 603 // TODO(varkha). Prevent windows from changing size programmatically while
604 // they are docked. The size will take effect only once a window is undocked. 604 // they are docked. The size will take effect only once a window is undocked.
605 // See http://crbug.com/307792. 605 // See http://crbug.com/307792.
606 if (window->GetBounds().width() > kMaxDockWidth && 606 if (window->GetBounds().width() > kMaxDockWidth &&
607 (!window_state->CanResize() || 607 (!window_state->CanResize() ||
608 (window->GetMinimumSize().width() != 0 && 608 (window->GetMinimumSize().width() != 0 &&
609 window->GetMinimumSize().width() > kMaxDockWidth))) { 609 window->GetMinimumSize().width() > kMaxDockWidth))) {
610 return false; 610 return false;
611 } 611 }
612 // If a window is tall and cannot be resized down to maximum height allowed 612 // If a window is tall and cannot be resized down to maximum height allowed
613 // then it cannot be docked. 613 // then it cannot be docked.
614 const gfx::Rect work_area = 614 const gfx::Rect work_area =
615 dock_container_->GetDisplayNearestWindow().work_area(); 615 dock_container_->GetDisplayNearestWindow().work_area();
616 if (GetWindowHeightCloseTo(window, work_area.height()) > work_area.height()) 616 if (GetWindowHeightCloseTo(window, work_area.height()) > work_area.height())
617 return false; 617 return false;
618 // Cannot dock on the other size from an existing dock. 618 // Cannot dock on the other size from an existing dock.
619 const DockedAlignment alignment = CalculateAlignmentExcept(window); 619 const DockedAlignment alignment = CalculateAlignmentExcept(window);
620 if (desired_alignment != DOCKED_ALIGNMENT_NONE && 620 if (desired_alignment != DOCKED_ALIGNMENT_NONE &&
621 alignment != DOCKED_ALIGNMENT_NONE && 621 alignment != DOCKED_ALIGNMENT_NONE && alignment != desired_alignment) {
622 alignment != desired_alignment) {
623 return false; 622 return false;
624 } 623 }
625 // Do not allow docking on the same side as shelf. 624 // Do not allow docking on the same side as shelf.
626 return IsDockedAlignmentValid(desired_alignment); 625 return IsDockedAlignmentValid(desired_alignment);
627 } 626 }
628 627
629 bool DockedWindowLayoutManager::IsDockedAlignmentValid( 628 bool DockedWindowLayoutManager::IsDockedAlignmentValid(
630 DockedAlignment alignment) const { 629 DockedAlignment alignment) const {
631 wm::ShelfAlignment shelf_alignment = 630 wm::ShelfAlignment shelf_alignment =
632 shelf_ ? shelf_->GetAlignment() : wm::SHELF_ALIGNMENT_BOTTOM; 631 shelf_ ? shelf_->GetAlignment() : wm::SHELF_ALIGNMENT_BOTTOM;
633 if ((alignment == DOCKED_ALIGNMENT_LEFT && 632 if ((alignment == DOCKED_ALIGNMENT_LEFT &&
634 shelf_alignment == wm::SHELF_ALIGNMENT_LEFT) || 633 shelf_alignment == wm::SHELF_ALIGNMENT_LEFT) ||
635 (alignment == DOCKED_ALIGNMENT_RIGHT && 634 (alignment == DOCKED_ALIGNMENT_RIGHT &&
636 shelf_alignment == wm::SHELF_ALIGNMENT_RIGHT)) { 635 shelf_alignment == wm::SHELF_ALIGNMENT_RIGHT)) {
637 return false; 636 return false;
638 } 637 }
639 return true; 638 return true;
640 } 639 }
641 640
642 void DockedWindowLayoutManager::MaybeSetDesiredDockedAlignment( 641 void DockedWindowLayoutManager::MaybeSetDesiredDockedAlignment(
643 DockedAlignment alignment) { 642 DockedAlignment alignment) {
644 // If the requested alignment is |NONE| or there are no 643 // If the requested alignment is |NONE| or there are no
645 // docked windows return early as we can't change whether there is a 644 // docked windows return early as we can't change whether there is a
646 // dock or not. If the requested alignment is the same as the current 645 // dock or not. If the requested alignment is the same as the current
647 // alignment return early as an optimization. 646 // alignment return early as an optimization.
648 if (alignment == DOCKED_ALIGNMENT_NONE || 647 if (alignment == DOCKED_ALIGNMENT_NONE ||
649 alignment_ == DOCKED_ALIGNMENT_NONE || 648 alignment_ == DOCKED_ALIGNMENT_NONE || alignment_ == alignment ||
650 alignment_ == alignment ||
651 !IsDockedAlignmentValid(alignment)) { 649 !IsDockedAlignmentValid(alignment)) {
652 return; 650 return;
653 } 651 }
654 alignment_ = alignment; 652 alignment_ = alignment;
655 653
656 Relayout(); 654 Relayout();
657 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); 655 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED);
658 } 656 }
659 657
660 void DockedWindowLayoutManager::OnShelfBoundsChanged() { 658 void DockedWindowLayoutManager::OnShelfBoundsChanged() {
(...skipping 16 matching lines...) Expand all
677 return; 675 return;
678 // Dragged windows are already observed by StartDragging and do not change 676 // Dragged windows are already observed by StartDragging and do not change
679 // docked alignment during the drag. 677 // docked alignment during the drag.
680 if (child == dragged_window_) 678 if (child == dragged_window_)
681 return; 679 return;
682 // If this is the first window getting docked - update alignment. 680 // If this is the first window getting docked - update alignment.
683 // A window can be added without proper bounds when window is moved to another 681 // A window can be added without proper bounds when window is moved to another
684 // display via API or due to display configuration change, so the alignment 682 // display via API or due to display configuration change, so the alignment
685 // is set based on which edge is closer in the new display. 683 // is set based on which edge is closer in the new display.
686 if (alignment_ == DOCKED_ALIGNMENT_NONE) { 684 if (alignment_ == DOCKED_ALIGNMENT_NONE) {
687 alignment_ = preferred_alignment_ != DOCKED_ALIGNMENT_NONE ? 685 alignment_ = preferred_alignment_ != DOCKED_ALIGNMENT_NONE
688 preferred_alignment_ : GetEdgeNearestWindow(child); 686 ? preferred_alignment_
687 : GetEdgeNearestWindow(child);
689 } 688 }
690 MaybeMinimizeChildrenExcept(child); 689 MaybeMinimizeChildrenExcept(child);
691 child->AddObserver(this); 690 child->AddObserver(this);
692 child->GetWindowState()->AddObserver(this); 691 child->GetWindowState()->AddObserver(this);
693 Relayout(); 692 Relayout();
694 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); 693 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED);
695 694
696 // Only keyboard-initiated actions are recorded here. Dragging cases 695 // Only keyboard-initiated actions are recorded here. Dragging cases
697 // are handled in FinishDragging. 696 // are handled in FinishDragging.
698 if (event_source_ != DOCKED_ACTION_SOURCE_UNKNOWN) 697 if (event_source_ != DOCKED_ACTION_SOURCE_UNKNOWN)
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 int available_room = work_area.height(); 906 int available_room = work_area.height();
908 bool gap_needed = !!child; 907 bool gap_needed = !!child;
909 if (child) 908 if (child)
910 available_room -= GetWindowHeightCloseTo(child, 0); 909 available_room -= GetWindowHeightCloseTo(child, 0);
911 // Use a copy of children array because a call to Minimize can change order. 910 // Use a copy of children array because a call to Minimize can change order.
912 std::vector<wm::WmWindow*> children(dock_container_->GetChildren()); 911 std::vector<wm::WmWindow*> children(dock_container_->GetChildren());
913 for (auto iter = children.rbegin(); iter != children.rend(); ++iter) { 912 for (auto iter = children.rbegin(); iter != children.rend(); ++iter) {
914 wm::WmWindow* window(*iter); 913 wm::WmWindow* window(*iter);
915 if (window == child || !IsWindowDocked(window)) 914 if (window == child || !IsWindowDocked(window))
916 continue; 915 continue;
917 int room_needed = GetWindowHeightCloseTo(window, 0) + 916 int room_needed =
918 (gap_needed ? kMinDockGap : 0); 917 GetWindowHeightCloseTo(window, 0) + (gap_needed ? kMinDockGap : 0);
919 gap_needed = true; 918 gap_needed = true;
920 if (available_room > room_needed) { 919 if (available_room > room_needed) {
921 available_room -= room_needed; 920 available_room -= room_needed;
922 } else { 921 } else {
923 // Slow down minimizing animations. Lock duration so that it is not 922 // Slow down minimizing animations. Lock duration so that it is not
924 // overridden by other ScopedLayerAnimationSettings down the stack. 923 // overridden by other ScopedLayerAnimationSettings down the stack.
925 ui::ScopedLayerAnimationSettings settings( 924 ui::ScopedLayerAnimationSettings settings(
926 window->GetLayer()->GetAnimator()); 925 window->GetLayer()->GetAnimator());
927 settings.SetTransitionDuration( 926 settings.SetTransitionDuration(
928 base::TimeDelta::FromMilliseconds(kMinimizeDurationMs)); 927 base::TimeDelta::FromMilliseconds(kMinimizeDurationMs));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 void DockedWindowLayoutManager::RecordUmaAction(DockedAction action, 968 void DockedWindowLayoutManager::RecordUmaAction(DockedAction action,
970 DockedActionSource source) { 969 DockedActionSource source) {
971 if (action == DOCKED_ACTION_NONE) 970 if (action == DOCKED_ACTION_NONE)
972 return; 971 return;
973 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.Action", action, DOCKED_ACTION_COUNT); 972 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.Action", action, DOCKED_ACTION_COUNT);
974 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.ActionSource", source, 973 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.ActionSource", source,
975 DOCKED_ACTION_SOURCE_COUNT); 974 DOCKED_ACTION_SOURCE_COUNT);
976 base::Time time_now = base::Time::Now(); 975 base::Time time_now = base::Time::Now();
977 base::TimeDelta time_between_use = time_now - last_action_time_; 976 base::TimeDelta time_between_use = time_now - last_action_time_;
978 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.Dock.TimeBetweenUse", 977 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.Dock.TimeBetweenUse",
979 time_between_use.InSeconds(), 978 time_between_use.InSeconds(), 1,
980 1, 979 base::TimeDelta::FromHours(10).InSeconds(), 100);
981 base::TimeDelta::FromHours(10).InSeconds(),
982 100);
983 last_action_time_ = time_now; 980 last_action_time_ = time_now;
984 int docked_all_count = 0; 981 int docked_all_count = 0;
985 int docked_visible_count = 0; 982 int docked_visible_count = 0;
986 int docked_panels_count = 0; 983 int docked_panels_count = 0;
987 int large_windows_count = 0; 984 int large_windows_count = 0;
988 for (wm::WmWindow* window : dock_container_->GetChildren()) { 985 for (wm::WmWindow* window : dock_container_->GetChildren()) {
989 if (IsPopupOrTransient(window)) 986 if (IsPopupOrTransient(window))
990 continue; 987 continue;
991 docked_all_count++; 988 docked_all_count++;
992 if (!IsWindowDocked(window)) 989 if (!IsWindowDocked(window))
(...skipping 20 matching lines...) Expand all
1013 docked_width_ = width; 1010 docked_width_ = width;
1014 UMA_HISTOGRAM_COUNTS_10000("Ash.Dock.Width", docked_width_); 1011 UMA_HISTOGRAM_COUNTS_10000("Ash.Dock.Width", docked_width_);
1015 } 1012 }
1016 1013
1017 void DockedWindowLayoutManager::OnDraggedWindowDocked(wm::WmWindow* window) { 1014 void DockedWindowLayoutManager::OnDraggedWindowDocked(wm::WmWindow* window) {
1018 DCHECK(!is_dragged_window_docked_); 1015 DCHECK(!is_dragged_window_docked_);
1019 is_dragged_window_docked_ = true; 1016 is_dragged_window_docked_ = true;
1020 } 1017 }
1021 1018
1022 void DockedWindowLayoutManager::OnDraggedWindowUndocked() { 1019 void DockedWindowLayoutManager::OnDraggedWindowUndocked() {
1023 DCHECK (is_dragged_window_docked_); 1020 DCHECK(is_dragged_window_docked_);
1024 is_dragged_window_docked_ = false; 1021 is_dragged_window_docked_ = false;
1025 } 1022 }
1026 1023
1027 bool DockedWindowLayoutManager::IsAnyWindowDocked() { 1024 bool DockedWindowLayoutManager::IsAnyWindowDocked() {
1028 return CalculateAlignment() != DOCKED_ALIGNMENT_NONE; 1025 return CalculateAlignment() != DOCKED_ALIGNMENT_NONE;
1029 } 1026 }
1030 1027
1031 DockedAlignment DockedWindowLayoutManager::GetEdgeNearestWindow( 1028 DockedAlignment DockedWindowLayoutManager::GetEdgeNearestWindow(
1032 const wm::WmWindow* window) const { 1029 const wm::WmWindow* window) const {
1033 const gfx::Rect bounds(window->GetBoundsInScreen()); 1030 const gfx::Rect bounds(window->GetBoundsInScreen());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 if (is_dragged_window_docked_) { 1071 if (is_dragged_window_docked_) {
1075 visible_windows.push_back(WindowWithHeight(dragged_window_)); 1072 visible_windows.push_back(WindowWithHeight(dragged_window_));
1076 DCHECK(!active_window); 1073 DCHECK(!active_window);
1077 active_window = dragged_window_; 1074 active_window = dragged_window_;
1078 } 1075 }
1079 1076
1080 // Position docked windows as well as the window being dragged. 1077 // Position docked windows as well as the window being dragged.
1081 gfx::Rect work_area = dock_container_->GetDisplayNearestWindow().work_area(); 1078 gfx::Rect work_area = dock_container_->GetDisplayNearestWindow().work_area();
1082 if (shelf_observer_) 1079 if (shelf_observer_)
1083 work_area.Subtract(shelf_observer_->shelf_bounds_in_screen()); 1080 work_area.Subtract(shelf_observer_->shelf_bounds_in_screen());
1084 int available_room = CalculateWindowHeightsAndRemainingRoom(work_area, 1081 int available_room =
1085 &visible_windows); 1082 CalculateWindowHeightsAndRemainingRoom(work_area, &visible_windows);
1086 FanOutChildren(work_area, 1083 FanOutChildren(work_area, CalculateIdealWidth(visible_windows),
1087 CalculateIdealWidth(visible_windows), 1084 available_room, &visible_windows);
1088 available_room,
1089 &visible_windows);
1090 1085
1091 // After the first Relayout allow the windows to change their order easier 1086 // After the first Relayout allow the windows to change their order easier
1092 // since we know they are docked. 1087 // since we know they are docked.
1093 is_dragged_from_dock_ = true; 1088 is_dragged_from_dock_ = true;
1094 UpdateStacking(active_window); 1089 UpdateStacking(active_window);
1095 } 1090 }
1096 1091
1097 int DockedWindowLayoutManager::CalculateWindowHeightsAndRemainingRoom( 1092 int DockedWindowLayoutManager::CalculateWindowHeightsAndRemainingRoom(
1098 const gfx::Rect& work_area, 1093 const gfx::Rect& work_area,
1099 std::vector<WindowWithHeight>* visible_windows) { 1094 std::vector<WindowWithHeight>* visible_windows) {
1100 int available_room = work_area.height(); 1095 int available_room = work_area.height();
1101 int remaining_windows = visible_windows->size(); 1096 int remaining_windows = visible_windows->size();
1102 int gap_height = remaining_windows > 1 ? kMinDockGap : 0; 1097 int gap_height = remaining_windows > 1 ? kMinDockGap : 0;
1103 1098
1104 // Sort windows by their minimum heights and calculate target heights. 1099 // Sort windows by their minimum heights and calculate target heights.
1105 std::sort(visible_windows->begin(), visible_windows->end(), 1100 std::sort(visible_windows->begin(), visible_windows->end(),
1106 CompareMinimumHeight()); 1101 CompareMinimumHeight());
1107 // Distribute the free space among the docked windows. Since the windows are 1102 // Distribute the free space among the docked windows. Since the windows are
1108 // sorted (tall windows first) we can now assume that any window which 1103 // sorted (tall windows first) we can now assume that any window which
1109 // required more space than the current window will have already been 1104 // required more space than the current window will have already been
1110 // accounted for previously in this loop, so we can safely give that window 1105 // accounted for previously in this loop, so we can safely give that window
1111 // its proportional share of the remaining space. 1106 // its proportional share of the remaining space.
1112 for (std::vector<WindowWithHeight>::reverse_iterator iter = 1107 for (std::vector<WindowWithHeight>::reverse_iterator iter =
1113 visible_windows->rbegin(); 1108 visible_windows->rbegin();
1114 iter != visible_windows->rend(); ++iter) { 1109 iter != visible_windows->rend(); ++iter) {
1115 iter->height = GetWindowHeightCloseTo( 1110 iter->height = GetWindowHeightCloseTo(
1116 iter->window, 1111 iter->window,
1117 (available_room + gap_height) / remaining_windows - gap_height); 1112 (available_room + gap_height) / remaining_windows - gap_height);
1118 available_room -= (iter->height + gap_height); 1113 available_room -= (iter->height + gap_height);
1119 remaining_windows--; 1114 remaining_windows--;
1120 } 1115 }
1121 return available_room + gap_height; 1116 return available_room + gap_height;
1122 } 1117 }
1123 1118
1124 int DockedWindowLayoutManager::CalculateIdealWidth( 1119 int DockedWindowLayoutManager::CalculateIdealWidth(
(...skipping 10 matching lines...) Expand all
1135 const wm::WmWindow* window = iter->window; 1130 const wm::WmWindow* window = iter->window;
1136 int min_window_width = window->GetBounds().width(); 1131 int min_window_width = window->GetBounds().width();
1137 int max_window_width = min_window_width; 1132 int max_window_width = min_window_width;
1138 if (!window->GetWindowState()->bounds_changed_by_user()) { 1133 if (!window->GetWindowState()->bounds_changed_by_user()) {
1139 min_window_width = GetWindowWidthCloseTo(window, kMinDockWidth); 1134 min_window_width = GetWindowWidthCloseTo(window, kMinDockWidth);
1140 max_window_width = GetWindowWidthCloseTo(window, kMaxDockWidth); 1135 max_window_width = GetWindowWidthCloseTo(window, kMaxDockWidth);
1141 } 1136 }
1142 largest_min_width = std::max(largest_min_width, min_window_width); 1137 largest_min_width = std::max(largest_min_width, min_window_width);
1143 smallest_max_width = std::min(smallest_max_width, max_window_width); 1138 smallest_max_width = std::min(smallest_max_width, max_window_width);
1144 } 1139 }
1145 int ideal_width = std::max(largest_min_width, 1140 int ideal_width =
1146 std::min(smallest_max_width, kIdealWidth)); 1141 std::max(largest_min_width, std::min(smallest_max_width, kIdealWidth));
1147 // Restrict docked area width regardless of window restrictions. 1142 // Restrict docked area width regardless of window restrictions.
1148 ideal_width = std::max(std::min(ideal_width, kMaxDockWidth), kMinDockWidth); 1143 ideal_width = std::max(std::min(ideal_width, kMaxDockWidth), kMinDockWidth);
1149 return ideal_width; 1144 return ideal_width;
1150 } 1145 }
1151 1146
1152 void DockedWindowLayoutManager::FanOutChildren( 1147 void DockedWindowLayoutManager::FanOutChildren(
1153 const gfx::Rect& work_area, 1148 const gfx::Rect& work_area,
1154 int ideal_docked_width, 1149 int ideal_docked_width,
1155 int available_room, 1150 int available_room,
1156 std::vector<WindowWithHeight>* visible_windows) { 1151 std::vector<WindowWithHeight>* visible_windows) {
1157 gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen(); 1152 gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen();
1158 1153
1159 // Calculate initial vertical offset and the gap or overlap between windows. 1154 // Calculate initial vertical offset and the gap or overlap between windows.
1160 const int num_windows = visible_windows->size(); 1155 const int num_windows = visible_windows->size();
1161 const float delta = static_cast<float>(available_room) / 1156 const float delta =
1162 ((available_room > 0 || num_windows <= 1) ? 1157 static_cast<float>(available_room) /
1163 num_windows + 1 : num_windows - 1); 1158 ((available_room > 0 || num_windows <= 1) ? num_windows + 1
1159 : num_windows - 1);
1164 float y_pos = work_area.y() + ((delta > 0) ? delta : 0); 1160 float y_pos = work_area.y() + ((delta > 0) ? delta : 0);
1165 1161
1166 // Docked area is shown only if there is at least one non-dragged visible 1162 // Docked area is shown only if there is at least one non-dragged visible
1167 // docked window. 1163 // docked window.
1168 int new_width = ideal_docked_width; 1164 int new_width = ideal_docked_width;
1169 if (visible_windows->empty() || 1165 if (visible_windows->empty() ||
1170 (visible_windows->size() == 1 && 1166 (visible_windows->size() == 1 &&
1171 (*visible_windows)[0].window == dragged_window_)) { 1167 (*visible_windows)[0].window == dragged_window_)) {
1172 new_width = 0; 1168 new_width = 0;
1173 } 1169 }
(...skipping 17 matching lines...) Expand all
1191 ? bounds.width() 1187 ? bounds.width()
1192 : ideal_docked_width)); 1188 : ideal_docked_width));
1193 DCHECK_LE(bounds.width(), ideal_docked_width); 1189 DCHECK_LE(bounds.width(), ideal_docked_width);
1194 1190
1195 DockedAlignment alignment = alignment_; 1191 DockedAlignment alignment = alignment_;
1196 if (alignment == DOCKED_ALIGNMENT_NONE && window == dragged_window_) 1192 if (alignment == DOCKED_ALIGNMENT_NONE && window == dragged_window_)
1197 alignment = GetEdgeNearestWindow(window); 1193 alignment = GetEdgeNearestWindow(window);
1198 1194
1199 // Fan out windows evenly distributing the overlap or remaining free space. 1195 // Fan out windows evenly distributing the overlap or remaining free space.
1200 bounds.set_height(iter->height); 1196 bounds.set_height(iter->height);
1201 bounds.set_y(std::max(work_area.y(), 1197 bounds.set_y(
1202 std::min(work_area.bottom() - bounds.height(), 1198 std::max(work_area.y(), std::min(work_area.bottom() - bounds.height(),
1203 static_cast<int>(y_pos + 0.5)))); 1199 static_cast<int>(y_pos + 0.5))));
1204 y_pos += bounds.height() + delta + kMinDockGap; 1200 y_pos += bounds.height() + delta + kMinDockGap;
1205 1201
1206 // All docked windows other than the one currently dragged remain stuck 1202 // All docked windows other than the one currently dragged remain stuck
1207 // to the screen edge (flush with the edge or centered in the dock area). 1203 // to the screen edge (flush with the edge or centered in the dock area).
1208 switch (alignment) { 1204 switch (alignment) {
1209 case DOCKED_ALIGNMENT_LEFT: 1205 case DOCKED_ALIGNMENT_LEFT:
1210 bounds.set_x(dock_bounds.x() + 1206 bounds.set_x(dock_bounds.x() +
1211 (ideal_docked_width - bounds.width()) / 2); 1207 (ideal_docked_width - bounds.width()) / 2);
1212 break; 1208 break;
1213 case DOCKED_ALIGNMENT_RIGHT: 1209 case DOCKED_ALIGNMENT_RIGHT:
(...skipping 26 matching lines...) Expand all
1240 void DockedWindowLayoutManager::UpdateDockBounds( 1236 void DockedWindowLayoutManager::UpdateDockBounds(
1241 DockedWindowLayoutManagerObserver::Reason reason) { 1237 DockedWindowLayoutManagerObserver::Reason reason) {
1242 int dock_inset = docked_width_ + (docked_width_ > 0 ? kMinDockGap : 0); 1238 int dock_inset = docked_width_ + (docked_width_ > 0 ? kMinDockGap : 0);
1243 const gfx::Rect work_area = 1239 const gfx::Rect work_area =
1244 dock_container_->GetDisplayNearestWindow().work_area(); 1240 dock_container_->GetDisplayNearestWindow().work_area();
1245 gfx::Rect bounds = gfx::Rect( 1241 gfx::Rect bounds = gfx::Rect(
1246 alignment_ == DOCKED_ALIGNMENT_RIGHT && dock_inset > 0 1242 alignment_ == DOCKED_ALIGNMENT_RIGHT && dock_inset > 0
1247 ? dock_container_->GetBounds().right() - dock_inset 1243 ? dock_container_->GetBounds().right() - dock_inset
1248 : dock_container_->GetBounds().x(), 1244 : dock_container_->GetBounds().x(),
1249 dock_container_->GetBounds().y(), dock_inset, work_area.height()); 1245 dock_container_->GetBounds().y(), dock_inset, work_area.height());
1250 docked_bounds_ = bounds + 1246 docked_bounds_ =
1251 dock_container_->GetBoundsInScreen().OffsetFromOrigin(); 1247 bounds + dock_container_->GetBoundsInScreen().OffsetFromOrigin();
1252 FOR_EACH_OBSERVER( 1248 FOR_EACH_OBSERVER(DockedWindowLayoutManagerObserver, observer_list_,
1253 DockedWindowLayoutManagerObserver, 1249 OnDockBoundsChanging(bounds, reason));
1254 observer_list_,
1255 OnDockBoundsChanging(bounds, reason));
1256 // Show or hide background for docked area. 1250 // Show or hide background for docked area.
1257 gfx::Rect background_bounds(docked_bounds_); 1251 gfx::Rect background_bounds(docked_bounds_);
1258 if (shelf_observer_) 1252 if (shelf_observer_)
1259 background_bounds.Subtract(shelf_observer_->shelf_bounds_in_screen()); 1253 background_bounds.Subtract(shelf_observer_->shelf_bounds_in_screen());
1260 if (docked_width_ > 0) { 1254 if (docked_width_ > 0) {
1261 if (!background_widget_) 1255 if (!background_widget_)
1262 background_widget_.reset(new DockedBackgroundWidget(this)); 1256 background_widget_.reset(new DockedBackgroundWidget(this));
1263 background_widget_->SetBackgroundBounds(background_bounds, alignment_); 1257 background_widget_->SetBackgroundBounds(background_bounds, alignment_);
1264 background_widget_->Show(); 1258 background_widget_->Show();
1265 } else if (background_widget_) { 1259 } else if (background_widget_) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 1319
1326 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( 1320 void DockedWindowLayoutManager::OnKeyboardBoundsChanging(
1327 const gfx::Rect& keyboard_bounds) { 1321 const gfx::Rect& keyboard_bounds) {
1328 // This bounds change will have caused a change to the Shelf which does not 1322 // This bounds change will have caused a change to the Shelf which does not
1329 // propagate automatically to this class, so manually recalculate bounds. 1323 // propagate automatically to this class, so manually recalculate bounds.
1330 Relayout(); 1324 Relayout();
1331 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); 1325 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING);
1332 } 1326 }
1333 1327
1334 } // namespace ash 1328 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/common/dock/docked_window_layout_manager.h ('k') | ash/wm/common/dock/docked_window_layout_manager_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698