| OLD | NEW |
| 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/dock/docked_window_layout_manager.h" |
| 6 | 6 |
| 7 #include "ash/screen_util.h" | 7 #include "ash/screen_util.h" |
| 8 #include "ash/shelf/shelf.h" | 8 #include "ash/shelf/shelf.h" |
| 9 #include "ash/shelf/shelf_constants.h" | 9 #include "ash/shelf/shelf_constants.h" |
| 10 #include "ash/shelf/shelf_layout_manager.h" | 10 #include "ash/shelf/shelf_layout_manager.h" |
| 11 #include "ash/shelf/shelf_layout_manager_observer.h" | 11 #include "ash/shelf/shelf_layout_manager_observer.h" |
| 12 #include "ash/shelf/shelf_types.h" | 12 #include "ash/shelf/shelf_types.h" |
| 13 #include "ash/shelf/shelf_widget.h" | 13 #include "ash/shelf/shelf_widget.h" |
| 14 #include "ash/shell.h" | 14 #include "ash/shell.h" |
| 15 #include "ash/shell_window_ids.h" | 15 #include "ash/shell_window_ids.h" |
| 16 #include "ash/wm/common/window_animation_types.h" | 16 #include "ash/wm/common/window_animation_types.h" |
| 17 #include "ash/wm/common/window_parenting_utils.h" | 17 #include "ash/wm/common/window_parenting_utils.h" |
| 18 #include "ash/wm/common/wm_globals.h" |
| 19 #include "ash/wm/common/wm_root_window_controller.h" |
| 18 #include "ash/wm/window_animations.h" | 20 #include "ash/wm/window_animations.h" |
| 19 #include "ash/wm/window_properties.h" | 21 #include "ash/wm/window_properties.h" |
| 20 #include "ash/wm/window_resizer.h" | 22 #include "ash/wm/window_resizer.h" |
| 21 #include "ash/wm/window_state.h" | 23 #include "ash/wm/window_state.h" |
| 22 #include "ash/wm/window_state_aura.h" | 24 #include "ash/wm/window_state_aura.h" |
| 23 #include "ash/wm/window_util.h" | 25 #include "ash/wm/window_util.h" |
| 24 #include "ash/wm/workspace_controller.h" | 26 #include "ash/wm/workspace_controller.h" |
| 25 #include "base/auto_reset.h" | 27 #include "base/auto_reset.h" |
| 26 #include "base/command_line.h" | 28 #include "base/command_line.h" |
| 27 #include "base/metrics/histogram.h" | 29 #include "base/metrics/histogram.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 visible_background_change_type_(BACKGROUND_CHANGE_IMMEDIATE) { | 76 visible_background_change_type_(BACKGROUND_CHANGE_IMMEDIATE) { |
| 75 manager_->shelf()->shelf_layout_manager()->AddObserver(this); | 77 manager_->shelf()->shelf_layout_manager()->AddObserver(this); |
| 76 InitWidget(manager_->dock_container()); | 78 InitWidget(manager_->dock_container()); |
| 77 } | 79 } |
| 78 | 80 |
| 79 ~DockedBackgroundWidget() override { | 81 ~DockedBackgroundWidget() override { |
| 80 manager_->shelf()->shelf_layout_manager()->RemoveObserver(this); | 82 manager_->shelf()->shelf_layout_manager()->RemoveObserver(this); |
| 81 } | 83 } |
| 82 | 84 |
| 83 // Sets widget bounds and sizes opaque background layer to fill the widget. | 85 // Sets widget bounds and sizes opaque background layer to fill the widget. |
| 84 void SetBackgroundBounds(const gfx::Rect bounds, DockedAlignment alignment) { | 86 void SetBackgroundBounds(const gfx::Rect& bounds, DockedAlignment alignment) { |
| 85 SetBounds(bounds); | 87 SetBounds(bounds); |
| 86 opaque_background_.SetBounds(gfx::Rect(bounds.size())); | 88 opaque_background_.SetBounds(gfx::Rect(bounds.size())); |
| 87 alignment_ = alignment; | 89 alignment_ = alignment; |
| 88 } | 90 } |
| 89 | 91 |
| 90 private: | 92 private: |
| 91 // views::Widget: | 93 // views::Widget: |
| 92 void OnNativeWidgetVisibilityChanged(bool visible) override { | 94 void OnNativeWidgetVisibilityChanged(bool visible) override { |
| 93 views::Widget::OnNativeWidgetVisibilityChanged(visible); | 95 views::Widget::OnNativeWidgetVisibilityChanged(visible); |
| 94 UpdateBackground(); | 96 UpdateBackground(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 BackgroundAnimatorChangeType change_type) override { | 132 BackgroundAnimatorChangeType change_type) override { |
| 131 // Sets the background type. Starts an animation to transition to | 133 // Sets the background type. Starts an animation to transition to |
| 132 // |background_type| if the widget is visible. If the widget is not visible, | 134 // |background_type| if the widget is visible. If the widget is not visible, |
| 133 // the animation is postponed till the widget becomes visible. | 135 // the animation is postponed till the widget becomes visible. |
| 134 visible_background_type_ = background_type; | 136 visible_background_type_ = background_type; |
| 135 visible_background_change_type_ = change_type; | 137 visible_background_change_type_ = change_type; |
| 136 if (IsVisible()) | 138 if (IsVisible()) |
| 137 UpdateBackground(); | 139 UpdateBackground(); |
| 138 } | 140 } |
| 139 | 141 |
| 140 void InitWidget(aura::Window* parent) { | 142 void InitWidget(wm::WmWindow* parent) { |
| 141 views::Widget::InitParams params; | 143 views::Widget::InitParams params; |
| 142 params.type = views::Widget::InitParams::TYPE_POPUP; | 144 params.type = views::Widget::InitParams::TYPE_POPUP; |
| 143 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 145 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 144 params.keep_on_top = false; | 146 params.keep_on_top = false; |
| 145 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 147 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 146 params.parent = parent; | |
| 147 params.accept_events = false; | 148 params.accept_events = false; |
| 148 set_focus_on_creation(false); | 149 set_focus_on_creation(false); |
| 150 parent->GetRootWindowController()->ConfigureWidgetInitParamsForContainer( |
| 151 this, parent->GetShellWindowId(), ¶ms); |
| 149 Init(params); | 152 Init(params); |
| 150 SetVisibilityChangedAnimationsEnabled(false); | 153 SetVisibilityChangedAnimationsEnabled(false); |
| 151 GetNativeWindow()->SetProperty(kStayInSameRootWindowKey, true); | 154 GetNativeWindow()->SetProperty(kStayInSameRootWindowKey, true); |
| 152 opaque_background_.SetColor(SK_ColorBLACK); | 155 opaque_background_.SetColor(SK_ColorBLACK); |
| 153 opaque_background_.SetBounds(gfx::Rect(GetWindowBoundsInScreen().size())); | 156 opaque_background_.SetBounds(gfx::Rect(GetWindowBoundsInScreen().size())); |
| 154 opaque_background_.SetOpacity(0.0f); | 157 opaque_background_.SetOpacity(0.0f); |
| 155 GetNativeWindow()->layer()->Add(&opaque_background_); | 158 GetNativeWindow()->layer()->Add(&opaque_background_); |
| 156 | 159 |
| 157 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 160 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 158 gfx::ImageSkia shelf_background = | 161 gfx::ImageSkia shelf_background = |
| 159 *rb.GetImageSkiaNamed(IDR_ASH_SHELF_BACKGROUND); | 162 *rb.GetImageSkiaNamed(IDR_ASH_SHELF_BACKGROUND); |
| 160 shelf_background_left_ = gfx::ImageSkiaOperations::CreateRotatedImage( | 163 shelf_background_left_ = gfx::ImageSkiaOperations::CreateRotatedImage( |
| 161 shelf_background, SkBitmapOperations::ROTATION_90_CW); | 164 shelf_background, SkBitmapOperations::ROTATION_90_CW); |
| 162 shelf_background_right_ = gfx::ImageSkiaOperations::CreateRotatedImage( | 165 shelf_background_right_ = gfx::ImageSkiaOperations::CreateRotatedImage( |
| 163 shelf_background, SkBitmapOperations::ROTATION_270_CW); | 166 shelf_background, SkBitmapOperations::ROTATION_270_CW); |
| 164 | 167 |
| 165 // This background should be explicitly stacked below any windows already in | 168 // This background should be explicitly stacked below any windows already in |
| 166 // the dock, otherwise the z-order is set by the order in which windows were | 169 // the dock, otherwise the z-order is set by the order in which windows were |
| 167 // added to the container, and UpdateStacking only manages user windows, not | 170 // added to the container, and UpdateStacking only manages user windows, not |
| 168 // the background widget. | 171 // the background widget. |
| 169 parent->StackChildAtBottom(GetNativeWindow()); | 172 parent->StackChildAtBottom(wm::WmWindow::Get(this)); |
| 170 } | 173 } |
| 171 | 174 |
| 172 // Transitions to |visible_background_type_| if the widget is visible and to | 175 // Transitions to |visible_background_type_| if the widget is visible and to |
| 173 // SHELF_BACKGROUND_DEFAULT if it is not. | 176 // SHELF_BACKGROUND_DEFAULT if it is not. |
| 174 void UpdateBackground() { | 177 void UpdateBackground() { |
| 175 ShelfBackgroundType background_type = IsVisible() ? | 178 ShelfBackgroundType background_type = IsVisible() ? |
| 176 visible_background_type_ : SHELF_BACKGROUND_DEFAULT; | 179 visible_background_type_ : SHELF_BACKGROUND_DEFAULT; |
| 177 BackgroundAnimatorChangeType change_type = IsVisible() ? | 180 BackgroundAnimatorChangeType change_type = IsVisible() ? |
| 178 visible_background_change_type_ : BACKGROUND_CHANGE_IMMEDIATE; | 181 visible_background_change_type_ : BACKGROUND_CHANGE_IMMEDIATE; |
| 179 | 182 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 | 224 |
| 222 // Whether the widget should animate to |visible_background_type_|. | 225 // Whether the widget should animate to |visible_background_type_|. |
| 223 BackgroundAnimatorChangeType visible_background_change_type_; | 226 BackgroundAnimatorChangeType visible_background_change_type_; |
| 224 | 227 |
| 225 DISALLOW_COPY_AND_ASSIGN(DockedBackgroundWidget); | 228 DISALLOW_COPY_AND_ASSIGN(DockedBackgroundWidget); |
| 226 }; | 229 }; |
| 227 | 230 |
| 228 namespace { | 231 namespace { |
| 229 | 232 |
| 230 // Returns true if a window is a popup or a transient child. | 233 // Returns true if a window is a popup or a transient child. |
| 231 bool IsPopupOrTransient(const aura::Window* window) { | 234 bool IsPopupOrTransient(const wm::WmWindow* window) { |
| 232 return (window->type() == ui::wm::WINDOW_TYPE_POPUP || | 235 return (window->GetType() == ui::wm::WINDOW_TYPE_POPUP || |
| 233 ::wm::GetTransientParent(window)); | 236 window->GetTransientParent()); |
| 234 } | 237 } |
| 235 | 238 |
| 236 // Certain windows (minimized, hidden or popups) are not docked and are ignored | 239 // Certain windows (minimized, hidden or popups) are not docked and are ignored |
| 237 // by layout logic even when they are children of a docked container. | 240 // by layout logic even when they are children of a docked container. |
| 238 bool IsWindowDocked(const aura::Window* window) { | 241 bool IsWindowDocked(const wm::WmWindow* window) { |
| 239 return (window->IsVisible() && | 242 return (window->IsVisible() && !window->GetWindowState()->IsMinimized() && |
| 240 !wm::GetWindowState(window)->IsMinimized() && | |
| 241 !IsPopupOrTransient(window)); | 243 !IsPopupOrTransient(window)); |
| 242 } | 244 } |
| 243 | 245 |
| 244 void UndockWindow(aura::Window* window) { | 246 void UndockWindow(wm::WmWindow* window) { |
| 245 gfx::Rect previous_bounds = window->bounds(); | 247 gfx::Rect previous_bounds = window->GetBounds(); |
| 246 aura::Window* old_parent = window->parent(); | 248 wm::WmWindow* old_parent = window->GetParent(); |
| 247 aura::client::ParentWindowWithContext(window, window, gfx::Rect()); | 249 window->SetParentUsingContext(window, gfx::Rect()); |
| 248 if (window->parent() != old_parent) { | 250 if (window->GetParent() != old_parent) { |
| 249 wm::ReparentTransientChildrenOfChild( | 251 wm::ReparentTransientChildrenOfChild(window, old_parent, |
| 250 wm::WmWindowAura::Get(window), wm::WmWindowAura::Get(old_parent), | 252 window->GetParent()); |
| 251 wm::WmWindowAura::Get(window->parent())); | |
| 252 } | 253 } |
| 253 // Start maximize or fullscreen (affecting packaged apps) animation from | 254 // Start maximize or fullscreen (affecting packaged apps) animation from |
| 254 // previous window bounds. | 255 // previous window bounds. |
| 255 window->layer()->SetBounds(previous_bounds); | 256 window->GetLayer()->SetBounds(previous_bounds); |
| 256 } | 257 } |
| 257 | 258 |
| 258 // Returns width that is as close as possible to |target_width| while being | 259 // Returns width that is as close as possible to |target_width| while being |
| 259 // consistent with docked min and max restrictions and respects the |window|'s | 260 // consistent with docked min and max restrictions and respects the |window|'s |
| 260 // minimum and maximum size. | 261 // minimum and maximum size. |
| 261 int GetWindowWidthCloseTo(const aura::Window* window, int target_width) { | 262 int GetWindowWidthCloseTo(const wm::WmWindow* window, int target_width) { |
| 262 if (!wm::GetWindowState(window)->CanResize()) { | 263 if (!window->GetWindowState()->CanResize()) { |
| 263 DCHECK_LE(window->bounds().width(), | 264 DCHECK_LE(window->GetBounds().width(), |
| 264 DockedWindowLayoutManager::kMaxDockWidth); | 265 DockedWindowLayoutManager::kMaxDockWidth); |
| 265 return window->bounds().width(); | 266 return window->GetBounds().width(); |
| 266 } | 267 } |
| 267 int width = std::max(DockedWindowLayoutManager::kMinDockWidth, | 268 int width = std::max(DockedWindowLayoutManager::kMinDockWidth, |
| 268 std::min(target_width, | 269 std::min(target_width, |
| 269 DockedWindowLayoutManager::kMaxDockWidth)); | 270 DockedWindowLayoutManager::kMaxDockWidth)); |
| 270 if (window->delegate()) { | 271 width = std::max(width, window->GetMinimumSize().width()); |
| 271 if (window->delegate()->GetMinimumSize().width() != 0) | 272 if (window->GetMaximumSize().width() != 0) |
| 272 width = std::max(width, window->delegate()->GetMinimumSize().width()); | 273 width = std::min(width, window->GetMaximumSize().width()); |
| 273 if (window->delegate()->GetMaximumSize().width() != 0) | |
| 274 width = std::min(width, window->delegate()->GetMaximumSize().width()); | |
| 275 } | |
| 276 DCHECK_LE(width, DockedWindowLayoutManager::kMaxDockWidth); | 274 DCHECK_LE(width, DockedWindowLayoutManager::kMaxDockWidth); |
| 277 return width; | 275 return width; |
| 278 } | 276 } |
| 279 | 277 |
| 280 // Returns height that is as close as possible to |target_height| while | 278 // Returns height that is as close as possible to |target_height| while |
| 281 // respecting the |window|'s minimum and maximum size. | 279 // respecting the |window|'s minimum and maximum size. |
| 282 int GetWindowHeightCloseTo(const aura::Window* window, int target_height) { | 280 int GetWindowHeightCloseTo(const wm::WmWindow* window, int target_height) { |
| 283 if (!wm::GetWindowState(window)->CanResize()) | 281 if (!window->GetWindowState()->CanResize()) |
| 284 return window->bounds().height(); | 282 return window->GetBounds().height(); |
| 285 int minimum_height = kMinimumHeight; | 283 int minimum_height = |
| 286 int maximum_height = 0; | 284 std::max(kMinimumHeight, window->GetMinimumSize().height()); |
| 287 const aura::WindowDelegate* delegate(window->delegate()); | 285 int maximum_height = window->GetMaximumSize().height(); |
| 288 if (delegate) { | |
| 289 if (delegate->GetMinimumSize().height() != 0) { | |
| 290 minimum_height = std::max(kMinimumHeight, | |
| 291 delegate->GetMinimumSize().height()); | |
| 292 } | |
| 293 if (delegate->GetMaximumSize().height() != 0) | |
| 294 maximum_height = delegate->GetMaximumSize().height(); | |
| 295 } | |
| 296 if (minimum_height) | 286 if (minimum_height) |
| 297 target_height = std::max(target_height, minimum_height); | 287 target_height = std::max(target_height, minimum_height); |
| 298 if (maximum_height) | 288 if (maximum_height) |
| 299 target_height = std::min(target_height, maximum_height); | 289 target_height = std::min(target_height, maximum_height); |
| 300 return target_height; | 290 return target_height; |
| 301 } | 291 } |
| 302 | 292 |
| 303 } // namespace | 293 } // namespace |
| 304 | 294 |
| 305 struct DockedWindowLayoutManager::WindowWithHeight { | 295 struct DockedWindowLayoutManager::WindowWithHeight { |
| 306 explicit WindowWithHeight(aura::Window* window) | 296 explicit WindowWithHeight(wm::WmWindow* window) |
| 307 : window(window), height(window->bounds().height()) {} | 297 : window(window), height(window->GetBounds().height()) {} |
| 308 aura::Window* window; | 298 wm::WmWindow* window; |
| 309 int height; | 299 int height; |
| 310 }; | 300 }; |
| 311 | 301 |
| 312 // A functor used to sort the windows in order of their minimum height. | 302 // A functor used to sort the windows in order of their minimum height. |
| 313 struct DockedWindowLayoutManager::CompareMinimumHeight { | 303 struct DockedWindowLayoutManager::CompareMinimumHeight { |
| 314 bool operator()(const WindowWithHeight& win1, const WindowWithHeight& win2) { | 304 bool operator()(const WindowWithHeight& win1, const WindowWithHeight& win2) { |
| 315 return GetWindowHeightCloseTo(win1.window, 0) < | 305 return GetWindowHeightCloseTo(win1.window, 0) < |
| 316 GetWindowHeightCloseTo(win2.window, 0); | 306 GetWindowHeightCloseTo(win2.window, 0); |
| 317 } | 307 } |
| 318 }; | 308 }; |
| 319 | 309 |
| 320 // A functor used to sort the windows in order of their center Y position. | 310 // A functor used to sort the windows in order of their center Y position. |
| 321 // |delta| is a pre-calculated distance from the bottom of one window to the top | 311 // |delta| is a pre-calculated distance from the bottom of one window to the top |
| 322 // of the next. Its value can be positive (gap) or negative (overlap). | 312 // of the next. Its value can be positive (gap) or negative (overlap). |
| 323 // Half of |delta| is used as a transition point at which windows could ideally | 313 // Half of |delta| is used as a transition point at which windows could ideally |
| 324 // swap positions. | 314 // swap positions. |
| 325 struct DockedWindowLayoutManager::CompareWindowPos { | 315 struct DockedWindowLayoutManager::CompareWindowPos { |
| 326 CompareWindowPos(aura::Window* dragged_window, | 316 CompareWindowPos(wm::WmWindow* dragged_window, |
| 327 aura::Window* docked_container, | 317 wm::WmWindow* docked_container, |
| 328 float delta) | 318 float delta) |
| 329 : dragged_window_(dragged_window), | 319 : dragged_window_(dragged_window), |
| 330 docked_container_(docked_container), | 320 docked_container_(docked_container), |
| 331 delta_(delta / 2) {} | 321 delta_(delta / 2) {} |
| 332 | 322 |
| 333 bool operator()(const WindowWithHeight& window_with_height1, | 323 bool operator()(const WindowWithHeight& window_with_height1, |
| 334 const WindowWithHeight& window_with_height2) { | 324 const WindowWithHeight& window_with_height2) { |
| 335 // Use target coordinates since animations may be active when windows are | 325 // Use target coordinates since animations may be active when windows are |
| 336 // reordered. | 326 // reordered. |
| 337 aura::Window* win1(window_with_height1.window); | 327 wm::WmWindow* win1(window_with_height1.window); |
| 338 aura::Window* win2(window_with_height2.window); | 328 wm::WmWindow* win2(window_with_height2.window); |
| 339 gfx::Rect win1_bounds = ScreenUtil::ConvertRectToScreen( | 329 gfx::Rect win1_bounds = |
| 340 docked_container_, win1->GetTargetBounds()); | 330 docked_container_->ConvertRectToScreen(win1->GetTargetBounds()); |
| 341 gfx::Rect win2_bounds = ScreenUtil::ConvertRectToScreen( | 331 gfx::Rect win2_bounds = |
| 342 docked_container_, win2->GetTargetBounds()); | 332 docked_container_->ConvertRectToScreen(win2->GetTargetBounds()); |
| 343 win1_bounds.set_height(window_with_height1.height); | 333 win1_bounds.set_height(window_with_height1.height); |
| 344 win2_bounds.set_height(window_with_height2.height); | 334 win2_bounds.set_height(window_with_height2.height); |
| 345 // If one of the windows is the |dragged_window_| attempt to make an | 335 // If one of the windows is the |dragged_window_| attempt to make an |
| 346 // earlier swap between the windows than just based on their centers. | 336 // earlier swap between the windows than just based on their centers. |
| 347 // This is possible if the dragged window is at least as tall as the other | 337 // This is possible if the dragged window is at least as tall as the other |
| 348 // window. | 338 // window. |
| 349 if (win1 == dragged_window_) | 339 if (win1 == dragged_window_) |
| 350 return compare_two_windows(win1_bounds, win2_bounds); | 340 return compare_two_windows(win1_bounds, win2_bounds); |
| 351 if (win2 == dragged_window_) | 341 if (win2 == dragged_window_) |
| 352 return !compare_two_windows(win2_bounds, win1_bounds); | 342 return !compare_two_windows(win2_bounds, win1_bounds); |
| 353 // Otherwise just compare the centers. | 343 // Otherwise just compare the centers. |
| 354 return win1_bounds.CenterPoint().y() < win2_bounds.CenterPoint().y(); | 344 return win1_bounds.CenterPoint().y() < win2_bounds.CenterPoint().y(); |
| 355 } | 345 } |
| 356 | 346 |
| 357 // Based on center point tries to deduce where the drag is coming from. | 347 // Based on center point tries to deduce where the drag is coming from. |
| 358 // When dragging from below up the transition point is lower. | 348 // When dragging from below up the transition point is lower. |
| 359 // When dragging from above down the transition point is higher. | 349 // When dragging from above down the transition point is higher. |
| 360 bool compare_bounds(const gfx::Rect dragged, const gfx::Rect other) { | 350 bool compare_bounds(const gfx::Rect& dragged, const gfx::Rect& other) { |
| 361 if (dragged.CenterPoint().y() < other.CenterPoint().y()) | 351 if (dragged.CenterPoint().y() < other.CenterPoint().y()) |
| 362 return dragged.CenterPoint().y() < other.y() - delta_; | 352 return dragged.CenterPoint().y() < other.y() - delta_; |
| 363 return dragged.CenterPoint().y() < other.bottom() + delta_; | 353 return dragged.CenterPoint().y() < other.bottom() + delta_; |
| 364 } | 354 } |
| 365 | 355 |
| 366 // Performs comparison both ways and selects stable result. | 356 // Performs comparison both ways and selects stable result. |
| 367 bool compare_two_windows(const gfx::Rect bounds1, const gfx::Rect bounds2) { | 357 bool compare_two_windows(const gfx::Rect& bounds1, const gfx::Rect& bounds2) { |
| 368 // Try comparing windows in both possible orders and see if the comparison | 358 // Try comparing windows in both possible orders and see if the comparison |
| 369 // is stable. | 359 // is stable. |
| 370 bool result1 = compare_bounds(bounds1, bounds2); | 360 bool result1 = compare_bounds(bounds1, bounds2); |
| 371 bool result2 = compare_bounds(bounds2, bounds1); | 361 bool result2 = compare_bounds(bounds2, bounds1); |
| 372 if (result1 != result2) | 362 if (result1 != result2) |
| 373 return result1; | 363 return result1; |
| 374 | 364 |
| 375 // Otherwise it is not possible to be sure that the windows will not bounce. | 365 // Otherwise it is not possible to be sure that the windows will not bounce. |
| 376 // In this case just compare the centers. | 366 // In this case just compare the centers. |
| 377 return bounds1.CenterPoint().y() < bounds2.CenterPoint().y(); | 367 return bounds1.CenterPoint().y() < bounds2.CenterPoint().y(); |
| 378 } | 368 } |
| 379 | 369 |
| 380 private: | 370 private: |
| 381 aura::Window* dragged_window_; | 371 wm::WmWindow* dragged_window_; |
| 382 aura::Window* docked_container_; | 372 wm::WmWindow* docked_container_; |
| 383 float delta_; | 373 float delta_; |
| 384 }; | 374 }; |
| 385 | 375 |
| 386 //////////////////////////////////////////////////////////////////////////////// | 376 //////////////////////////////////////////////////////////////////////////////// |
| 387 // A class that observes shelf for bounds changes. | 377 // A class that observes shelf for bounds changes. |
| 388 class DockedWindowLayoutManager::ShelfWindowObserver : public WindowObserver { | 378 class DockedWindowLayoutManager::ShelfWindowObserver |
| 379 : public wm::WmWindowObserver { |
| 389 public: | 380 public: |
| 390 explicit ShelfWindowObserver( | 381 explicit ShelfWindowObserver( |
| 391 DockedWindowLayoutManager* docked_layout_manager) | 382 DockedWindowLayoutManager* docked_layout_manager) |
| 392 : docked_layout_manager_(docked_layout_manager) { | 383 : docked_layout_manager_(docked_layout_manager) { |
| 393 DCHECK(docked_layout_manager_->shelf()->shelf_widget()); | 384 DCHECK(docked_layout_manager_->shelf()->shelf_widget()); |
| 394 docked_layout_manager_->shelf()->shelf_widget()->GetNativeView() | 385 wm::WmWindow::Get(docked_layout_manager_->shelf()->shelf_widget()) |
| 395 ->AddObserver(this); | 386 ->AddObserver(this); |
| 396 } | 387 } |
| 397 | 388 |
| 398 ~ShelfWindowObserver() override { | 389 ~ShelfWindowObserver() override { |
| 399 if (docked_layout_manager_->shelf() && | 390 if (docked_layout_manager_->shelf() && |
| 400 docked_layout_manager_->shelf()->shelf_widget()) | 391 docked_layout_manager_->shelf()->shelf_widget()) { |
| 401 docked_layout_manager_->shelf()->shelf_widget()->GetNativeView() | 392 wm::WmWindow::Get(docked_layout_manager_->shelf()->shelf_widget()) |
| 402 ->RemoveObserver(this); | 393 ->RemoveObserver(this); |
| 394 } |
| 403 } | 395 } |
| 404 | 396 |
| 405 // aura::WindowObserver: | 397 // wm::WmWindowObserver: |
| 406 void OnWindowBoundsChanged(aura::Window* window, | 398 void OnWindowBoundsChanged(wm::WmWindow* window, |
| 407 const gfx::Rect& old_bounds, | 399 const gfx::Rect& old_bounds, |
| 408 const gfx::Rect& new_bounds) override { | 400 const gfx::Rect& new_bounds) override { |
| 409 shelf_bounds_in_screen_ = ScreenUtil::ConvertRectToScreen( | 401 shelf_bounds_in_screen_ = |
| 410 window->parent(), new_bounds); | 402 window->GetParent()->ConvertRectToScreen(new_bounds); |
| 411 docked_layout_manager_->OnShelfBoundsChanged(); | 403 docked_layout_manager_->OnShelfBoundsChanged(); |
| 412 } | 404 } |
| 413 | 405 |
| 414 const gfx::Rect& shelf_bounds_in_screen() const { | 406 const gfx::Rect& shelf_bounds_in_screen() const { |
| 415 return shelf_bounds_in_screen_; | 407 return shelf_bounds_in_screen_; |
| 416 } | 408 } |
| 417 | 409 |
| 418 private: | 410 private: |
| 419 DockedWindowLayoutManager* docked_layout_manager_; | 411 DockedWindowLayoutManager* docked_layout_manager_; |
| 420 gfx::Rect shelf_bounds_in_screen_; | 412 gfx::Rect shelf_bounds_in_screen_; |
| 421 | 413 |
| 422 DISALLOW_COPY_AND_ASSIGN(ShelfWindowObserver); | 414 DISALLOW_COPY_AND_ASSIGN(ShelfWindowObserver); |
| 423 }; | 415 }; |
| 424 | 416 |
| 425 //////////////////////////////////////////////////////////////////////////////// | 417 //////////////////////////////////////////////////////////////////////////////// |
| 426 // DockedWindowLayoutManager public implementation: | 418 // DockedWindowLayoutManager public implementation: |
| 427 DockedWindowLayoutManager::DockedWindowLayoutManager( | 419 DockedWindowLayoutManager::DockedWindowLayoutManager( |
| 428 aura::Window* dock_container, | 420 wm::WmWindow* dock_container, |
| 429 WorkspaceController* workspace_controller) | 421 WorkspaceController* workspace_controller) |
| 430 : SnapToPixelLayoutManager(dock_container), | 422 : dock_container_(dock_container), |
| 431 dock_container_(dock_container), | |
| 432 in_layout_(false), | 423 in_layout_(false), |
| 433 dragged_window_(nullptr), | 424 dragged_window_(nullptr), |
| 434 is_dragged_window_docked_(false), | 425 is_dragged_window_docked_(false), |
| 435 is_dragged_from_dock_(false), | 426 is_dragged_from_dock_(false), |
| 436 shelf_(nullptr), | 427 shelf_(nullptr), |
| 437 workspace_controller_(workspace_controller), | 428 workspace_controller_(workspace_controller), |
| 438 in_fullscreen_(workspace_controller_->GetWindowState() == | 429 in_fullscreen_(workspace_controller_->GetWindowState() == |
| 439 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN), | 430 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN), |
| 440 docked_width_(0), | 431 docked_width_(0), |
| 441 alignment_(DOCKED_ALIGNMENT_NONE), | 432 alignment_(DOCKED_ALIGNMENT_NONE), |
| 442 preferred_alignment_(DOCKED_ALIGNMENT_NONE), | 433 preferred_alignment_(DOCKED_ALIGNMENT_NONE), |
| 443 event_source_(DOCKED_ACTION_SOURCE_UNKNOWN), | 434 event_source_(DOCKED_ACTION_SOURCE_UNKNOWN), |
| 444 last_active_window_(nullptr), | 435 last_active_window_(nullptr), |
| 445 last_action_time_(base::Time::Now()), | 436 last_action_time_(base::Time::Now()), |
| 446 background_widget_(nullptr) { | 437 background_widget_(nullptr) { |
| 447 DCHECK(dock_container); | 438 DCHECK(dock_container); |
| 448 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> | 439 dock_container->GetGlobals()->AddActivationObserver(this); |
| 449 AddObserver(this); | |
| 450 Shell::GetInstance()->AddShellObserver(this); | 440 Shell::GetInstance()->AddShellObserver(this); |
| 451 } | 441 } |
| 452 | 442 |
| 453 DockedWindowLayoutManager::~DockedWindowLayoutManager() { | 443 DockedWindowLayoutManager::~DockedWindowLayoutManager() { |
| 454 Shutdown(); | 444 Shutdown(); |
| 455 } | 445 } |
| 456 | 446 |
| 447 // static |
| 448 DockedWindowLayoutManager* DockedWindowLayoutManager::Get( |
| 449 wm::WmWindow* window) { |
| 450 if (!window) |
| 451 return nullptr; |
| 452 |
| 453 wm::WmWindow* root = window->GetRootWindow(); |
| 454 return static_cast<DockedWindowLayoutManager*>( |
| 455 root->GetChildByShellWindowId(kShellWindowId_DockedContainer) |
| 456 ->GetLayoutManager()); |
| 457 } |
| 458 |
| 457 void DockedWindowLayoutManager::Shutdown() { | 459 void DockedWindowLayoutManager::Shutdown() { |
| 458 background_widget_.reset(); | 460 background_widget_.reset(); |
| 459 shelf_observer_.reset(); | 461 shelf_observer_.reset(); |
| 460 shelf_ = nullptr; | 462 shelf_ = nullptr; |
| 461 for (size_t i = 0; i < dock_container_->children().size(); ++i) { | 463 for (wm::WmWindow* child : dock_container_->GetChildren()) { |
| 462 aura::Window* child = dock_container_->children()[i]; | |
| 463 child->RemoveObserver(this); | 464 child->RemoveObserver(this); |
| 464 wm::GetWindowState(child)->RemoveObserver(this); | 465 child->GetWindowState()->RemoveObserver(this); |
| 465 } | 466 } |
| 466 aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> | 467 dock_container_->GetGlobals()->RemoveActivationObserver(this); |
| 467 RemoveObserver(this); | |
| 468 Shell::GetInstance()->RemoveShellObserver(this); | 468 Shell::GetInstance()->RemoveShellObserver(this); |
| 469 } | 469 } |
| 470 | 470 |
| 471 void DockedWindowLayoutManager::AddObserver( | 471 void DockedWindowLayoutManager::AddObserver( |
| 472 DockedWindowLayoutManagerObserver* observer) { | 472 DockedWindowLayoutManagerObserver* observer) { |
| 473 observer_list_.AddObserver(observer); | 473 observer_list_.AddObserver(observer); |
| 474 } | 474 } |
| 475 | 475 |
| 476 void DockedWindowLayoutManager::RemoveObserver( | 476 void DockedWindowLayoutManager::RemoveObserver( |
| 477 DockedWindowLayoutManagerObserver* observer) { | 477 DockedWindowLayoutManagerObserver* observer) { |
| 478 observer_list_.RemoveObserver(observer); | 478 observer_list_.RemoveObserver(observer); |
| 479 } | 479 } |
| 480 | 480 |
| 481 void DockedWindowLayoutManager::StartDragging(aura::Window* window) { | 481 void DockedWindowLayoutManager::StartDragging(wm::WmWindow* window) { |
| 482 DCHECK(!dragged_window_); | 482 DCHECK(!dragged_window_); |
| 483 dragged_window_ = window; | 483 dragged_window_ = window; |
| 484 DCHECK(!IsPopupOrTransient(window)); | 484 DCHECK(!IsPopupOrTransient(window)); |
| 485 // Start observing a window unless it is docked container's child in which | 485 // Start observing a window unless it is docked container's child in which |
| 486 // case it is already observed. | 486 // case it is already observed. |
| 487 wm::WindowState* dragged_state = wm::GetWindowState(dragged_window_); | 487 wm::WindowState* dragged_state = dragged_window_->GetWindowState(); |
| 488 if (dragged_window_->parent() != dock_container_) { | 488 if (dragged_window_->GetParent() != dock_container_) { |
| 489 dragged_window_->AddObserver(this); | 489 dragged_window_->AddObserver(this); |
| 490 dragged_state->AddObserver(this); | 490 dragged_state->AddObserver(this); |
| 491 } else if (!IsAnyWindowDocked() && | 491 } else if (!IsAnyWindowDocked() && |
| 492 dragged_state->drag_details() && | 492 dragged_state->drag_details() && |
| 493 !(dragged_state->drag_details()->bounds_change & | 493 !(dragged_state->drag_details()->bounds_change & |
| 494 WindowResizer::kBoundsChange_Resizes)) { | 494 WindowResizer::kBoundsChange_Resizes)) { |
| 495 // If there are no other docked windows clear alignment when a docked window | 495 // If there are no other docked windows clear alignment when a docked window |
| 496 // is moved (but not when it is resized or the window could get undocked | 496 // is moved (but not when it is resized or the window could get undocked |
| 497 // when resized away from the edge while docked). | 497 // when resized away from the edge while docked). |
| 498 alignment_ = DOCKED_ALIGNMENT_NONE; | 498 alignment_ = DOCKED_ALIGNMENT_NONE; |
| 499 } | 499 } |
| 500 is_dragged_from_dock_ = window->parent() == dock_container_; | 500 is_dragged_from_dock_ = window->GetParent() == dock_container_; |
| 501 DCHECK(!is_dragged_window_docked_); | 501 DCHECK(!is_dragged_window_docked_); |
| 502 | 502 |
| 503 // Resize all windows that are flush with the dock edge together if one of | 503 // Resize all windows that are flush with the dock edge together if one of |
| 504 // them gets resized. | 504 // them gets resized. |
| 505 if (dragged_window_->bounds().width() == docked_width_ && | 505 if (dragged_window_->GetBounds().width() == docked_width_ && |
| 506 (dragged_state->drag_details()->bounds_change & | 506 (dragged_state->drag_details()->bounds_change & |
| 507 WindowResizer::kBoundsChange_Resizes) && | 507 WindowResizer::kBoundsChange_Resizes) && |
| 508 (dragged_state->drag_details()->size_change_direction & | 508 (dragged_state->drag_details()->size_change_direction & |
| 509 WindowResizer::kBoundsChangeDirection_Horizontal)) { | 509 WindowResizer::kBoundsChangeDirection_Horizontal)) { |
| 510 for (size_t i = 0; i < dock_container_->children().size(); ++i) { | 510 for (wm::WmWindow* window1 : dock_container_->GetChildren()) { |
| 511 aura::Window* window1(dock_container_->children()[i]); | |
| 512 if (IsWindowDocked(window1) && window1 != dragged_window_ && | 511 if (IsWindowDocked(window1) && window1 != dragged_window_ && |
| 513 window1->bounds().width() == docked_width_) { | 512 window1->GetBounds().width() == docked_width_) { |
| 514 wm::GetWindowState(window1)->set_bounds_changed_by_user(false); | 513 window1->GetWindowState()->set_bounds_changed_by_user(false); |
| 515 } | 514 } |
| 516 } | 515 } |
| 517 } | 516 } |
| 518 } | 517 } |
| 519 | 518 |
| 520 void DockedWindowLayoutManager::DockDraggedWindow(aura::Window* window) { | 519 void DockedWindowLayoutManager::DockDraggedWindow(wm::WmWindow* window) { |
| 521 DCHECK(!IsPopupOrTransient(window)); | 520 DCHECK(!IsPopupOrTransient(window)); |
| 522 OnDraggedWindowDocked(window); | 521 OnDraggedWindowDocked(window); |
| 523 Relayout(); | 522 Relayout(); |
| 524 } | 523 } |
| 525 | 524 |
| 526 void DockedWindowLayoutManager::UndockDraggedWindow() { | 525 void DockedWindowLayoutManager::UndockDraggedWindow() { |
| 527 DCHECK(!IsPopupOrTransient(dragged_window_)); | 526 DCHECK(!IsPopupOrTransient(dragged_window_)); |
| 528 OnDraggedWindowUndocked(); | 527 OnDraggedWindowUndocked(); |
| 529 Relayout(); | 528 Relayout(); |
| 530 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 529 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 531 is_dragged_from_dock_ = false; | 530 is_dragged_from_dock_ = false; |
| 532 } | 531 } |
| 533 | 532 |
| 534 void DockedWindowLayoutManager::FinishDragging(DockedAction action, | 533 void DockedWindowLayoutManager::FinishDragging(DockedAction action, |
| 535 DockedActionSource source) { | 534 DockedActionSource source) { |
| 536 DCHECK(dragged_window_); | 535 DCHECK(dragged_window_); |
| 537 DCHECK(!IsPopupOrTransient(dragged_window_)); | 536 DCHECK(!IsPopupOrTransient(dragged_window_)); |
| 538 if (is_dragged_window_docked_) | 537 if (is_dragged_window_docked_) |
| 539 OnDraggedWindowUndocked(); | 538 OnDraggedWindowUndocked(); |
| 540 DCHECK (!is_dragged_window_docked_); | 539 DCHECK (!is_dragged_window_docked_); |
| 541 // Stop observing a window unless it is docked container's child in which | 540 // Stop observing a window unless it is docked container's child in which |
| 542 // case it needs to keep being observed after the drag completes. | 541 // case it needs to keep being observed after the drag completes. |
| 543 if (dragged_window_->parent() != dock_container_) { | 542 if (dragged_window_->GetParent() != dock_container_) { |
| 544 dragged_window_->RemoveObserver(this); | 543 dragged_window_->RemoveObserver(this); |
| 545 wm::GetWindowState(dragged_window_)->RemoveObserver(this); | 544 dragged_window_->GetWindowState()->RemoveObserver(this); |
| 546 if (last_active_window_ == dragged_window_) | 545 if (last_active_window_ == dragged_window_) |
| 547 last_active_window_ = nullptr; | 546 last_active_window_ = nullptr; |
| 548 } else { | 547 } else { |
| 549 // If this is the first window that got docked by a move update alignment. | 548 // If this is the first window that got docked by a move update alignment. |
| 550 if (alignment_ == DOCKED_ALIGNMENT_NONE) | 549 if (alignment_ == DOCKED_ALIGNMENT_NONE) |
| 551 alignment_ = GetEdgeNearestWindow(dragged_window_); | 550 alignment_ = GetEdgeNearestWindow(dragged_window_); |
| 552 // A window is no longer dragged and is a child. | 551 // A window is no longer dragged and is a child. |
| 553 // When a window becomes a child at drag start this is | 552 // When a window becomes a child at drag start this is |
| 554 // the only opportunity we will have to enforce a window | 553 // the only opportunity we will have to enforce a window |
| 555 // count limit so do it here. | 554 // count limit so do it here. |
| 556 MaybeMinimizeChildrenExcept(dragged_window_); | 555 MaybeMinimizeChildrenExcept(dragged_window_); |
| 557 } | 556 } |
| 558 dragged_window_ = nullptr; | 557 dragged_window_ = nullptr; |
| 559 dragged_bounds_ = gfx::Rect(); | 558 dragged_bounds_ = gfx::Rect(); |
| 560 Relayout(); | 559 Relayout(); |
| 561 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 560 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 562 RecordUmaAction(action, source); | 561 RecordUmaAction(action, source); |
| 563 } | 562 } |
| 564 | 563 |
| 565 void DockedWindowLayoutManager::SetShelf(Shelf* shelf) { | 564 void DockedWindowLayoutManager::SetShelf(Shelf* shelf) { |
| 566 DCHECK(!shelf_); | 565 DCHECK(!shelf_); |
| 567 shelf_ = shelf; | 566 shelf_ = shelf; |
| 568 shelf_observer_.reset(new ShelfWindowObserver(this)); | 567 shelf_observer_.reset(new ShelfWindowObserver(this)); |
| 569 } | 568 } |
| 570 | 569 |
| 571 DockedAlignment DockedWindowLayoutManager::GetAlignmentOfWindow( | 570 DockedAlignment DockedWindowLayoutManager::GetAlignmentOfWindow( |
| 572 const aura::Window* window) const { | 571 const wm::WmWindow* window) const { |
| 573 const gfx::Rect& bounds(window->GetBoundsInScreen()); | 572 const gfx::Rect& bounds(window->GetBoundsInScreen()); |
| 574 | 573 |
| 575 // Test overlap with an existing docked area first. | 574 // Test overlap with an existing docked area first. |
| 576 if (docked_bounds_.Intersects(bounds) && | 575 if (docked_bounds_.Intersects(bounds) && |
| 577 alignment_ != DOCKED_ALIGNMENT_NONE) { | 576 alignment_ != DOCKED_ALIGNMENT_NONE) { |
| 578 // A window is being added to other docked windows (on the same side). | 577 // A window is being added to other docked windows (on the same side). |
| 579 return alignment_; | 578 return alignment_; |
| 580 } | 579 } |
| 581 | 580 |
| 582 const gfx::Rect container_bounds = dock_container_->GetBoundsInScreen(); | 581 const gfx::Rect container_bounds = dock_container_->GetBoundsInScreen(); |
| 583 if (bounds.x() <= container_bounds.x() && | 582 if (bounds.x() <= container_bounds.x() && |
| 584 bounds.right() > container_bounds.x()) { | 583 bounds.right() > container_bounds.x()) { |
| 585 return DOCKED_ALIGNMENT_LEFT; | 584 return DOCKED_ALIGNMENT_LEFT; |
| 586 } else if (bounds.x() < container_bounds.right() && | 585 } else if (bounds.x() < container_bounds.right() && |
| 587 bounds.right() >= container_bounds.right()) { | 586 bounds.right() >= container_bounds.right()) { |
| 588 return DOCKED_ALIGNMENT_RIGHT; | 587 return DOCKED_ALIGNMENT_RIGHT; |
| 589 } | 588 } |
| 590 return DOCKED_ALIGNMENT_NONE; | 589 return DOCKED_ALIGNMENT_NONE; |
| 591 } | 590 } |
| 592 | 591 |
| 593 DockedAlignment DockedWindowLayoutManager::CalculateAlignment() const { | 592 DockedAlignment DockedWindowLayoutManager::CalculateAlignment() const { |
| 594 return CalculateAlignmentExcept(dragged_window_); | 593 return CalculateAlignmentExcept(dragged_window_); |
| 595 } | 594 } |
| 596 | 595 |
| 597 DockedAlignment DockedWindowLayoutManager::CalculateAlignmentExcept( | 596 DockedAlignment DockedWindowLayoutManager::CalculateAlignmentExcept( |
| 598 const aura::Window* window) const { | 597 const wm::WmWindow* window) const { |
| 599 // Find a child that is not the window being queried and is not a popup. | 598 // Find a child that is not the window being queried and is not a popup. |
| 600 // If such exists the current alignment is returned - even if some of the | 599 // If such exists the current alignment is returned - even if some of the |
| 601 // children are hidden or minimized (so they can be restored without losing | 600 // children are hidden or minimized (so they can be restored without losing |
| 602 // the docked state). | 601 // the docked state). |
| 603 for (size_t i = 0; i < dock_container_->children().size(); ++i) { | 602 for (wm::WmWindow* child : dock_container_->GetChildren()) { |
| 604 aura::Window* child(dock_container_->children()[i]); | |
| 605 if (window != child && !IsPopupOrTransient(child)) | 603 if (window != child && !IsPopupOrTransient(child)) |
| 606 return alignment_; | 604 return alignment_; |
| 607 } | 605 } |
| 608 // No docked windows remain other than possibly the window being queried. | 606 // No docked windows remain other than possibly the window being queried. |
| 609 // Return |NONE| to indicate that windows may get docked on either side. | 607 // Return |NONE| to indicate that windows may get docked on either side. |
| 610 return DOCKED_ALIGNMENT_NONE; | 608 return DOCKED_ALIGNMENT_NONE; |
| 611 } | 609 } |
| 612 | 610 |
| 613 bool DockedWindowLayoutManager::CanDockWindow( | 611 bool DockedWindowLayoutManager::CanDockWindow( |
| 614 aura::Window* window, | 612 wm::WmWindow* window, |
| 615 DockedAlignment desired_alignment) { | 613 DockedAlignment desired_alignment) { |
| 616 // Don't allow interactive docking of windows with transient parents such as | 614 // Don't allow interactive docking of windows with transient parents such as |
| 617 // modal browser dialogs. Prevent docking of panels attached to shelf during | 615 // modal browser dialogs. Prevent docking of panels attached to shelf during |
| 618 // the drag. | 616 // the drag. |
| 619 wm::WindowState* window_state = wm::GetWindowState(window); | 617 wm::WindowState* window_state = window->GetWindowState(); |
| 620 bool should_attach_to_shelf = window_state->drag_details() && | 618 bool should_attach_to_shelf = window_state->drag_details() && |
| 621 window_state->drag_details()->should_attach_to_shelf; | 619 window_state->drag_details()->should_attach_to_shelf; |
| 622 if (IsPopupOrTransient(window) || should_attach_to_shelf) | 620 if (IsPopupOrTransient(window) || should_attach_to_shelf) |
| 623 return false; | 621 return false; |
| 624 // If a window is wide and cannot be resized down to maximum width allowed | 622 // If a window is wide and cannot be resized down to maximum width allowed |
| 625 // then it cannot be docked. | 623 // then it cannot be docked. |
| 626 // TODO(varkha). Prevent windows from changing size programmatically while | 624 // TODO(varkha). Prevent windows from changing size programmatically while |
| 627 // they are docked. The size will take effect only once a window is undocked. | 625 // they are docked. The size will take effect only once a window is undocked. |
| 628 // See http://crbug.com/307792. | 626 // See http://crbug.com/307792. |
| 629 if (window->bounds().width() > kMaxDockWidth && | 627 if (window->GetBounds().width() > kMaxDockWidth && |
| 630 (!window_state->CanResize() || | 628 (!window_state->CanResize() || |
| 631 (window->delegate() && | 629 (window->GetMinimumSize().width() != 0 && |
| 632 window->delegate()->GetMinimumSize().width() != 0 && | 630 window->GetMinimumSize().width() > kMaxDockWidth))) { |
| 633 window->delegate()->GetMinimumSize().width() > kMaxDockWidth))) { | |
| 634 return false; | 631 return false; |
| 635 } | 632 } |
| 636 // If a window is tall and cannot be resized down to maximum height allowed | 633 // If a window is tall and cannot be resized down to maximum height allowed |
| 637 // then it cannot be docked. | 634 // then it cannot be docked. |
| 638 const gfx::Rect work_area = gfx::Screen::GetScreen() | 635 const gfx::Rect work_area = |
| 639 ->GetDisplayNearestWindow(dock_container_) | 636 dock_container_->GetDisplayNearestWindow().work_area(); |
| 640 .work_area(); | |
| 641 if (GetWindowHeightCloseTo(window, work_area.height()) > work_area.height()) | 637 if (GetWindowHeightCloseTo(window, work_area.height()) > work_area.height()) |
| 642 return false; | 638 return false; |
| 643 // Cannot dock on the other size from an existing dock. | 639 // Cannot dock on the other size from an existing dock. |
| 644 const DockedAlignment alignment = CalculateAlignmentExcept(window); | 640 const DockedAlignment alignment = CalculateAlignmentExcept(window); |
| 645 if (desired_alignment != DOCKED_ALIGNMENT_NONE && | 641 if (desired_alignment != DOCKED_ALIGNMENT_NONE && |
| 646 alignment != DOCKED_ALIGNMENT_NONE && | 642 alignment != DOCKED_ALIGNMENT_NONE && |
| 647 alignment != desired_alignment) { | 643 alignment != desired_alignment) { |
| 648 return false; | 644 return false; |
| 649 } | 645 } |
| 650 // Do not allow docking on the same side as shelf. | 646 // Do not allow docking on the same side as shelf. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 //////////////////////////////////////////////////////////////////////////////// | 686 //////////////////////////////////////////////////////////////////////////////// |
| 691 // DockedWindowLayoutManager, aura::LayoutManager implementation: | 687 // DockedWindowLayoutManager, aura::LayoutManager implementation: |
| 692 void DockedWindowLayoutManager::OnWindowResized() { | 688 void DockedWindowLayoutManager::OnWindowResized() { |
| 693 MaybeMinimizeChildrenExcept(dragged_window_); | 689 MaybeMinimizeChildrenExcept(dragged_window_); |
| 694 Relayout(); | 690 Relayout(); |
| 695 // When screen resizes update the insets even when dock width or alignment | 691 // When screen resizes update the insets even when dock width or alignment |
| 696 // does not change. | 692 // does not change. |
| 697 UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_RESIZED); | 693 UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_RESIZED); |
| 698 } | 694 } |
| 699 | 695 |
| 700 void DockedWindowLayoutManager::OnWindowAddedToLayout(aura::Window* child) { | 696 void DockedWindowLayoutManager::OnWindowAddedToLayout(wm::WmWindow* child) { |
| 701 if (IsPopupOrTransient(child)) | 697 if (IsPopupOrTransient(child)) |
| 702 return; | 698 return; |
| 703 // Dragged windows are already observed by StartDragging and do not change | 699 // Dragged windows are already observed by StartDragging and do not change |
| 704 // docked alignment during the drag. | 700 // docked alignment during the drag. |
| 705 if (child == dragged_window_) | 701 if (child == dragged_window_) |
| 706 return; | 702 return; |
| 707 // If this is the first window getting docked - update alignment. | 703 // If this is the first window getting docked - update alignment. |
| 708 // A window can be added without proper bounds when window is moved to another | 704 // A window can be added without proper bounds when window is moved to another |
| 709 // display via API or due to display configuration change, so the alignment | 705 // display via API or due to display configuration change, so the alignment |
| 710 // is set based on which edge is closer in the new display. | 706 // is set based on which edge is closer in the new display. |
| 711 if (alignment_ == DOCKED_ALIGNMENT_NONE) { | 707 if (alignment_ == DOCKED_ALIGNMENT_NONE) { |
| 712 alignment_ = preferred_alignment_ != DOCKED_ALIGNMENT_NONE ? | 708 alignment_ = preferred_alignment_ != DOCKED_ALIGNMENT_NONE ? |
| 713 preferred_alignment_ : GetEdgeNearestWindow(child); | 709 preferred_alignment_ : GetEdgeNearestWindow(child); |
| 714 } | 710 } |
| 715 MaybeMinimizeChildrenExcept(child); | 711 MaybeMinimizeChildrenExcept(child); |
| 716 child->AddObserver(this); | 712 child->AddObserver(this); |
| 717 wm::GetWindowState(child)->AddObserver(this); | 713 child->GetWindowState()->AddObserver(this); |
| 718 Relayout(); | 714 Relayout(); |
| 719 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 715 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 720 | 716 |
| 721 // Only keyboard-initiated actions are recorded here. Dragging cases | 717 // Only keyboard-initiated actions are recorded here. Dragging cases |
| 722 // are handled in FinishDragging. | 718 // are handled in FinishDragging. |
| 723 if (event_source_ != DOCKED_ACTION_SOURCE_UNKNOWN) | 719 if (event_source_ != DOCKED_ACTION_SOURCE_UNKNOWN) |
| 724 RecordUmaAction(DOCKED_ACTION_DOCK, event_source_); | 720 RecordUmaAction(DOCKED_ACTION_DOCK, event_source_); |
| 725 } | 721 } |
| 726 | 722 |
| 727 void DockedWindowLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) { | 723 void DockedWindowLayoutManager::OnWindowRemovedFromLayout(wm::WmWindow* child) { |
| 728 if (IsPopupOrTransient(child)) | 724 if (IsPopupOrTransient(child)) |
| 729 return; | 725 return; |
| 730 // Dragged windows are stopped being observed by FinishDragging and do not | 726 // Dragged windows are stopped being observed by FinishDragging and do not |
| 731 // change alignment during the drag. They also cannot be set to be the | 727 // change alignment during the drag. They also cannot be set to be the |
| 732 // |last_active_window_|. | 728 // |last_active_window_|. |
| 733 if (child == dragged_window_) | 729 if (child == dragged_window_) |
| 734 return; | 730 return; |
| 735 // If this is the last window, set alignment and maximize the workspace. | 731 // If this is the last window, set alignment and maximize the workspace. |
| 736 if (!IsAnyWindowDocked()) { | 732 if (!IsAnyWindowDocked()) { |
| 737 alignment_ = DOCKED_ALIGNMENT_NONE; | 733 alignment_ = DOCKED_ALIGNMENT_NONE; |
| 738 UpdateDockedWidth(0); | 734 UpdateDockedWidth(0); |
| 739 } | 735 } |
| 740 if (last_active_window_ == child) | 736 if (last_active_window_ == child) |
| 741 last_active_window_ = nullptr; | 737 last_active_window_ = nullptr; |
| 742 child->RemoveObserver(this); | 738 child->RemoveObserver(this); |
| 743 wm::GetWindowState(child)->RemoveObserver(this); | 739 child->GetWindowState()->RemoveObserver(this); |
| 744 Relayout(); | 740 Relayout(); |
| 745 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 741 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 746 } | 742 } |
| 747 | 743 |
| 748 void DockedWindowLayoutManager::OnChildWindowVisibilityChanged( | 744 void DockedWindowLayoutManager::OnChildWindowVisibilityChanged( |
| 749 aura::Window* child, | 745 wm::WmWindow* child, |
| 750 bool visible) { | 746 bool visible) { |
| 751 if (IsPopupOrTransient(child)) | 747 if (IsPopupOrTransient(child)) |
| 752 return; | 748 return; |
| 753 | 749 |
| 754 wm::WindowState* window_state = wm::GetWindowState(child); | 750 wm::WindowState* window_state = child->GetWindowState(); |
| 755 if (visible && window_state->IsMinimized()) | 751 if (visible && window_state->IsMinimized()) |
| 756 window_state->Restore(); | 752 window_state->Restore(); |
| 757 Relayout(); | 753 Relayout(); |
| 758 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 754 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 759 } | 755 } |
| 760 | 756 |
| 761 void DockedWindowLayoutManager::SetChildBounds( | 757 void DockedWindowLayoutManager::SetChildBounds( |
| 762 aura::Window* child, | 758 wm::WmWindow* child, |
| 763 const gfx::Rect& requested_bounds) { | 759 const gfx::Rect& requested_bounds) { |
| 764 // The minimum constraints have to be applied first by the layout manager. | 760 // The minimum constraints have to be applied first by the layout manager. |
| 765 gfx::Rect actual_new_bounds(requested_bounds); | 761 gfx::Rect actual_new_bounds(requested_bounds); |
| 766 if (child->delegate()) { | 762 if (child->HasNonClientArea()) { |
| 767 const gfx::Size& min_size = child->delegate()->GetMinimumSize(); | 763 const gfx::Size min_size = child->GetMinimumSize(); |
| 768 actual_new_bounds.set_width( | 764 actual_new_bounds.set_width( |
| 769 std::max(min_size.width(), actual_new_bounds.width())); | 765 std::max(min_size.width(), actual_new_bounds.width())); |
| 770 actual_new_bounds.set_height( | 766 actual_new_bounds.set_height( |
| 771 std::max(min_size.height(), actual_new_bounds.height())); | 767 std::max(min_size.height(), actual_new_bounds.height())); |
| 772 } | 768 } |
| 773 if (IsWindowDocked(child) && child != dragged_window_) | 769 if (IsWindowDocked(child) && child != dragged_window_) |
| 774 return; | 770 return; |
| 775 SnapToPixelLayoutManager::SetChildBounds(child, actual_new_bounds); | 771 wm::WmSnapToPixelLayoutManager::SetChildBounds(child, actual_new_bounds); |
| 776 if (IsPopupOrTransient(child)) | 772 if (IsPopupOrTransient(child)) |
| 777 return; | 773 return; |
| 778 // Whenever one of our windows is moved or resized enforce layout. | 774 // Whenever one of our windows is moved or resized enforce layout. |
| 779 ShelfLayoutManager* shelf_layout = shelf_->shelf_layout_manager(); | 775 ShelfLayoutManager* shelf_layout = shelf_->shelf_layout_manager(); |
| 780 if (shelf_layout) | 776 if (shelf_layout) |
| 781 shelf_layout->UpdateVisibilityState(); | 777 shelf_layout->UpdateVisibilityState(); |
| 782 } | 778 } |
| 783 | 779 |
| 784 //////////////////////////////////////////////////////////////////////////////// | 780 //////////////////////////////////////////////////////////////////////////////// |
| 785 // DockedWindowLayoutManager, ash::ShellObserver implementation: | 781 // DockedWindowLayoutManager, ash::ShellObserver implementation: |
| 786 | 782 |
| 787 void DockedWindowLayoutManager::OnDisplayWorkAreaInsetsChanged() { | 783 void DockedWindowLayoutManager::OnDisplayWorkAreaInsetsChanged() { |
| 788 Relayout(); | 784 Relayout(); |
| 789 UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_INSETS_CHANGED); | 785 UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_INSETS_CHANGED); |
| 790 MaybeMinimizeChildrenExcept(dragged_window_); | 786 MaybeMinimizeChildrenExcept(dragged_window_); |
| 791 } | 787 } |
| 792 | 788 |
| 793 void DockedWindowLayoutManager::OnFullscreenStateChanged( | 789 void DockedWindowLayoutManager::OnFullscreenStateChanged( |
| 794 bool is_fullscreen, aura::Window* root_window) { | 790 bool is_fullscreen, aura::Window* root_window) { |
| 795 if (dock_container_->GetRootWindow() != root_window) | 791 if (dock_container_->GetRootWindow() != wm::WmWindowAura::Get(root_window)) |
| 796 return; | 792 return; |
| 797 // Entering fullscreen mode (including immersive) hides docked windows. | 793 // Entering fullscreen mode (including immersive) hides docked windows. |
| 798 in_fullscreen_ = workspace_controller_->GetWindowState() == | 794 in_fullscreen_ = workspace_controller_->GetWindowState() == |
| 799 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN; | 795 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN; |
| 800 { | 796 { |
| 801 // prevent Relayout from getting called multiple times during this | 797 // prevent Relayout from getting called multiple times during this |
| 802 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); | 798 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); |
| 803 // Use a copy of children array because a call to MinimizeDockedWindow or | 799 // Use a copy of children array because a call to MinimizeDockedWindow or |
| 804 // RestoreDockedWindow can change order. | 800 // RestoreDockedWindow can change order. |
| 805 aura::Window::Windows children(dock_container_->children()); | 801 for (wm::WmWindow* window : dock_container_->GetChildren()) { |
| 806 for (aura::Window::Windows::const_iterator iter = children.begin(); | |
| 807 iter != children.end(); ++iter) { | |
| 808 aura::Window* window(*iter); | |
| 809 if (IsPopupOrTransient(window)) | 802 if (IsPopupOrTransient(window)) |
| 810 continue; | 803 continue; |
| 811 wm::WindowState* window_state = wm::GetWindowState(window); | 804 wm::WindowState* window_state = window->GetWindowState(); |
| 812 if (in_fullscreen_) { | 805 if (in_fullscreen_) { |
| 813 if (window->IsVisible()) | 806 if (window->IsVisible()) |
| 814 MinimizeDockedWindow(window_state); | 807 MinimizeDockedWindow(window_state); |
| 815 } else { | 808 } else { |
| 816 if (!window_state->IsMinimized()) | 809 if (!window_state->IsMinimized()) |
| 817 RestoreDockedWindow(window_state); | 810 RestoreDockedWindow(window_state); |
| 818 } | 811 } |
| 819 } | 812 } |
| 820 } | 813 } |
| 821 Relayout(); | 814 Relayout(); |
| 822 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 815 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 823 } | 816 } |
| 824 | 817 |
| 825 void DockedWindowLayoutManager::OnShelfAlignmentChanged( | 818 void DockedWindowLayoutManager::OnShelfAlignmentChanged( |
| 826 aura::Window* root_window) { | 819 aura::Window* root_window) { |
| 827 if (dock_container_->GetRootWindow() != root_window) | 820 if (dock_container_->GetRootWindow() != wm::WmWindowAura::Get(root_window)) |
| 828 return; | 821 return; |
| 829 | 822 |
| 830 if (!shelf_ || alignment_ == DOCKED_ALIGNMENT_NONE) | 823 if (!shelf_ || alignment_ == DOCKED_ALIGNMENT_NONE) |
| 831 return; | 824 return; |
| 832 | 825 |
| 833 // Do not allow shelf and dock on the same side. Switch side that | 826 // Do not allow shelf and dock on the same side. Switch side that |
| 834 // the dock is attached to and move all dock windows to that new side. | 827 // the dock is attached to and move all dock windows to that new side. |
| 835 ShelfAlignment shelf_alignment = shelf_->alignment(); | 828 ShelfAlignment shelf_alignment = shelf_->alignment(); |
| 836 if (alignment_ == DOCKED_ALIGNMENT_LEFT && | 829 if (alignment_ == DOCKED_ALIGNMENT_LEFT && |
| 837 shelf_alignment == SHELF_ALIGNMENT_LEFT) { | 830 shelf_alignment == SHELF_ALIGNMENT_LEFT) { |
| 838 alignment_ = DOCKED_ALIGNMENT_RIGHT; | 831 alignment_ = DOCKED_ALIGNMENT_RIGHT; |
| 839 } else if (alignment_ == DOCKED_ALIGNMENT_RIGHT && | 832 } else if (alignment_ == DOCKED_ALIGNMENT_RIGHT && |
| 840 shelf_alignment == SHELF_ALIGNMENT_RIGHT) { | 833 shelf_alignment == SHELF_ALIGNMENT_RIGHT) { |
| 841 alignment_ = DOCKED_ALIGNMENT_LEFT; | 834 alignment_ = DOCKED_ALIGNMENT_LEFT; |
| 842 } | 835 } |
| 843 Relayout(); | 836 Relayout(); |
| 844 UpdateDockBounds(DockedWindowLayoutManagerObserver::SHELF_ALIGNMENT_CHANGED); | 837 UpdateDockBounds(DockedWindowLayoutManagerObserver::SHELF_ALIGNMENT_CHANGED); |
| 845 } | 838 } |
| 846 | 839 |
| 847 ///////////////////////////////////////////////////////////////////////////// | 840 ///////////////////////////////////////////////////////////////////////////// |
| 848 // DockedWindowLayoutManager, WindowStateObserver implementation: | 841 // DockedWindowLayoutManager, WindowStateObserver implementation: |
| 849 | 842 |
| 850 void DockedWindowLayoutManager::OnPreWindowStateTypeChange( | 843 void DockedWindowLayoutManager::OnPreWindowStateTypeChange( |
| 851 wm::WindowState* window_state, | 844 wm::WindowState* window_state, |
| 852 wm::WindowStateType old_type) { | 845 wm::WindowStateType old_type) { |
| 853 aura::Window* window = window_state->aura_window(); | 846 wm::WmWindow* window = window_state->window(); |
| 854 if (IsPopupOrTransient(window)) | 847 if (IsPopupOrTransient(window)) |
| 855 return; | 848 return; |
| 856 // The window property will still be set, but no actual change will occur | 849 // The window property will still be set, but no actual change will occur |
| 857 // until OnFullscreenStateChange is called when exiting fullscreen. | 850 // until OnFullscreenStateChange is called when exiting fullscreen. |
| 858 if (in_fullscreen_) | 851 if (in_fullscreen_) |
| 859 return; | 852 return; |
| 860 if (!window_state->IsDocked()) { | 853 if (!window_state->IsDocked()) { |
| 861 if (window != dragged_window_) { | 854 if (window != dragged_window_) { |
| 862 UndockWindow(window); | 855 UndockWindow(window); |
| 863 if (window_state->IsMaximizedOrFullscreen()) | 856 if (window_state->IsMaximizedOrFullscreen()) |
| 864 RecordUmaAction(DOCKED_ACTION_MAXIMIZE, event_source_); | 857 RecordUmaAction(DOCKED_ACTION_MAXIMIZE, event_source_); |
| 865 else | 858 else |
| 866 RecordUmaAction(DOCKED_ACTION_UNDOCK, event_source_); | 859 RecordUmaAction(DOCKED_ACTION_UNDOCK, event_source_); |
| 867 } | 860 } |
| 868 } else if (window_state->IsMinimized()) { | 861 } else if (window_state->IsMinimized()) { |
| 869 MinimizeDockedWindow(window_state); | 862 MinimizeDockedWindow(window_state); |
| 870 } else if (old_type == wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED) { | 863 } else if (old_type == wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED) { |
| 871 RestoreDockedWindow(window_state); | 864 RestoreDockedWindow(window_state); |
| 872 } else if (old_type == wm::WINDOW_STATE_TYPE_MINIMIZED) { | 865 } else if (old_type == wm::WINDOW_STATE_TYPE_MINIMIZED) { |
| 873 NOTREACHED() << "Minimized window in docked layout manager"; | 866 NOTREACHED() << "Minimized window in docked layout manager"; |
| 874 } | 867 } |
| 875 } | 868 } |
| 876 | 869 |
| 877 ///////////////////////////////////////////////////////////////////////////// | 870 ///////////////////////////////////////////////////////////////////////////// |
| 878 // DockedWindowLayoutManager, WindowObserver implementation: | 871 // DockedWindowLayoutManager, WindowObserver implementation: |
| 879 | 872 |
| 880 void DockedWindowLayoutManager::OnWindowBoundsChanged( | 873 void DockedWindowLayoutManager::OnWindowBoundsChanged( |
| 881 aura::Window* window, | 874 wm::WmWindow* window, |
| 882 const gfx::Rect& old_bounds, | 875 const gfx::Rect& old_bounds, |
| 883 const gfx::Rect& new_bounds) { | 876 const gfx::Rect& new_bounds) { |
| 884 // Only relayout if the dragged window would get docked. | 877 // Only relayout if the dragged window would get docked. |
| 885 if (window == dragged_window_ && is_dragged_window_docked_) | 878 if (window == dragged_window_ && is_dragged_window_docked_) |
| 886 Relayout(); | 879 Relayout(); |
| 887 } | 880 } |
| 888 | 881 |
| 889 void DockedWindowLayoutManager::OnWindowVisibilityChanging( | 882 void DockedWindowLayoutManager::OnWindowVisibilityChanging(wm::WmWindow* window, |
| 890 aura::Window* window, bool visible) { | 883 bool visible) { |
| 891 if (IsPopupOrTransient(window)) | 884 if (IsPopupOrTransient(window)) |
| 892 return; | 885 return; |
| 893 int animation_type = ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT; | 886 int animation_type = ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT; |
| 894 if (visible) { | 887 if (visible) { |
| 895 animation_type = ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DROP; | 888 animation_type = ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DROP; |
| 896 ::wm::SetWindowVisibilityAnimationDuration( | 889 window->SetVisibilityAnimationDuration( |
| 897 window, base::TimeDelta::FromMilliseconds(kFadeDurationMs)); | 890 base::TimeDelta::FromMilliseconds(kFadeDurationMs)); |
| 898 } else if (wm::GetWindowState(window)->IsMinimized()) { | 891 } else if (window->GetWindowState()->IsMinimized()) { |
| 899 animation_type = wm::WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE; | 892 animation_type = wm::WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE; |
| 900 } | 893 } |
| 901 ::wm::SetWindowVisibilityAnimationType(window, animation_type); | 894 window->SetVisibilityAnimationType(animation_type); |
| 902 } | 895 } |
| 903 | 896 |
| 904 void DockedWindowLayoutManager::OnWindowDestroying(aura::Window* window) { | 897 void DockedWindowLayoutManager::OnWindowDestroying(wm::WmWindow* window) { |
| 905 if (dragged_window_ == window) { | 898 if (dragged_window_ == window) { |
| 906 FinishDragging(DOCKED_ACTION_NONE, DOCKED_ACTION_SOURCE_UNKNOWN); | 899 FinishDragging(DOCKED_ACTION_NONE, DOCKED_ACTION_SOURCE_UNKNOWN); |
| 907 DCHECK(!dragged_window_); | 900 DCHECK(!dragged_window_); |
| 908 DCHECK(!is_dragged_window_docked_); | 901 DCHECK(!is_dragged_window_docked_); |
| 909 } | 902 } |
| 910 if (window == last_active_window_) | 903 if (window == last_active_window_) |
| 911 last_active_window_ = nullptr; | 904 last_active_window_ = nullptr; |
| 912 RecordUmaAction(DOCKED_ACTION_CLOSE, event_source_); | 905 RecordUmaAction(DOCKED_ACTION_CLOSE, event_source_); |
| 913 } | 906 } |
| 914 | 907 |
| 915 //////////////////////////////////////////////////////////////////////////////// | 908 //////////////////////////////////////////////////////////////////////////////// |
| 916 // DockedWindowLayoutManager, aura::client::ActivationChangeObserver | 909 // DockedWindowLayoutManager, wm::WmActivationObserver implementation: |
| 917 // implementation: | |
| 918 | 910 |
| 919 void DockedWindowLayoutManager::OnWindowActivated( | 911 void DockedWindowLayoutManager::OnWindowActivated(wm::WmWindow* gained_active, |
| 920 aura::client::ActivationChangeObserver::ActivationReason reason, | 912 wm::WmWindow* lost_active) { |
| 921 aura::Window* gained_active, | |
| 922 aura::Window* lost_active) { | |
| 923 if (gained_active && IsPopupOrTransient(gained_active)) | 913 if (gained_active && IsPopupOrTransient(gained_active)) |
| 924 return; | 914 return; |
| 925 // Ignore if the window that is not managed by this was activated. | 915 // Ignore if the window that is not managed by this was activated. |
| 926 aura::Window* ancestor = nullptr; | 916 wm::WmWindow* ancestor = nullptr; |
| 927 for (aura::Window* parent = gained_active; | 917 for (wm::WmWindow* parent = gained_active; parent; |
| 928 parent; parent = parent->parent()) { | 918 parent = parent->GetParent()) { |
| 929 if (parent->parent() == dock_container_) { | 919 if (parent->GetParent() == dock_container_) { |
| 930 ancestor = parent; | 920 ancestor = parent; |
| 931 break; | 921 break; |
| 932 } | 922 } |
| 933 } | 923 } |
| 934 if (ancestor) | 924 if (ancestor) |
| 935 UpdateStacking(ancestor); | 925 UpdateStacking(ancestor); |
| 936 } | 926 } |
| 937 | 927 |
| 938 //////////////////////////////////////////////////////////////////////////////// | 928 //////////////////////////////////////////////////////////////////////////////// |
| 939 // DockedWindowLayoutManager private implementation: | 929 // DockedWindowLayoutManager private implementation: |
| 940 | 930 |
| 941 void DockedWindowLayoutManager::MaybeMinimizeChildrenExcept( | 931 void DockedWindowLayoutManager::MaybeMinimizeChildrenExcept( |
| 942 aura::Window* child) { | 932 wm::WmWindow* child) { |
| 943 // Minimize any windows that don't fit without overlap. | 933 // Minimize any windows that don't fit without overlap. |
| 944 const gfx::Rect work_area = gfx::Screen::GetScreen() | 934 const gfx::Rect work_area = |
| 945 ->GetDisplayNearestWindow(dock_container_) | 935 dock_container_->GetDisplayNearestWindow().work_area(); |
| 946 .work_area(); | |
| 947 int available_room = work_area.height(); | 936 int available_room = work_area.height(); |
| 948 bool gap_needed = !!child; | 937 bool gap_needed = !!child; |
| 949 if (child) | 938 if (child) |
| 950 available_room -= GetWindowHeightCloseTo(child, 0); | 939 available_room -= GetWindowHeightCloseTo(child, 0); |
| 951 // Use a copy of children array because a call to Minimize can change order. | 940 // Use a copy of children array because a call to Minimize can change order. |
| 952 aura::Window::Windows children(dock_container_->children()); | 941 std::vector<wm::WmWindow*> children(dock_container_->GetChildren()); |
| 953 aura::Window::Windows::const_reverse_iterator iter = children.rbegin(); | 942 for (auto iter = children.rbegin(); iter != children.rend(); ++iter) { |
| 954 while (iter != children.rend()) { | 943 wm::WmWindow* window(*iter); |
| 955 aura::Window* window(*iter++); | |
| 956 if (window == child || !IsWindowDocked(window)) | 944 if (window == child || !IsWindowDocked(window)) |
| 957 continue; | 945 continue; |
| 958 int room_needed = GetWindowHeightCloseTo(window, 0) + | 946 int room_needed = GetWindowHeightCloseTo(window, 0) + |
| 959 (gap_needed ? kMinDockGap : 0); | 947 (gap_needed ? kMinDockGap : 0); |
| 960 gap_needed = true; | 948 gap_needed = true; |
| 961 if (available_room > room_needed) { | 949 if (available_room > room_needed) { |
| 962 available_room -= room_needed; | 950 available_room -= room_needed; |
| 963 } else { | 951 } else { |
| 964 // Slow down minimizing animations. Lock duration so that it is not | 952 // Slow down minimizing animations. Lock duration so that it is not |
| 965 // overridden by other ScopedLayerAnimationSettings down the stack. | 953 // overridden by other ScopedLayerAnimationSettings down the stack. |
| 966 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); | 954 ui::ScopedLayerAnimationSettings settings( |
| 955 window->GetLayer()->GetAnimator()); |
| 967 settings.SetTransitionDuration( | 956 settings.SetTransitionDuration( |
| 968 base::TimeDelta::FromMilliseconds(kMinimizeDurationMs)); | 957 base::TimeDelta::FromMilliseconds(kMinimizeDurationMs)); |
| 969 settings.LockTransitionDuration(); | 958 settings.LockTransitionDuration(); |
| 970 wm::GetWindowState(window)->Minimize(); | 959 window->GetWindowState()->Minimize(); |
| 971 } | 960 } |
| 972 } | 961 } |
| 973 } | 962 } |
| 974 | 963 |
| 975 void DockedWindowLayoutManager::MinimizeDockedWindow( | 964 void DockedWindowLayoutManager::MinimizeDockedWindow( |
| 976 wm::WindowState* window_state) { | 965 wm::WindowState* window_state) { |
| 977 DCHECK(!IsPopupOrTransient(window_state->aura_window())); | 966 DCHECK(!IsPopupOrTransient(window_state->window())); |
| 978 window_state->window()->Hide(); | 967 window_state->window()->Hide(); |
| 979 if (window_state->IsActive()) | 968 if (window_state->IsActive()) |
| 980 window_state->Deactivate(); | 969 window_state->Deactivate(); |
| 981 RecordUmaAction(DOCKED_ACTION_MINIMIZE, event_source_); | 970 RecordUmaAction(DOCKED_ACTION_MINIMIZE, event_source_); |
| 982 } | 971 } |
| 983 | 972 |
| 984 void DockedWindowLayoutManager::RestoreDockedWindow( | 973 void DockedWindowLayoutManager::RestoreDockedWindow( |
| 985 wm::WindowState* window_state) { | 974 wm::WindowState* window_state) { |
| 986 aura::Window* window = window_state->aura_window(); | 975 wm::WmWindow* window = window_state->window(); |
| 987 DCHECK(!IsPopupOrTransient(window)); | 976 DCHECK(!IsPopupOrTransient(window)); |
| 988 // Always place restored window at the bottom shuffling the other windows up. | |
| 989 // TODO(varkha): add a separate container for docked windows to keep track | |
| 990 // of ordering. | |
| 991 gfx::Display display = | |
| 992 gfx::Screen::GetScreen()->GetDisplayNearestWindow(dock_container_); | |
| 993 const gfx::Rect work_area = display.work_area(); | |
| 994 | 977 |
| 995 // Evict the window if it can no longer be docked because of its height. | 978 // Evict the window if it can no longer be docked because of its height. |
| 996 if (!CanDockWindow(window, DOCKED_ALIGNMENT_NONE)) { | 979 if (!CanDockWindow(window, DOCKED_ALIGNMENT_NONE)) { |
| 997 window_state->Restore(); | 980 window_state->Restore(); |
| 998 RecordUmaAction(DOCKED_ACTION_EVICT, event_source_); | 981 RecordUmaAction(DOCKED_ACTION_EVICT, event_source_); |
| 999 return; | 982 return; |
| 1000 } | 983 } |
| 1001 gfx::Rect bounds(window->bounds()); | 984 |
| 985 // Always place restored window at the bottom shuffling the other windows up. |
| 986 // TODO(varkha): add a separate container for docked windows to keep track |
| 987 // of ordering. |
| 988 const gfx::Rect work_area = |
| 989 dock_container_->GetDisplayNearestWindow().work_area(); |
| 990 gfx::Rect bounds(window->GetBounds()); |
| 1002 bounds.set_y(work_area.bottom()); | 991 bounds.set_y(work_area.bottom()); |
| 1003 window->SetBounds(bounds); | 992 window->SetBounds(bounds); |
| 1004 window->Show(); | 993 window->Show(); |
| 1005 MaybeMinimizeChildrenExcept(window); | 994 MaybeMinimizeChildrenExcept(window); |
| 1006 RecordUmaAction(DOCKED_ACTION_RESTORE, event_source_); | 995 RecordUmaAction(DOCKED_ACTION_RESTORE, event_source_); |
| 1007 } | 996 } |
| 1008 | 997 |
| 1009 void DockedWindowLayoutManager::RecordUmaAction(DockedAction action, | 998 void DockedWindowLayoutManager::RecordUmaAction(DockedAction action, |
| 1010 DockedActionSource source) { | 999 DockedActionSource source) { |
| 1011 if (action == DOCKED_ACTION_NONE) | 1000 if (action == DOCKED_ACTION_NONE) |
| 1012 return; | 1001 return; |
| 1013 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.Action", action, DOCKED_ACTION_COUNT); | 1002 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.Action", action, DOCKED_ACTION_COUNT); |
| 1014 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.ActionSource", source, | 1003 UMA_HISTOGRAM_ENUMERATION("Ash.Dock.ActionSource", source, |
| 1015 DOCKED_ACTION_SOURCE_COUNT); | 1004 DOCKED_ACTION_SOURCE_COUNT); |
| 1016 base::Time time_now = base::Time::Now(); | 1005 base::Time time_now = base::Time::Now(); |
| 1017 base::TimeDelta time_between_use = time_now - last_action_time_; | 1006 base::TimeDelta time_between_use = time_now - last_action_time_; |
| 1018 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.Dock.TimeBetweenUse", | 1007 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.Dock.TimeBetweenUse", |
| 1019 time_between_use.InSeconds(), | 1008 time_between_use.InSeconds(), |
| 1020 1, | 1009 1, |
| 1021 base::TimeDelta::FromHours(10).InSeconds(), | 1010 base::TimeDelta::FromHours(10).InSeconds(), |
| 1022 100); | 1011 100); |
| 1023 last_action_time_ = time_now; | 1012 last_action_time_ = time_now; |
| 1024 int docked_all_count = 0; | 1013 int docked_all_count = 0; |
| 1025 int docked_visible_count = 0; | 1014 int docked_visible_count = 0; |
| 1026 int docked_panels_count = 0; | 1015 int docked_panels_count = 0; |
| 1027 int large_windows_count = 0; | 1016 int large_windows_count = 0; |
| 1028 for (size_t i = 0; i < dock_container_->children().size(); ++i) { | 1017 for (wm::WmWindow* window : dock_container_->GetChildren()) { |
| 1029 const aura::Window* window(dock_container_->children()[i]); | |
| 1030 if (IsPopupOrTransient(window)) | 1018 if (IsPopupOrTransient(window)) |
| 1031 continue; | 1019 continue; |
| 1032 docked_all_count++; | 1020 docked_all_count++; |
| 1033 if (!IsWindowDocked(window)) | 1021 if (!IsWindowDocked(window)) |
| 1034 continue; | 1022 continue; |
| 1035 docked_visible_count++; | 1023 docked_visible_count++; |
| 1036 if (window->type() == ui::wm::WINDOW_TYPE_PANEL) | 1024 if (window->GetType() == ui::wm::WINDOW_TYPE_PANEL) |
| 1037 docked_panels_count++; | 1025 docked_panels_count++; |
| 1038 const wm::WindowState* window_state = wm::GetWindowState(window); | 1026 const wm::WindowState* window_state = window->GetWindowState(); |
| 1039 if (window_state->HasRestoreBounds()) { | 1027 if (window_state->HasRestoreBounds()) { |
| 1040 const gfx::Rect restore_bounds = window_state->GetRestoreBoundsInScreen(); | 1028 const gfx::Rect restore_bounds = window_state->GetRestoreBoundsInScreen(); |
| 1041 if (restore_bounds.width() > kMaxDockWidth) | 1029 if (restore_bounds.width() > kMaxDockWidth) |
| 1042 large_windows_count++; | 1030 large_windows_count++; |
| 1043 } | 1031 } |
| 1044 } | 1032 } |
| 1045 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsAll", docked_all_count); | 1033 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsAll", docked_all_count); |
| 1046 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsLarge", large_windows_count); | 1034 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsLarge", large_windows_count); |
| 1047 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsPanels", docked_panels_count); | 1035 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsPanels", docked_panels_count); |
| 1048 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsVisible", docked_visible_count); | 1036 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsVisible", docked_visible_count); |
| 1049 } | 1037 } |
| 1050 | 1038 |
| 1051 void DockedWindowLayoutManager::UpdateDockedWidth(int width) { | 1039 void DockedWindowLayoutManager::UpdateDockedWidth(int width) { |
| 1052 if (docked_width_ == width) | 1040 if (docked_width_ == width) |
| 1053 return; | 1041 return; |
| 1054 docked_width_ = width; | 1042 docked_width_ = width; |
| 1055 UMA_HISTOGRAM_COUNTS_10000("Ash.Dock.Width", docked_width_); | 1043 UMA_HISTOGRAM_COUNTS_10000("Ash.Dock.Width", docked_width_); |
| 1056 } | 1044 } |
| 1057 | 1045 |
| 1058 void DockedWindowLayoutManager::OnDraggedWindowDocked(aura::Window* window) { | 1046 void DockedWindowLayoutManager::OnDraggedWindowDocked(wm::WmWindow* window) { |
| 1059 DCHECK(!is_dragged_window_docked_); | 1047 DCHECK(!is_dragged_window_docked_); |
| 1060 is_dragged_window_docked_ = true; | 1048 is_dragged_window_docked_ = true; |
| 1061 } | 1049 } |
| 1062 | 1050 |
| 1063 void DockedWindowLayoutManager::OnDraggedWindowUndocked() { | 1051 void DockedWindowLayoutManager::OnDraggedWindowUndocked() { |
| 1064 DCHECK (is_dragged_window_docked_); | 1052 DCHECK (is_dragged_window_docked_); |
| 1065 is_dragged_window_docked_ = false; | 1053 is_dragged_window_docked_ = false; |
| 1066 } | 1054 } |
| 1067 | 1055 |
| 1068 bool DockedWindowLayoutManager::IsAnyWindowDocked() { | 1056 bool DockedWindowLayoutManager::IsAnyWindowDocked() { |
| 1069 return CalculateAlignment() != DOCKED_ALIGNMENT_NONE; | 1057 return CalculateAlignment() != DOCKED_ALIGNMENT_NONE; |
| 1070 } | 1058 } |
| 1071 | 1059 |
| 1072 DockedAlignment DockedWindowLayoutManager::GetEdgeNearestWindow( | 1060 DockedAlignment DockedWindowLayoutManager::GetEdgeNearestWindow( |
| 1073 const aura::Window* window) const { | 1061 const wm::WmWindow* window) const { |
| 1074 const gfx::Rect& bounds(window->GetBoundsInScreen()); | 1062 const gfx::Rect bounds(window->GetBoundsInScreen()); |
| 1075 const gfx::Rect container_bounds = dock_container_->GetBoundsInScreen(); | 1063 const gfx::Rect container_bounds = dock_container_->GetBoundsInScreen(); |
| 1076 // Give one pixel preference for docking on the right side to a window that | 1064 // Give one pixel preference for docking on the right side to a window that |
| 1077 // has odd width and is centered in a screen that has even width (or vice | 1065 // has odd width and is centered in a screen that has even width (or vice |
| 1078 // versa). This only matters to the tests but could be a source of flakiness. | 1066 // versa). This only matters to the tests but could be a source of flakiness. |
| 1079 return (abs(bounds.x() - container_bounds.x()) + 1 < | 1067 return (abs(bounds.x() - container_bounds.x()) + 1 < |
| 1080 abs(bounds.right() - container_bounds.right())) | 1068 abs(bounds.right() - container_bounds.right())) |
| 1081 ? DOCKED_ALIGNMENT_LEFT | 1069 ? DOCKED_ALIGNMENT_LEFT |
| 1082 : DOCKED_ALIGNMENT_RIGHT; | 1070 : DOCKED_ALIGNMENT_RIGHT; |
| 1083 } | 1071 } |
| 1084 | 1072 |
| 1085 void DockedWindowLayoutManager::Relayout() { | 1073 void DockedWindowLayoutManager::Relayout() { |
| 1086 if (in_layout_) | 1074 if (in_layout_) |
| 1087 return; | 1075 return; |
| 1088 if (alignment_ == DOCKED_ALIGNMENT_NONE && !is_dragged_window_docked_) | 1076 if (alignment_ == DOCKED_ALIGNMENT_NONE && !is_dragged_window_docked_) |
| 1089 return; | 1077 return; |
| 1090 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); | 1078 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); |
| 1091 | 1079 |
| 1092 gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen(); | 1080 gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen(); |
| 1093 aura::Window* active_window = nullptr; | 1081 wm::WmWindow* active_window = nullptr; |
| 1094 std::vector<WindowWithHeight> visible_windows; | 1082 std::vector<WindowWithHeight> visible_windows; |
| 1095 for (size_t i = 0; i < dock_container_->children().size(); ++i) { | 1083 for (wm::WmWindow* window : dock_container_->GetChildren()) { |
| 1096 aura::Window* window(dock_container_->children()[i]); | |
| 1097 | |
| 1098 if (!IsWindowDocked(window) || window == dragged_window_) | 1084 if (!IsWindowDocked(window) || window == dragged_window_) |
| 1099 continue; | 1085 continue; |
| 1100 | 1086 |
| 1101 // If the shelf is currently hidden (full-screen mode), hide window until | 1087 // If the shelf is currently hidden (full-screen mode), hide window until |
| 1102 // full-screen mode is exited. | 1088 // full-screen mode is exited. |
| 1103 if (in_fullscreen_) { | 1089 if (in_fullscreen_) { |
| 1104 // The call to Hide does not set the minimize property, so the window will | 1090 // The call to Hide does not set the minimize property, so the window will |
| 1105 // be restored when the shelf becomes visible again. | 1091 // be restored when the shelf becomes visible again. |
| 1106 window->Hide(); | 1092 window->Hide(); |
| 1107 continue; | 1093 continue; |
| 1108 } | 1094 } |
| 1109 if (window->HasFocus() || | 1095 if (window->IsFocused() || |
| 1110 window->Contains( | 1096 window->Contains(window->GetGlobals()->GetFocusedWindow())) { |
| 1111 aura::client::GetFocusClient(window)->GetFocusedWindow())) { | |
| 1112 DCHECK(!active_window); | 1097 DCHECK(!active_window); |
| 1113 active_window = window; | 1098 active_window = window; |
| 1114 } | 1099 } |
| 1115 visible_windows.push_back(WindowWithHeight(window)); | 1100 visible_windows.push_back(WindowWithHeight(window)); |
| 1116 } | 1101 } |
| 1117 // Consider docked dragged_window_ when fanning out other child windows. | 1102 // Consider docked dragged_window_ when fanning out other child windows. |
| 1118 if (is_dragged_window_docked_) { | 1103 if (is_dragged_window_docked_) { |
| 1119 visible_windows.push_back(WindowWithHeight(dragged_window_)); | 1104 visible_windows.push_back(WindowWithHeight(dragged_window_)); |
| 1120 DCHECK(!active_window); | 1105 DCHECK(!active_window); |
| 1121 active_window = dragged_window_; | 1106 active_window = dragged_window_; |
| 1122 } | 1107 } |
| 1123 | 1108 |
| 1124 // Position docked windows as well as the window being dragged. | 1109 // Position docked windows as well as the window being dragged. |
| 1125 gfx::Rect work_area = gfx::Screen::GetScreen() | 1110 gfx::Rect work_area = dock_container_->GetDisplayNearestWindow().work_area(); |
| 1126 ->GetDisplayNearestWindow(dock_container_) | |
| 1127 .work_area(); | |
| 1128 if (shelf_observer_) | 1111 if (shelf_observer_) |
| 1129 work_area.Subtract(shelf_observer_->shelf_bounds_in_screen()); | 1112 work_area.Subtract(shelf_observer_->shelf_bounds_in_screen()); |
| 1130 int available_room = CalculateWindowHeightsAndRemainingRoom(work_area, | 1113 int available_room = CalculateWindowHeightsAndRemainingRoom(work_area, |
| 1131 &visible_windows); | 1114 &visible_windows); |
| 1132 FanOutChildren(work_area, | 1115 FanOutChildren(work_area, |
| 1133 CalculateIdealWidth(visible_windows), | 1116 CalculateIdealWidth(visible_windows), |
| 1134 available_room, | 1117 available_room, |
| 1135 &visible_windows); | 1118 &visible_windows); |
| 1136 | 1119 |
| 1137 // After the first Relayout allow the windows to change their order easier | 1120 // After the first Relayout allow the windows to change their order easier |
| 1138 // since we know they are docked. | 1121 // since we know they are docked. |
| 1139 is_dragged_from_dock_ = true; | 1122 is_dragged_from_dock_ = true; |
| 1140 UpdateStacking(active_window); | 1123 UpdateStacking(active_window); |
| 1141 } | 1124 } |
| 1142 | 1125 |
| 1143 int DockedWindowLayoutManager::CalculateWindowHeightsAndRemainingRoom( | 1126 int DockedWindowLayoutManager::CalculateWindowHeightsAndRemainingRoom( |
| 1144 const gfx::Rect work_area, | 1127 const gfx::Rect& work_area, |
| 1145 std::vector<WindowWithHeight>* visible_windows) { | 1128 std::vector<WindowWithHeight>* visible_windows) { |
| 1146 int available_room = work_area.height(); | 1129 int available_room = work_area.height(); |
| 1147 int remaining_windows = visible_windows->size(); | 1130 int remaining_windows = visible_windows->size(); |
| 1148 int gap_height = remaining_windows > 1 ? kMinDockGap : 0; | 1131 int gap_height = remaining_windows > 1 ? kMinDockGap : 0; |
| 1149 | 1132 |
| 1150 // Sort windows by their minimum heights and calculate target heights. | 1133 // Sort windows by their minimum heights and calculate target heights. |
| 1151 std::sort(visible_windows->begin(), visible_windows->end(), | 1134 std::sort(visible_windows->begin(), visible_windows->end(), |
| 1152 CompareMinimumHeight()); | 1135 CompareMinimumHeight()); |
| 1153 // Distribute the free space among the docked windows. Since the windows are | 1136 // Distribute the free space among the docked windows. Since the windows are |
| 1154 // sorted (tall windows first) we can now assume that any window which | 1137 // sorted (tall windows first) we can now assume that any window which |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1171 const std::vector<WindowWithHeight>& visible_windows) { | 1154 const std::vector<WindowWithHeight>& visible_windows) { |
| 1172 int smallest_max_width = kMaxDockWidth; | 1155 int smallest_max_width = kMaxDockWidth; |
| 1173 int largest_min_width = kMinDockWidth; | 1156 int largest_min_width = kMinDockWidth; |
| 1174 // Ideal width of the docked area is as close to kIdealWidth as possible | 1157 // Ideal width of the docked area is as close to kIdealWidth as possible |
| 1175 // while still respecting the minimum and maximum width restrictions on the | 1158 // while still respecting the minimum and maximum width restrictions on the |
| 1176 // individual docked windows as well as the width that was possibly set by a | 1159 // individual docked windows as well as the width that was possibly set by a |
| 1177 // user (which needs to be preserved when dragging and rearranging windows). | 1160 // user (which needs to be preserved when dragging and rearranging windows). |
| 1178 for (std::vector<WindowWithHeight>::const_iterator iter = | 1161 for (std::vector<WindowWithHeight>::const_iterator iter = |
| 1179 visible_windows.begin(); | 1162 visible_windows.begin(); |
| 1180 iter != visible_windows.end(); ++iter) { | 1163 iter != visible_windows.end(); ++iter) { |
| 1181 const aura::Window* window = iter->window; | 1164 const wm::WmWindow* window = iter->window; |
| 1182 int min_window_width = window->bounds().width(); | 1165 int min_window_width = window->GetBounds().width(); |
| 1183 int max_window_width = min_window_width; | 1166 int max_window_width = min_window_width; |
| 1184 if (!wm::GetWindowState(window)->bounds_changed_by_user()) { | 1167 if (!window->GetWindowState()->bounds_changed_by_user()) { |
| 1185 min_window_width = GetWindowWidthCloseTo(window, kMinDockWidth); | 1168 min_window_width = GetWindowWidthCloseTo(window, kMinDockWidth); |
| 1186 max_window_width = GetWindowWidthCloseTo(window, kMaxDockWidth); | 1169 max_window_width = GetWindowWidthCloseTo(window, kMaxDockWidth); |
| 1187 } | 1170 } |
| 1188 largest_min_width = std::max(largest_min_width, min_window_width); | 1171 largest_min_width = std::max(largest_min_width, min_window_width); |
| 1189 smallest_max_width = std::min(smallest_max_width, max_window_width); | 1172 smallest_max_width = std::min(smallest_max_width, max_window_width); |
| 1190 } | 1173 } |
| 1191 int ideal_width = std::max(largest_min_width, | 1174 int ideal_width = std::max(largest_min_width, |
| 1192 std::min(smallest_max_width, kIdealWidth)); | 1175 std::min(smallest_max_width, kIdealWidth)); |
| 1193 // Restrict docked area width regardless of window restrictions. | 1176 // Restrict docked area width regardless of window restrictions. |
| 1194 ideal_width = std::max(std::min(ideal_width, kMaxDockWidth), kMinDockWidth); | 1177 ideal_width = std::max(std::min(ideal_width, kMaxDockWidth), kMinDockWidth); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1218 new_width = 0; | 1201 new_width = 0; |
| 1219 } | 1202 } |
| 1220 UpdateDockedWidth(new_width); | 1203 UpdateDockedWidth(new_width); |
| 1221 // Sort windows by their center positions and fan out overlapping | 1204 // Sort windows by their center positions and fan out overlapping |
| 1222 // windows. | 1205 // windows. |
| 1223 std::sort(visible_windows->begin(), visible_windows->end(), | 1206 std::sort(visible_windows->begin(), visible_windows->end(), |
| 1224 CompareWindowPos(is_dragged_from_dock_ ? dragged_window_ : nullptr, | 1207 CompareWindowPos(is_dragged_from_dock_ ? dragged_window_ : nullptr, |
| 1225 dock_container_, delta)); | 1208 dock_container_, delta)); |
| 1226 for (std::vector<WindowWithHeight>::iterator iter = visible_windows->begin(); | 1209 for (std::vector<WindowWithHeight>::iterator iter = visible_windows->begin(); |
| 1227 iter != visible_windows->end(); ++iter) { | 1210 iter != visible_windows->end(); ++iter) { |
| 1228 aura::Window* window = iter->window; | 1211 wm::WmWindow* window = iter->window; |
| 1229 gfx::Rect bounds = ScreenUtil::ConvertRectToScreen( | 1212 gfx::Rect bounds = |
| 1230 dock_container_, window->GetTargetBounds()); | 1213 dock_container_->ConvertRectToScreen(window->GetTargetBounds()); |
| 1231 // A window is extended or shrunk to be as close as possible to the ideal | 1214 // A window is extended or shrunk to be as close as possible to the ideal |
| 1232 // docked area width. Windows that were resized by a user are kept at their | 1215 // docked area width. Windows that were resized by a user are kept at their |
| 1233 // existing size. | 1216 // existing size. |
| 1234 // This also enforces the min / max restrictions on the docked area width. | 1217 // This also enforces the min / max restrictions on the docked area width. |
| 1235 bounds.set_width(GetWindowWidthCloseTo( | 1218 bounds.set_width(GetWindowWidthCloseTo( |
| 1236 window, | 1219 window, window->GetWindowState()->bounds_changed_by_user() |
| 1237 wm::GetWindowState(window)->bounds_changed_by_user() ? | 1220 ? bounds.width() |
| 1238 bounds.width() : ideal_docked_width)); | 1221 : ideal_docked_width)); |
| 1239 DCHECK_LE(bounds.width(), ideal_docked_width); | 1222 DCHECK_LE(bounds.width(), ideal_docked_width); |
| 1240 | 1223 |
| 1241 DockedAlignment alignment = alignment_; | 1224 DockedAlignment alignment = alignment_; |
| 1242 if (alignment == DOCKED_ALIGNMENT_NONE && window == dragged_window_) | 1225 if (alignment == DOCKED_ALIGNMENT_NONE && window == dragged_window_) |
| 1243 alignment = GetEdgeNearestWindow(window); | 1226 alignment = GetEdgeNearestWindow(window); |
| 1244 | 1227 |
| 1245 // Fan out windows evenly distributing the overlap or remaining free space. | 1228 // Fan out windows evenly distributing the overlap or remaining free space. |
| 1246 bounds.set_height(iter->height); | 1229 bounds.set_height(iter->height); |
| 1247 bounds.set_y(std::max(work_area.y(), | 1230 bounds.set_y(std::max(work_area.y(), |
| 1248 std::min(work_area.bottom() - bounds.height(), | 1231 std::min(work_area.bottom() - bounds.height(), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1263 case DOCKED_ALIGNMENT_NONE: | 1246 case DOCKED_ALIGNMENT_NONE: |
| 1264 break; | 1247 break; |
| 1265 } | 1248 } |
| 1266 if (window == dragged_window_) { | 1249 if (window == dragged_window_) { |
| 1267 dragged_bounds_ = bounds; | 1250 dragged_bounds_ = bounds; |
| 1268 continue; | 1251 continue; |
| 1269 } | 1252 } |
| 1270 // If the following asserts it is probably because not all the children | 1253 // If the following asserts it is probably because not all the children |
| 1271 // have been removed when dock was closed. | 1254 // have been removed when dock was closed. |
| 1272 DCHECK_NE(alignment_, DOCKED_ALIGNMENT_NONE); | 1255 DCHECK_NE(alignment_, DOCKED_ALIGNMENT_NONE); |
| 1273 bounds = ScreenUtil::ConvertRectFromScreen(dock_container_, bounds); | 1256 bounds = dock_container_->ConvertRectFromScreen(bounds); |
| 1274 if (bounds != window->GetTargetBounds()) { | 1257 if (bounds != window->GetTargetBounds()) { |
| 1275 ui::Layer* layer = window->layer(); | 1258 ui::Layer* layer = window->GetLayer(); |
| 1276 ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator()); | 1259 ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator()); |
| 1277 slide_settings.SetPreemptionStrategy( | 1260 slide_settings.SetPreemptionStrategy( |
| 1278 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 1261 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 1279 slide_settings.SetTransitionDuration( | 1262 slide_settings.SetTransitionDuration( |
| 1280 base::TimeDelta::FromMilliseconds(kSlideDurationMs)); | 1263 base::TimeDelta::FromMilliseconds(kSlideDurationMs)); |
| 1281 SetChildBoundsDirect(window, bounds); | 1264 window->SetBoundsDirect(bounds); |
| 1282 } | 1265 } |
| 1283 } | 1266 } |
| 1284 } | 1267 } |
| 1285 | 1268 |
| 1286 void DockedWindowLayoutManager::UpdateDockBounds( | 1269 void DockedWindowLayoutManager::UpdateDockBounds( |
| 1287 DockedWindowLayoutManagerObserver::Reason reason) { | 1270 DockedWindowLayoutManagerObserver::Reason reason) { |
| 1288 int dock_inset = docked_width_ + (docked_width_ > 0 ? kMinDockGap : 0); | 1271 int dock_inset = docked_width_ + (docked_width_ > 0 ? kMinDockGap : 0); |
| 1289 const gfx::Rect work_area = gfx::Screen::GetScreen() | 1272 const gfx::Rect work_area = |
| 1290 ->GetDisplayNearestWindow(dock_container_) | 1273 dock_container_->GetDisplayNearestWindow().work_area(); |
| 1291 .work_area(); | |
| 1292 gfx::Rect bounds = gfx::Rect( | 1274 gfx::Rect bounds = gfx::Rect( |
| 1293 alignment_ == DOCKED_ALIGNMENT_RIGHT && dock_inset > 0 ? | 1275 alignment_ == DOCKED_ALIGNMENT_RIGHT && dock_inset > 0 |
| 1294 dock_container_->bounds().right() - dock_inset: | 1276 ? dock_container_->GetBounds().right() - dock_inset |
| 1295 dock_container_->bounds().x(), | 1277 : dock_container_->GetBounds().x(), |
| 1296 dock_container_->bounds().y(), | 1278 dock_container_->GetBounds().y(), dock_inset, work_area.height()); |
| 1297 dock_inset, | |
| 1298 work_area.height()); | |
| 1299 docked_bounds_ = bounds + | 1279 docked_bounds_ = bounds + |
| 1300 dock_container_->GetBoundsInScreen().OffsetFromOrigin(); | 1280 dock_container_->GetBoundsInScreen().OffsetFromOrigin(); |
| 1301 FOR_EACH_OBSERVER( | 1281 FOR_EACH_OBSERVER( |
| 1302 DockedWindowLayoutManagerObserver, | 1282 DockedWindowLayoutManagerObserver, |
| 1303 observer_list_, | 1283 observer_list_, |
| 1304 OnDockBoundsChanging(bounds, reason)); | 1284 OnDockBoundsChanging(bounds, reason)); |
| 1305 // Show or hide background for docked area. | 1285 // Show or hide background for docked area. |
| 1306 gfx::Rect background_bounds(docked_bounds_); | 1286 gfx::Rect background_bounds(docked_bounds_); |
| 1307 if (shelf_observer_) | 1287 if (shelf_observer_) |
| 1308 background_bounds.Subtract(shelf_observer_->shelf_bounds_in_screen()); | 1288 background_bounds.Subtract(shelf_observer_->shelf_bounds_in_screen()); |
| 1309 if (docked_width_ > 0) { | 1289 if (docked_width_ > 0) { |
| 1310 if (!background_widget_) | 1290 if (!background_widget_) |
| 1311 background_widget_.reset(new DockedBackgroundWidget(this)); | 1291 background_widget_.reset(new DockedBackgroundWidget(this)); |
| 1312 background_widget_->SetBackgroundBounds(background_bounds, alignment_); | 1292 background_widget_->SetBackgroundBounds(background_bounds, alignment_); |
| 1313 background_widget_->Show(); | 1293 background_widget_->Show(); |
| 1314 } else if (background_widget_) { | 1294 } else if (background_widget_) { |
| 1315 background_widget_->Hide(); | 1295 background_widget_->Hide(); |
| 1316 } | 1296 } |
| 1317 } | 1297 } |
| 1318 | 1298 |
| 1319 void DockedWindowLayoutManager::UpdateStacking(aura::Window* active_window) { | 1299 void DockedWindowLayoutManager::UpdateStacking(wm::WmWindow* active_window) { |
| 1320 if (!active_window) { | 1300 if (!active_window) { |
| 1321 if (!last_active_window_) | 1301 if (!last_active_window_) |
| 1322 return; | 1302 return; |
| 1323 active_window = last_active_window_; | 1303 active_window = last_active_window_; |
| 1324 } | 1304 } |
| 1325 | 1305 |
| 1326 // Windows are stacked like a deck of cards: | 1306 // Windows are stacked like a deck of cards: |
| 1327 // ,------. | 1307 // ,------. |
| 1328 // |,------.| | 1308 // |,------.| |
| 1329 // |,------.| | 1309 // |,------.| |
| 1330 // | active | | 1310 // | active | |
| 1331 // | window | | 1311 // | window | |
| 1332 // |`------'| | 1312 // |`------'| |
| 1333 // |`------'| | 1313 // |`------'| |
| 1334 // `------' | 1314 // `------' |
| 1335 // Use the middle of each window to figure out how to stack the window. | 1315 // Use the middle of each window to figure out how to stack the window. |
| 1336 // This allows us to update the stacking when a window is being dragged around | 1316 // This allows us to update the stacking when a window is being dragged around |
| 1337 // by the titlebar. | 1317 // by the titlebar. |
| 1338 std::map<int, aura::Window*> window_ordering; | 1318 std::map<int, wm::WmWindow*> window_ordering; |
| 1339 for (aura::Window::Windows::const_iterator it = | 1319 for (wm::WmWindow* child : dock_container_->GetChildren()) { |
| 1340 dock_container_->children().begin(); | 1320 if (!IsWindowDocked(child) || |
| 1341 it != dock_container_->children().end(); ++it) { | 1321 (child == dragged_window_ && !is_dragged_window_docked_)) { |
| 1342 if (!IsWindowDocked(*it) || | |
| 1343 ((*it) == dragged_window_ && !is_dragged_window_docked_)) { | |
| 1344 continue; | 1322 continue; |
| 1345 } | 1323 } |
| 1346 gfx::Rect bounds = (*it)->bounds(); | 1324 gfx::Rect bounds = child->GetBounds(); |
| 1347 window_ordering.insert(std::make_pair(bounds.y() + bounds.height() / 2, | 1325 window_ordering.insert( |
| 1348 *it)); | 1326 std::make_pair(bounds.y() + bounds.height() / 2, child)); |
| 1349 } | 1327 } |
| 1350 int active_center_y = active_window->bounds().CenterPoint().y(); | 1328 int active_center_y = active_window->GetBounds().CenterPoint().y(); |
| 1351 | 1329 |
| 1352 aura::Window* previous_window = nullptr; | 1330 wm::WmWindow* previous_window = nullptr; |
| 1353 for (std::map<int, aura::Window*>::const_iterator it = | 1331 for (std::map<int, wm::WmWindow*>::const_iterator it = |
| 1354 window_ordering.begin(); | 1332 window_ordering.begin(); |
| 1355 it != window_ordering.end() && it->first < active_center_y; ++it) { | 1333 it != window_ordering.end() && it->first < active_center_y; ++it) { |
| 1356 if (previous_window) | 1334 if (previous_window) |
| 1357 dock_container_->StackChildAbove(it->second, previous_window); | 1335 dock_container_->StackChildAbove(it->second, previous_window); |
| 1358 previous_window = it->second; | 1336 previous_window = it->second; |
| 1359 } | 1337 } |
| 1360 for (std::map<int, aura::Window*>::const_reverse_iterator it = | 1338 for (std::map<int, wm::WmWindow*>::const_reverse_iterator it = |
| 1361 window_ordering.rbegin(); | 1339 window_ordering.rbegin(); |
| 1362 it != window_ordering.rend() && it->first > active_center_y; ++it) { | 1340 it != window_ordering.rend() && it->first > active_center_y; ++it) { |
| 1363 if (previous_window) | 1341 if (previous_window) |
| 1364 dock_container_->StackChildAbove(it->second, previous_window); | 1342 dock_container_->StackChildAbove(it->second, previous_window); |
| 1365 previous_window = it->second; | 1343 previous_window = it->second; |
| 1366 } | 1344 } |
| 1367 | 1345 |
| 1368 if (previous_window && active_window->parent() == dock_container_) | 1346 if (previous_window && active_window->GetParent() == dock_container_) |
| 1369 dock_container_->StackChildAbove(active_window, previous_window); | 1347 dock_container_->StackChildAbove(active_window, previous_window); |
| 1370 if (active_window != dragged_window_) | 1348 if (active_window != dragged_window_) |
| 1371 last_active_window_ = active_window; | 1349 last_active_window_ = active_window; |
| 1372 } | 1350 } |
| 1373 | 1351 |
| 1374 //////////////////////////////////////////////////////////////////////////////// | 1352 //////////////////////////////////////////////////////////////////////////////// |
| 1375 // keyboard::KeyboardControllerObserver implementation: | 1353 // keyboard::KeyboardControllerObserver implementation: |
| 1376 | 1354 |
| 1377 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( | 1355 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( |
| 1378 const gfx::Rect& keyboard_bounds) { | 1356 const gfx::Rect& keyboard_bounds) { |
| 1379 // This bounds change will have caused a change to the Shelf which does not | 1357 // This bounds change will have caused a change to the Shelf which does not |
| 1380 // propagate automatically to this class, so manually recalculate bounds. | 1358 // propagate automatically to this class, so manually recalculate bounds. |
| 1381 Relayout(); | 1359 Relayout(); |
| 1382 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); | 1360 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); |
| 1383 } | 1361 } |
| 1384 | 1362 |
| 1385 } // namespace ash | 1363 } // namespace ash |
| OLD | NEW |