| 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/common/wm/dock/docked_window_layout_manager.h" | 5 #include "ash/common/wm/dock/docked_window_layout_manager.h" |
| 6 | 6 |
| 7 #include "ash/common/shell_window_ids.h" | 7 #include "ash/common/shell_window_ids.h" |
| 8 #include "ash/common/wm/shelf/wm_shelf.h" | 8 #include "ash/common/wm/shelf/wm_shelf.h" |
| 9 #include "ash/common/wm/shelf/wm_shelf_constants.h" | 9 #include "ash/common/wm/shelf/wm_shelf_constants.h" |
| 10 #include "ash/common/wm/shelf/wm_shelf_observer.h" | 10 #include "ash/common/wm/shelf/wm_shelf_observer.h" |
| 11 #include "ash/common/wm/window_animation_types.h" | 11 #include "ash/common/wm/window_animation_types.h" |
| 12 #include "ash/common/wm/window_parenting_utils.h" | 12 #include "ash/common/wm/window_parenting_utils.h" |
| 13 #include "ash/common/wm/window_resizer.h" | 13 #include "ash/common/wm/window_resizer.h" |
| 14 #include "ash/common/wm/window_state.h" | 14 #include "ash/common/wm/window_state.h" |
| 15 #include "ash/common/wm/wm_globals.h" | 15 #include "ash/common/wm_lookup.h" |
| 16 #include "ash/common/wm/wm_lookup.h" | 16 #include "ash/common/wm_root_window_controller.h" |
| 17 #include "ash/common/wm/wm_root_window_controller.h" | 17 #include "ash/common/wm_shell.h" |
| 18 #include "ash/common/wm/wm_window.h" | 18 #include "ash/common/wm_window.h" |
| 19 #include "base/auto_reset.h" | 19 #include "base/auto_reset.h" |
| 20 #include "base/metrics/histogram.h" | 20 #include "base/metrics/histogram.h" |
| 21 #include "grit/ash_resources.h" | 21 #include "grit/ash_resources.h" |
| 22 #include "third_party/skia/include/core/SkColor.h" | 22 #include "third_party/skia/include/core/SkColor.h" |
| 23 #include "third_party/skia/include/core/SkPaint.h" | 23 #include "third_party/skia/include/core/SkPaint.h" |
| 24 #include "ui/base/resource/resource_bundle.h" | 24 #include "ui/base/resource/resource_bundle.h" |
| 25 #include "ui/compositor/paint_recorder.h" | 25 #include "ui/compositor/paint_recorder.h" |
| 26 #include "ui/compositor/scoped_layer_animation_settings.h" | 26 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 27 #include "ui/display/display.h" | 27 #include "ui/display/display.h" |
| 28 #include "ui/gfx/canvas.h" | 28 #include "ui/gfx/canvas.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 BackgroundAnimatorChangeType change_type) override { | 115 BackgroundAnimatorChangeType change_type) override { |
| 116 // Sets the background type. Starts an animation to transition to | 116 // Sets the background type. Starts an animation to transition to |
| 117 // |background_type| if the widget is visible. If the widget is not visible, | 117 // |background_type| if the widget is visible. If the widget is not visible, |
| 118 // the animation is postponed till the widget becomes visible. | 118 // the animation is postponed till the widget becomes visible. |
| 119 visible_background_type_ = background_type; | 119 visible_background_type_ = background_type; |
| 120 visible_background_change_type_ = change_type; | 120 visible_background_change_type_ = change_type; |
| 121 if (IsVisible()) | 121 if (IsVisible()) |
| 122 UpdateBackground(); | 122 UpdateBackground(); |
| 123 } | 123 } |
| 124 | 124 |
| 125 void InitWidget(wm::WmWindow* parent) { | 125 void InitWidget(WmWindow* parent) { |
| 126 views::Widget::InitParams params; | 126 views::Widget::InitParams params; |
| 127 params.type = views::Widget::InitParams::TYPE_POPUP; | 127 params.type = views::Widget::InitParams::TYPE_POPUP; |
| 128 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 128 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 129 params.keep_on_top = false; | 129 params.keep_on_top = false; |
| 130 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 130 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 131 params.accept_events = false; | 131 params.accept_events = false; |
| 132 set_focus_on_creation(false); | 132 set_focus_on_creation(false); |
| 133 parent->GetRootWindowController()->ConfigureWidgetInitParamsForContainer( | 133 parent->GetRootWindowController()->ConfigureWidgetInitParamsForContainer( |
| 134 this, parent->GetShellWindowId(), ¶ms); | 134 this, parent->GetShellWindowId(), ¶ms); |
| 135 Init(params); | 135 Init(params); |
| 136 SetVisibilityChangedAnimationsEnabled(false); | 136 SetVisibilityChangedAnimationsEnabled(false); |
| 137 wm::WmWindow* wm_window = wm::WmLookup::Get()->GetWindowForWidget(this); | 137 WmWindow* wm_window = WmLookup::Get()->GetWindowForWidget(this); |
| 138 wm_window->SetLockedToRoot(true); | 138 wm_window->SetLockedToRoot(true); |
| 139 opaque_background_.SetColor(SK_ColorBLACK); | 139 opaque_background_.SetColor(SK_ColorBLACK); |
| 140 opaque_background_.SetBounds(gfx::Rect(GetWindowBoundsInScreen().size())); | 140 opaque_background_.SetBounds(gfx::Rect(GetWindowBoundsInScreen().size())); |
| 141 opaque_background_.SetOpacity(0.0f); | 141 opaque_background_.SetOpacity(0.0f); |
| 142 wm_window->GetLayer()->Add(&opaque_background_); | 142 wm_window->GetLayer()->Add(&opaque_background_); |
| 143 | 143 |
| 144 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 144 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 145 gfx::ImageSkia shelf_background = | 145 gfx::ImageSkia shelf_background = |
| 146 *rb.GetImageSkiaNamed(IDR_ASH_SHELF_BACKGROUND); | 146 *rb.GetImageSkiaNamed(IDR_ASH_SHELF_BACKGROUND); |
| 147 shelf_background_left_ = gfx::ImageSkiaOperations::CreateRotatedImage( | 147 shelf_background_left_ = gfx::ImageSkiaOperations::CreateRotatedImage( |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 | 208 |
| 209 // Whether the widget should animate to |visible_background_type_|. | 209 // Whether the widget should animate to |visible_background_type_|. |
| 210 BackgroundAnimatorChangeType visible_background_change_type_; | 210 BackgroundAnimatorChangeType visible_background_change_type_; |
| 211 | 211 |
| 212 DISALLOW_COPY_AND_ASSIGN(DockedBackgroundWidget); | 212 DISALLOW_COPY_AND_ASSIGN(DockedBackgroundWidget); |
| 213 }; | 213 }; |
| 214 | 214 |
| 215 namespace { | 215 namespace { |
| 216 | 216 |
| 217 // Returns true if a window is a popup or a transient child. | 217 // Returns true if a window is a popup or a transient child. |
| 218 bool IsPopupOrTransient(const wm::WmWindow* window) { | 218 bool IsPopupOrTransient(const WmWindow* window) { |
| 219 return (window->GetType() == ui::wm::WINDOW_TYPE_POPUP || | 219 return (window->GetType() == ui::wm::WINDOW_TYPE_POPUP || |
| 220 window->GetTransientParent()); | 220 window->GetTransientParent()); |
| 221 } | 221 } |
| 222 | 222 |
| 223 // Certain windows (minimized, hidden or popups) are not docked and are ignored | 223 // Certain windows (minimized, hidden or popups) are not docked and are ignored |
| 224 // by layout logic even when they are children of a docked container. | 224 // by layout logic even when they are children of a docked container. |
| 225 bool IsWindowDocked(const wm::WmWindow* window) { | 225 bool IsWindowDocked(const WmWindow* window) { |
| 226 return (window->IsVisible() && !window->GetWindowState()->IsMinimized() && | 226 return (window->IsVisible() && !window->GetWindowState()->IsMinimized() && |
| 227 !IsPopupOrTransient(window)); | 227 !IsPopupOrTransient(window)); |
| 228 } | 228 } |
| 229 | 229 |
| 230 void UndockWindow(wm::WmWindow* window) { | 230 void UndockWindow(WmWindow* window) { |
| 231 gfx::Rect previous_bounds = window->GetBounds(); | 231 gfx::Rect previous_bounds = window->GetBounds(); |
| 232 wm::WmWindow* old_parent = window->GetParent(); | 232 WmWindow* old_parent = window->GetParent(); |
| 233 window->SetParentUsingContext(window, gfx::Rect()); | 233 window->SetParentUsingContext(window, gfx::Rect()); |
| 234 if (window->GetParent() != old_parent) { | 234 if (window->GetParent() != old_parent) { |
| 235 wm::ReparentTransientChildrenOfChild(window, old_parent, | 235 wm::ReparentTransientChildrenOfChild(window, old_parent, |
| 236 window->GetParent()); | 236 window->GetParent()); |
| 237 } | 237 } |
| 238 // Start maximize or fullscreen (affecting packaged apps) animation from | 238 // Start maximize or fullscreen (affecting packaged apps) animation from |
| 239 // previous window bounds. | 239 // previous window bounds. |
| 240 window->GetLayer()->SetBounds(previous_bounds); | 240 window->GetLayer()->SetBounds(previous_bounds); |
| 241 } | 241 } |
| 242 | 242 |
| 243 // Returns width that is as close as possible to |target_width| while being | 243 // Returns width that is as close as possible to |target_width| while being |
| 244 // consistent with docked min and max restrictions and respects the |window|'s | 244 // consistent with docked min and max restrictions and respects the |window|'s |
| 245 // minimum and maximum size. | 245 // minimum and maximum size. |
| 246 int GetWindowWidthCloseTo(const wm::WmWindow* window, int target_width) { | 246 int GetWindowWidthCloseTo(const WmWindow* window, int target_width) { |
| 247 if (!window->GetWindowState()->CanResize()) { | 247 if (!window->GetWindowState()->CanResize()) { |
| 248 DCHECK_LE(window->GetBounds().width(), | 248 DCHECK_LE(window->GetBounds().width(), |
| 249 DockedWindowLayoutManager::kMaxDockWidth); | 249 DockedWindowLayoutManager::kMaxDockWidth); |
| 250 return window->GetBounds().width(); | 250 return window->GetBounds().width(); |
| 251 } | 251 } |
| 252 int width = std::max( | 252 int width = std::max( |
| 253 DockedWindowLayoutManager::kMinDockWidth, | 253 DockedWindowLayoutManager::kMinDockWidth, |
| 254 std::min(target_width, DockedWindowLayoutManager::kMaxDockWidth)); | 254 std::min(target_width, DockedWindowLayoutManager::kMaxDockWidth)); |
| 255 width = std::max(width, window->GetMinimumSize().width()); | 255 width = std::max(width, window->GetMinimumSize().width()); |
| 256 if (window->GetMaximumSize().width() != 0) | 256 if (window->GetMaximumSize().width() != 0) |
| 257 width = std::min(width, window->GetMaximumSize().width()); | 257 width = std::min(width, window->GetMaximumSize().width()); |
| 258 DCHECK_LE(width, DockedWindowLayoutManager::kMaxDockWidth); | 258 DCHECK_LE(width, DockedWindowLayoutManager::kMaxDockWidth); |
| 259 return width; | 259 return width; |
| 260 } | 260 } |
| 261 | 261 |
| 262 // Returns height that is as close as possible to |target_height| while | 262 // Returns height that is as close as possible to |target_height| while |
| 263 // respecting the |window|'s minimum and maximum size. | 263 // respecting the |window|'s minimum and maximum size. |
| 264 int GetWindowHeightCloseTo(const wm::WmWindow* window, int target_height) { | 264 int GetWindowHeightCloseTo(const WmWindow* window, int target_height) { |
| 265 if (!window->GetWindowState()->CanResize()) | 265 if (!window->GetWindowState()->CanResize()) |
| 266 return window->GetBounds().height(); | 266 return window->GetBounds().height(); |
| 267 int minimum_height = | 267 int minimum_height = |
| 268 std::max(kMinimumHeight, window->GetMinimumSize().height()); | 268 std::max(kMinimumHeight, window->GetMinimumSize().height()); |
| 269 int maximum_height = window->GetMaximumSize().height(); | 269 int maximum_height = window->GetMaximumSize().height(); |
| 270 if (minimum_height) | 270 if (minimum_height) |
| 271 target_height = std::max(target_height, minimum_height); | 271 target_height = std::max(target_height, minimum_height); |
| 272 if (maximum_height) | 272 if (maximum_height) |
| 273 target_height = std::min(target_height, maximum_height); | 273 target_height = std::min(target_height, maximum_height); |
| 274 return target_height; | 274 return target_height; |
| 275 } | 275 } |
| 276 | 276 |
| 277 } // namespace | 277 } // namespace |
| 278 | 278 |
| 279 struct DockedWindowLayoutManager::WindowWithHeight { | 279 struct DockedWindowLayoutManager::WindowWithHeight { |
| 280 explicit WindowWithHeight(wm::WmWindow* window) | 280 explicit WindowWithHeight(WmWindow* window) |
| 281 : window(window), height(window->GetBounds().height()) {} | 281 : window(window), height(window->GetBounds().height()) {} |
| 282 wm::WmWindow* window; | 282 WmWindow* window; |
| 283 int height; | 283 int height; |
| 284 }; | 284 }; |
| 285 | 285 |
| 286 // A functor used to sort the windows in order of their minimum height. | 286 // A functor used to sort the windows in order of their minimum height. |
| 287 struct DockedWindowLayoutManager::CompareMinimumHeight { | 287 struct DockedWindowLayoutManager::CompareMinimumHeight { |
| 288 bool operator()(const WindowWithHeight& win1, const WindowWithHeight& win2) { | 288 bool operator()(const WindowWithHeight& win1, const WindowWithHeight& win2) { |
| 289 return GetWindowHeightCloseTo(win1.window, 0) < | 289 return GetWindowHeightCloseTo(win1.window, 0) < |
| 290 GetWindowHeightCloseTo(win2.window, 0); | 290 GetWindowHeightCloseTo(win2.window, 0); |
| 291 } | 291 } |
| 292 }; | 292 }; |
| 293 | 293 |
| 294 // A functor used to sort the windows in order of their center Y position. | 294 // A functor used to sort the windows in order of their center Y position. |
| 295 // |delta| is a pre-calculated distance from the bottom of one window to the top | 295 // |delta| is a pre-calculated distance from the bottom of one window to the top |
| 296 // of the next. Its value can be positive (gap) or negative (overlap). | 296 // of the next. Its value can be positive (gap) or negative (overlap). |
| 297 // Half of |delta| is used as a transition point at which windows could ideally | 297 // Half of |delta| is used as a transition point at which windows could ideally |
| 298 // swap positions. | 298 // swap positions. |
| 299 struct DockedWindowLayoutManager::CompareWindowPos { | 299 struct DockedWindowLayoutManager::CompareWindowPos { |
| 300 CompareWindowPos(wm::WmWindow* dragged_window, | 300 CompareWindowPos(WmWindow* dragged_window, |
| 301 wm::WmWindow* docked_container, | 301 WmWindow* docked_container, |
| 302 float delta) | 302 float delta) |
| 303 : dragged_window_(dragged_window), | 303 : dragged_window_(dragged_window), |
| 304 docked_container_(docked_container), | 304 docked_container_(docked_container), |
| 305 delta_(delta / 2) {} | 305 delta_(delta / 2) {} |
| 306 | 306 |
| 307 bool operator()(const WindowWithHeight& window_with_height1, | 307 bool operator()(const WindowWithHeight& window_with_height1, |
| 308 const WindowWithHeight& window_with_height2) { | 308 const WindowWithHeight& window_with_height2) { |
| 309 // Use target coordinates since animations may be active when windows are | 309 // Use target coordinates since animations may be active when windows are |
| 310 // reordered. | 310 // reordered. |
| 311 wm::WmWindow* win1(window_with_height1.window); | 311 WmWindow* win1(window_with_height1.window); |
| 312 wm::WmWindow* win2(window_with_height2.window); | 312 WmWindow* win2(window_with_height2.window); |
| 313 gfx::Rect win1_bounds = | 313 gfx::Rect win1_bounds = |
| 314 docked_container_->ConvertRectToScreen(win1->GetTargetBounds()); | 314 docked_container_->ConvertRectToScreen(win1->GetTargetBounds()); |
| 315 gfx::Rect win2_bounds = | 315 gfx::Rect win2_bounds = |
| 316 docked_container_->ConvertRectToScreen(win2->GetTargetBounds()); | 316 docked_container_->ConvertRectToScreen(win2->GetTargetBounds()); |
| 317 win1_bounds.set_height(window_with_height1.height); | 317 win1_bounds.set_height(window_with_height1.height); |
| 318 win2_bounds.set_height(window_with_height2.height); | 318 win2_bounds.set_height(window_with_height2.height); |
| 319 // If one of the windows is the |dragged_window_| attempt to make an | 319 // If one of the windows is the |dragged_window_| attempt to make an |
| 320 // earlier swap between the windows than just based on their centers. | 320 // earlier swap between the windows than just based on their centers. |
| 321 // This is possible if the dragged window is at least as tall as the other | 321 // This is possible if the dragged window is at least as tall as the other |
| 322 // window. | 322 // window. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 345 bool result2 = compare_bounds(bounds2, bounds1); | 345 bool result2 = compare_bounds(bounds2, bounds1); |
| 346 if (result1 != result2) | 346 if (result1 != result2) |
| 347 return result1; | 347 return result1; |
| 348 | 348 |
| 349 // Otherwise it is not possible to be sure that the windows will not bounce. | 349 // Otherwise it is not possible to be sure that the windows will not bounce. |
| 350 // In this case just compare the centers. | 350 // In this case just compare the centers. |
| 351 return bounds1.CenterPoint().y() < bounds2.CenterPoint().y(); | 351 return bounds1.CenterPoint().y() < bounds2.CenterPoint().y(); |
| 352 } | 352 } |
| 353 | 353 |
| 354 private: | 354 private: |
| 355 wm::WmWindow* dragged_window_; | 355 WmWindow* dragged_window_; |
| 356 wm::WmWindow* docked_container_; | 356 WmWindow* docked_container_; |
| 357 float delta_; | 357 float delta_; |
| 358 }; | 358 }; |
| 359 | 359 |
| 360 //////////////////////////////////////////////////////////////////////////////// | 360 //////////////////////////////////////////////////////////////////////////////// |
| 361 // A class that observes shelf for bounds changes. | 361 // A class that observes shelf for bounds changes. |
| 362 class DockedWindowLayoutManager::ShelfWindowObserver | 362 class DockedWindowLayoutManager::ShelfWindowObserver : public WmWindowObserver { |
| 363 : public wm::WmWindowObserver { | |
| 364 public: | 363 public: |
| 365 explicit ShelfWindowObserver(DockedWindowLayoutManager* docked_layout_manager) | 364 explicit ShelfWindowObserver(DockedWindowLayoutManager* docked_layout_manager) |
| 366 : docked_layout_manager_(docked_layout_manager) { | 365 : docked_layout_manager_(docked_layout_manager) { |
| 367 DCHECK(docked_layout_manager_->shelf()->GetWindow()); | 366 DCHECK(docked_layout_manager_->shelf()->GetWindow()); |
| 368 docked_layout_manager_->shelf()->GetWindow()->AddObserver(this); | 367 docked_layout_manager_->shelf()->GetWindow()->AddObserver(this); |
| 369 } | 368 } |
| 370 | 369 |
| 371 ~ShelfWindowObserver() override { | 370 ~ShelfWindowObserver() override { |
| 372 if (docked_layout_manager_->shelf() && | 371 if (docked_layout_manager_->shelf() && |
| 373 docked_layout_manager_->shelf()->GetWindow()) { | 372 docked_layout_manager_->shelf()->GetWindow()) { |
| 374 docked_layout_manager_->shelf()->GetWindow()->RemoveObserver(this); | 373 docked_layout_manager_->shelf()->GetWindow()->RemoveObserver(this); |
| 375 } | 374 } |
| 376 } | 375 } |
| 377 | 376 |
| 378 // wm::WmWindowObserver: | 377 // WmWindowObserver: |
| 379 void OnWindowBoundsChanged(wm::WmWindow* window, | 378 void OnWindowBoundsChanged(WmWindow* window, |
| 380 const gfx::Rect& old_bounds, | 379 const gfx::Rect& old_bounds, |
| 381 const gfx::Rect& new_bounds) override { | 380 const gfx::Rect& new_bounds) override { |
| 382 shelf_bounds_in_screen_ = | 381 shelf_bounds_in_screen_ = |
| 383 window->GetParent()->ConvertRectToScreen(new_bounds); | 382 window->GetParent()->ConvertRectToScreen(new_bounds); |
| 384 docked_layout_manager_->OnShelfBoundsChanged(); | 383 docked_layout_manager_->OnShelfBoundsChanged(); |
| 385 } | 384 } |
| 386 | 385 |
| 387 const gfx::Rect& shelf_bounds_in_screen() const { | 386 const gfx::Rect& shelf_bounds_in_screen() const { |
| 388 return shelf_bounds_in_screen_; | 387 return shelf_bounds_in_screen_; |
| 389 } | 388 } |
| 390 | 389 |
| 391 private: | 390 private: |
| 392 DockedWindowLayoutManager* docked_layout_manager_; | 391 DockedWindowLayoutManager* docked_layout_manager_; |
| 393 gfx::Rect shelf_bounds_in_screen_; | 392 gfx::Rect shelf_bounds_in_screen_; |
| 394 | 393 |
| 395 DISALLOW_COPY_AND_ASSIGN(ShelfWindowObserver); | 394 DISALLOW_COPY_AND_ASSIGN(ShelfWindowObserver); |
| 396 }; | 395 }; |
| 397 | 396 |
| 398 //////////////////////////////////////////////////////////////////////////////// | 397 //////////////////////////////////////////////////////////////////////////////// |
| 399 // DockedWindowLayoutManager public implementation: | 398 // DockedWindowLayoutManager public implementation: |
| 400 DockedWindowLayoutManager::DockedWindowLayoutManager( | 399 DockedWindowLayoutManager::DockedWindowLayoutManager(WmWindow* dock_container) |
| 401 wm::WmWindow* dock_container) | |
| 402 : dock_container_(dock_container), | 400 : dock_container_(dock_container), |
| 403 root_window_controller_(dock_container->GetRootWindowController()), | 401 root_window_controller_(dock_container->GetRootWindowController()), |
| 404 in_layout_(false), | 402 in_layout_(false), |
| 405 dragged_window_(nullptr), | 403 dragged_window_(nullptr), |
| 406 is_dragged_window_docked_(false), | 404 is_dragged_window_docked_(false), |
| 407 is_dragged_from_dock_(false), | 405 is_dragged_from_dock_(false), |
| 408 shelf_(nullptr), | 406 shelf_(nullptr), |
| 409 in_fullscreen_(root_window_controller_->GetWorkspaceWindowState() == | 407 in_fullscreen_(root_window_controller_->GetWorkspaceWindowState() == |
| 410 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN), | 408 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN), |
| 411 docked_width_(0), | 409 docked_width_(0), |
| 412 alignment_(DOCKED_ALIGNMENT_NONE), | 410 alignment_(DOCKED_ALIGNMENT_NONE), |
| 413 preferred_alignment_(DOCKED_ALIGNMENT_NONE), | 411 preferred_alignment_(DOCKED_ALIGNMENT_NONE), |
| 414 event_source_(DOCKED_ACTION_SOURCE_UNKNOWN), | 412 event_source_(DOCKED_ACTION_SOURCE_UNKNOWN), |
| 415 last_active_window_(nullptr), | 413 last_active_window_(nullptr), |
| 416 last_action_time_(base::Time::Now()), | 414 last_action_time_(base::Time::Now()), |
| 417 background_widget_(nullptr) { | 415 background_widget_(nullptr) { |
| 418 DCHECK(dock_container); | 416 DCHECK(dock_container); |
| 419 dock_container->GetGlobals()->AddActivationObserver(this); | 417 dock_container->GetShell()->AddActivationObserver(this); |
| 420 root_window_controller_->AddObserver(this); | 418 root_window_controller_->AddObserver(this); |
| 421 } | 419 } |
| 422 | 420 |
| 423 DockedWindowLayoutManager::~DockedWindowLayoutManager() { | 421 DockedWindowLayoutManager::~DockedWindowLayoutManager() { |
| 424 Shutdown(); | 422 Shutdown(); |
| 425 } | 423 } |
| 426 | 424 |
| 427 // static | 425 // static |
| 428 DockedWindowLayoutManager* DockedWindowLayoutManager::Get( | 426 DockedWindowLayoutManager* DockedWindowLayoutManager::Get(WmWindow* window) { |
| 429 wm::WmWindow* window) { | |
| 430 if (!window) | 427 if (!window) |
| 431 return nullptr; | 428 return nullptr; |
| 432 | 429 |
| 433 wm::WmWindow* root = window->GetRootWindow(); | 430 WmWindow* root = window->GetRootWindow(); |
| 434 return static_cast<DockedWindowLayoutManager*>( | 431 return static_cast<DockedWindowLayoutManager*>( |
| 435 root->GetChildByShellWindowId(kShellWindowId_DockedContainer) | 432 root->GetChildByShellWindowId(kShellWindowId_DockedContainer) |
| 436 ->GetLayoutManager()); | 433 ->GetLayoutManager()); |
| 437 } | 434 } |
| 438 | 435 |
| 439 void DockedWindowLayoutManager::Shutdown() { | 436 void DockedWindowLayoutManager::Shutdown() { |
| 440 background_widget_.reset(); | 437 background_widget_.reset(); |
| 441 shelf_observer_.reset(); | 438 shelf_observer_.reset(); |
| 442 shelf_ = nullptr; | 439 shelf_ = nullptr; |
| 443 for (wm::WmWindow* child : dock_container_->GetChildren()) { | 440 for (WmWindow* child : dock_container_->GetChildren()) { |
| 444 child->RemoveObserver(this); | 441 child->RemoveObserver(this); |
| 445 child->GetWindowState()->RemoveObserver(this); | 442 child->GetWindowState()->RemoveObserver(this); |
| 446 } | 443 } |
| 447 dock_container_->GetGlobals()->RemoveActivationObserver(this); | 444 dock_container_->GetShell()->RemoveActivationObserver(this); |
| 448 root_window_controller_->RemoveObserver(this); | 445 root_window_controller_->RemoveObserver(this); |
| 449 } | 446 } |
| 450 | 447 |
| 451 void DockedWindowLayoutManager::AddObserver( | 448 void DockedWindowLayoutManager::AddObserver( |
| 452 DockedWindowLayoutManagerObserver* observer) { | 449 DockedWindowLayoutManagerObserver* observer) { |
| 453 observer_list_.AddObserver(observer); | 450 observer_list_.AddObserver(observer); |
| 454 } | 451 } |
| 455 | 452 |
| 456 void DockedWindowLayoutManager::RemoveObserver( | 453 void DockedWindowLayoutManager::RemoveObserver( |
| 457 DockedWindowLayoutManagerObserver* observer) { | 454 DockedWindowLayoutManagerObserver* observer) { |
| 458 observer_list_.RemoveObserver(observer); | 455 observer_list_.RemoveObserver(observer); |
| 459 } | 456 } |
| 460 | 457 |
| 461 void DockedWindowLayoutManager::StartDragging(wm::WmWindow* window) { | 458 void DockedWindowLayoutManager::StartDragging(WmWindow* window) { |
| 462 DCHECK(!dragged_window_); | 459 DCHECK(!dragged_window_); |
| 463 dragged_window_ = window; | 460 dragged_window_ = window; |
| 464 DCHECK(!IsPopupOrTransient(window)); | 461 DCHECK(!IsPopupOrTransient(window)); |
| 465 // Start observing a window unless it is docked container's child in which | 462 // Start observing a window unless it is docked container's child in which |
| 466 // case it is already observed. | 463 // case it is already observed. |
| 467 wm::WindowState* dragged_state = dragged_window_->GetWindowState(); | 464 wm::WindowState* dragged_state = dragged_window_->GetWindowState(); |
| 468 if (dragged_window_->GetParent() != dock_container_) { | 465 if (dragged_window_->GetParent() != dock_container_) { |
| 469 dragged_window_->AddObserver(this); | 466 dragged_window_->AddObserver(this); |
| 470 dragged_state->AddObserver(this); | 467 dragged_state->AddObserver(this); |
| 471 } else if (!IsAnyWindowDocked() && dragged_state->drag_details() && | 468 } else if (!IsAnyWindowDocked() && dragged_state->drag_details() && |
| 472 !(dragged_state->drag_details()->bounds_change & | 469 !(dragged_state->drag_details()->bounds_change & |
| 473 WindowResizer::kBoundsChange_Resizes)) { | 470 WindowResizer::kBoundsChange_Resizes)) { |
| 474 // If there are no other docked windows clear alignment when a docked window | 471 // If there are no other docked windows clear alignment when a docked window |
| 475 // is moved (but not when it is resized or the window could get undocked | 472 // is moved (but not when it is resized or the window could get undocked |
| 476 // when resized away from the edge while docked). | 473 // when resized away from the edge while docked). |
| 477 alignment_ = DOCKED_ALIGNMENT_NONE; | 474 alignment_ = DOCKED_ALIGNMENT_NONE; |
| 478 } | 475 } |
| 479 is_dragged_from_dock_ = window->GetParent() == dock_container_; | 476 is_dragged_from_dock_ = window->GetParent() == dock_container_; |
| 480 DCHECK(!is_dragged_window_docked_); | 477 DCHECK(!is_dragged_window_docked_); |
| 481 | 478 |
| 482 // Resize all windows that are flush with the dock edge together if one of | 479 // Resize all windows that are flush with the dock edge together if one of |
| 483 // them gets resized. | 480 // them gets resized. |
| 484 if (dragged_window_->GetBounds().width() == docked_width_ && | 481 if (dragged_window_->GetBounds().width() == docked_width_ && |
| 485 (dragged_state->drag_details()->bounds_change & | 482 (dragged_state->drag_details()->bounds_change & |
| 486 WindowResizer::kBoundsChange_Resizes) && | 483 WindowResizer::kBoundsChange_Resizes) && |
| 487 (dragged_state->drag_details()->size_change_direction & | 484 (dragged_state->drag_details()->size_change_direction & |
| 488 WindowResizer::kBoundsChangeDirection_Horizontal)) { | 485 WindowResizer::kBoundsChangeDirection_Horizontal)) { |
| 489 for (wm::WmWindow* window1 : dock_container_->GetChildren()) { | 486 for (WmWindow* window1 : dock_container_->GetChildren()) { |
| 490 if (IsWindowDocked(window1) && window1 != dragged_window_ && | 487 if (IsWindowDocked(window1) && window1 != dragged_window_ && |
| 491 window1->GetBounds().width() == docked_width_) { | 488 window1->GetBounds().width() == docked_width_) { |
| 492 window1->GetWindowState()->set_bounds_changed_by_user(false); | 489 window1->GetWindowState()->set_bounds_changed_by_user(false); |
| 493 } | 490 } |
| 494 } | 491 } |
| 495 } | 492 } |
| 496 } | 493 } |
| 497 | 494 |
| 498 void DockedWindowLayoutManager::DockDraggedWindow(wm::WmWindow* window) { | 495 void DockedWindowLayoutManager::DockDraggedWindow(WmWindow* window) { |
| 499 DCHECK(!IsPopupOrTransient(window)); | 496 DCHECK(!IsPopupOrTransient(window)); |
| 500 OnDraggedWindowDocked(window); | 497 OnDraggedWindowDocked(window); |
| 501 Relayout(); | 498 Relayout(); |
| 502 } | 499 } |
| 503 | 500 |
| 504 void DockedWindowLayoutManager::UndockDraggedWindow() { | 501 void DockedWindowLayoutManager::UndockDraggedWindow() { |
| 505 DCHECK(!IsPopupOrTransient(dragged_window_)); | 502 DCHECK(!IsPopupOrTransient(dragged_window_)); |
| 506 OnDraggedWindowUndocked(); | 503 OnDraggedWindowUndocked(); |
| 507 Relayout(); | 504 Relayout(); |
| 508 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 505 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 RecordUmaAction(action, source); | 537 RecordUmaAction(action, source); |
| 541 } | 538 } |
| 542 | 539 |
| 543 void DockedWindowLayoutManager::SetShelf(wm::WmShelf* shelf) { | 540 void DockedWindowLayoutManager::SetShelf(wm::WmShelf* shelf) { |
| 544 DCHECK(!shelf_); | 541 DCHECK(!shelf_); |
| 545 shelf_ = shelf; | 542 shelf_ = shelf; |
| 546 shelf_observer_.reset(new ShelfWindowObserver(this)); | 543 shelf_observer_.reset(new ShelfWindowObserver(this)); |
| 547 } | 544 } |
| 548 | 545 |
| 549 DockedAlignment DockedWindowLayoutManager::GetAlignmentOfWindow( | 546 DockedAlignment DockedWindowLayoutManager::GetAlignmentOfWindow( |
| 550 const wm::WmWindow* window) const { | 547 const WmWindow* window) const { |
| 551 const gfx::Rect& bounds(window->GetBoundsInScreen()); | 548 const gfx::Rect& bounds(window->GetBoundsInScreen()); |
| 552 | 549 |
| 553 // Test overlap with an existing docked area first. | 550 // Test overlap with an existing docked area first. |
| 554 if (docked_bounds_.Intersects(bounds) && | 551 if (docked_bounds_.Intersects(bounds) && |
| 555 alignment_ != DOCKED_ALIGNMENT_NONE) { | 552 alignment_ != DOCKED_ALIGNMENT_NONE) { |
| 556 // A window is being added to other docked windows (on the same side). | 553 // A window is being added to other docked windows (on the same side). |
| 557 return alignment_; | 554 return alignment_; |
| 558 } | 555 } |
| 559 | 556 |
| 560 const gfx::Rect container_bounds = dock_container_->GetBoundsInScreen(); | 557 const gfx::Rect container_bounds = dock_container_->GetBoundsInScreen(); |
| 561 if (bounds.x() <= container_bounds.x() && | 558 if (bounds.x() <= container_bounds.x() && |
| 562 bounds.right() > container_bounds.x()) { | 559 bounds.right() > container_bounds.x()) { |
| 563 return DOCKED_ALIGNMENT_LEFT; | 560 return DOCKED_ALIGNMENT_LEFT; |
| 564 } else if (bounds.x() < container_bounds.right() && | 561 } else if (bounds.x() < container_bounds.right() && |
| 565 bounds.right() >= container_bounds.right()) { | 562 bounds.right() >= container_bounds.right()) { |
| 566 return DOCKED_ALIGNMENT_RIGHT; | 563 return DOCKED_ALIGNMENT_RIGHT; |
| 567 } | 564 } |
| 568 return DOCKED_ALIGNMENT_NONE; | 565 return DOCKED_ALIGNMENT_NONE; |
| 569 } | 566 } |
| 570 | 567 |
| 571 DockedAlignment DockedWindowLayoutManager::CalculateAlignment() const { | 568 DockedAlignment DockedWindowLayoutManager::CalculateAlignment() const { |
| 572 return CalculateAlignmentExcept(dragged_window_); | 569 return CalculateAlignmentExcept(dragged_window_); |
| 573 } | 570 } |
| 574 | 571 |
| 575 DockedAlignment DockedWindowLayoutManager::CalculateAlignmentExcept( | 572 DockedAlignment DockedWindowLayoutManager::CalculateAlignmentExcept( |
| 576 const wm::WmWindow* window) const { | 573 const WmWindow* window) const { |
| 577 // Find a child that is not the window being queried and is not a popup. | 574 // Find a child that is not the window being queried and is not a popup. |
| 578 // If such exists the current alignment is returned - even if some of the | 575 // If such exists the current alignment is returned - even if some of the |
| 579 // children are hidden or minimized (so they can be restored without losing | 576 // children are hidden or minimized (so they can be restored without losing |
| 580 // the docked state). | 577 // the docked state). |
| 581 for (wm::WmWindow* child : dock_container_->GetChildren()) { | 578 for (WmWindow* child : dock_container_->GetChildren()) { |
| 582 if (window != child && !IsPopupOrTransient(child)) | 579 if (window != child && !IsPopupOrTransient(child)) |
| 583 return alignment_; | 580 return alignment_; |
| 584 } | 581 } |
| 585 // No docked windows remain other than possibly the window being queried. | 582 // No docked windows remain other than possibly the window being queried. |
| 586 // Return |NONE| to indicate that windows may get docked on either side. | 583 // Return |NONE| to indicate that windows may get docked on either side. |
| 587 return DOCKED_ALIGNMENT_NONE; | 584 return DOCKED_ALIGNMENT_NONE; |
| 588 } | 585 } |
| 589 | 586 |
| 590 bool DockedWindowLayoutManager::CanDockWindow( | 587 bool DockedWindowLayoutManager::CanDockWindow( |
| 591 wm::WmWindow* window, | 588 WmWindow* window, |
| 592 DockedAlignment desired_alignment) { | 589 DockedAlignment desired_alignment) { |
| 593 // Don't allow interactive docking of windows with transient parents such as | 590 // Don't allow interactive docking of windows with transient parents such as |
| 594 // modal browser dialogs. Prevent docking of panels attached to shelf during | 591 // modal browser dialogs. Prevent docking of panels attached to shelf during |
| 595 // the drag. | 592 // the drag. |
| 596 wm::WindowState* window_state = window->GetWindowState(); | 593 wm::WindowState* window_state = window->GetWindowState(); |
| 597 bool should_attach_to_shelf = | 594 bool should_attach_to_shelf = |
| 598 window_state->drag_details() && | 595 window_state->drag_details() && |
| 599 window_state->drag_details()->should_attach_to_shelf; | 596 window_state->drag_details()->should_attach_to_shelf; |
| 600 if (IsPopupOrTransient(window) || should_attach_to_shelf) | 597 if (IsPopupOrTransient(window) || should_attach_to_shelf) |
| 601 return false; | 598 return false; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 //////////////////////////////////////////////////////////////////////////////// | 661 //////////////////////////////////////////////////////////////////////////////// |
| 665 // DockedWindowLayoutManager, aura::LayoutManager implementation: | 662 // DockedWindowLayoutManager, aura::LayoutManager implementation: |
| 666 void DockedWindowLayoutManager::OnWindowResized() { | 663 void DockedWindowLayoutManager::OnWindowResized() { |
| 667 MaybeMinimizeChildrenExcept(dragged_window_); | 664 MaybeMinimizeChildrenExcept(dragged_window_); |
| 668 Relayout(); | 665 Relayout(); |
| 669 // When screen resizes update the insets even when dock width or alignment | 666 // When screen resizes update the insets even when dock width or alignment |
| 670 // does not change. | 667 // does not change. |
| 671 UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_RESIZED); | 668 UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_RESIZED); |
| 672 } | 669 } |
| 673 | 670 |
| 674 void DockedWindowLayoutManager::OnWindowAddedToLayout(wm::WmWindow* child) { | 671 void DockedWindowLayoutManager::OnWindowAddedToLayout(WmWindow* child) { |
| 675 if (IsPopupOrTransient(child)) | 672 if (IsPopupOrTransient(child)) |
| 676 return; | 673 return; |
| 677 // Dragged windows are already observed by StartDragging and do not change | 674 // Dragged windows are already observed by StartDragging and do not change |
| 678 // docked alignment during the drag. | 675 // docked alignment during the drag. |
| 679 if (child == dragged_window_) | 676 if (child == dragged_window_) |
| 680 return; | 677 return; |
| 681 // If this is the first window getting docked - update alignment. | 678 // If this is the first window getting docked - update alignment. |
| 682 // A window can be added without proper bounds when window is moved to another | 679 // A window can be added without proper bounds when window is moved to another |
| 683 // display via API or due to display configuration change, so the alignment | 680 // display via API or due to display configuration change, so the alignment |
| 684 // is set based on which edge is closer in the new display. | 681 // is set based on which edge is closer in the new display. |
| 685 if (alignment_ == DOCKED_ALIGNMENT_NONE) { | 682 if (alignment_ == DOCKED_ALIGNMENT_NONE) { |
| 686 alignment_ = preferred_alignment_ != DOCKED_ALIGNMENT_NONE | 683 alignment_ = preferred_alignment_ != DOCKED_ALIGNMENT_NONE |
| 687 ? preferred_alignment_ | 684 ? preferred_alignment_ |
| 688 : GetEdgeNearestWindow(child); | 685 : GetEdgeNearestWindow(child); |
| 689 } | 686 } |
| 690 MaybeMinimizeChildrenExcept(child); | 687 MaybeMinimizeChildrenExcept(child); |
| 691 child->AddObserver(this); | 688 child->AddObserver(this); |
| 692 child->GetWindowState()->AddObserver(this); | 689 child->GetWindowState()->AddObserver(this); |
| 693 Relayout(); | 690 Relayout(); |
| 694 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 691 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 695 | 692 |
| 696 // Only keyboard-initiated actions are recorded here. Dragging cases | 693 // Only keyboard-initiated actions are recorded here. Dragging cases |
| 697 // are handled in FinishDragging. | 694 // are handled in FinishDragging. |
| 698 if (event_source_ != DOCKED_ACTION_SOURCE_UNKNOWN) | 695 if (event_source_ != DOCKED_ACTION_SOURCE_UNKNOWN) |
| 699 RecordUmaAction(DOCKED_ACTION_DOCK, event_source_); | 696 RecordUmaAction(DOCKED_ACTION_DOCK, event_source_); |
| 700 } | 697 } |
| 701 | 698 |
| 702 void DockedWindowLayoutManager::OnWindowRemovedFromLayout(wm::WmWindow* child) { | 699 void DockedWindowLayoutManager::OnWindowRemovedFromLayout(WmWindow* child) { |
| 703 if (IsPopupOrTransient(child)) | 700 if (IsPopupOrTransient(child)) |
| 704 return; | 701 return; |
| 705 // Dragged windows are stopped being observed by FinishDragging and do not | 702 // Dragged windows are stopped being observed by FinishDragging and do not |
| 706 // change alignment during the drag. They also cannot be set to be the | 703 // change alignment during the drag. They also cannot be set to be the |
| 707 // |last_active_window_|. | 704 // |last_active_window_|. |
| 708 if (child == dragged_window_) | 705 if (child == dragged_window_) |
| 709 return; | 706 return; |
| 710 // If this is the last window, set alignment and maximize the workspace. | 707 // If this is the last window, set alignment and maximize the workspace. |
| 711 if (!IsAnyWindowDocked()) { | 708 if (!IsAnyWindowDocked()) { |
| 712 alignment_ = DOCKED_ALIGNMENT_NONE; | 709 alignment_ = DOCKED_ALIGNMENT_NONE; |
| 713 UpdateDockedWidth(0); | 710 UpdateDockedWidth(0); |
| 714 } | 711 } |
| 715 if (last_active_window_ == child) | 712 if (last_active_window_ == child) |
| 716 last_active_window_ = nullptr; | 713 last_active_window_ = nullptr; |
| 717 child->RemoveObserver(this); | 714 child->RemoveObserver(this); |
| 718 child->GetWindowState()->RemoveObserver(this); | 715 child->GetWindowState()->RemoveObserver(this); |
| 719 Relayout(); | 716 Relayout(); |
| 720 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 717 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 721 } | 718 } |
| 722 | 719 |
| 723 void DockedWindowLayoutManager::OnChildWindowVisibilityChanged( | 720 void DockedWindowLayoutManager::OnChildWindowVisibilityChanged(WmWindow* child, |
| 724 wm::WmWindow* child, | 721 bool visible) { |
| 725 bool visible) { | |
| 726 if (IsPopupOrTransient(child)) | 722 if (IsPopupOrTransient(child)) |
| 727 return; | 723 return; |
| 728 | 724 |
| 729 wm::WindowState* window_state = child->GetWindowState(); | 725 wm::WindowState* window_state = child->GetWindowState(); |
| 730 if (visible && window_state->IsMinimized()) | 726 if (visible && window_state->IsMinimized()) |
| 731 window_state->Restore(); | 727 window_state->Restore(); |
| 732 Relayout(); | 728 Relayout(); |
| 733 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); | 729 UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); |
| 734 } | 730 } |
| 735 | 731 |
| 736 void DockedWindowLayoutManager::SetChildBounds( | 732 void DockedWindowLayoutManager::SetChildBounds( |
| 737 wm::WmWindow* child, | 733 WmWindow* child, |
| 738 const gfx::Rect& requested_bounds) { | 734 const gfx::Rect& requested_bounds) { |
| 739 // The minimum constraints have to be applied first by the layout manager. | 735 // The minimum constraints have to be applied first by the layout manager. |
| 740 gfx::Rect actual_new_bounds(requested_bounds); | 736 gfx::Rect actual_new_bounds(requested_bounds); |
| 741 if (child->HasNonClientArea()) { | 737 if (child->HasNonClientArea()) { |
| 742 const gfx::Size min_size = child->GetMinimumSize(); | 738 const gfx::Size min_size = child->GetMinimumSize(); |
| 743 actual_new_bounds.set_width( | 739 actual_new_bounds.set_width( |
| 744 std::max(min_size.width(), actual_new_bounds.width())); | 740 std::max(min_size.width(), actual_new_bounds.width())); |
| 745 actual_new_bounds.set_height( | 741 actual_new_bounds.set_height( |
| 746 std::max(min_size.height(), actual_new_bounds.height())); | 742 std::max(min_size.height(), actual_new_bounds.height())); |
| 747 } | 743 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 766 | 762 |
| 767 void DockedWindowLayoutManager::OnFullscreenStateChanged(bool is_fullscreen) { | 763 void DockedWindowLayoutManager::OnFullscreenStateChanged(bool is_fullscreen) { |
| 768 // Entering fullscreen mode (including immersive) hides docked windows. | 764 // Entering fullscreen mode (including immersive) hides docked windows. |
| 769 in_fullscreen_ = root_window_controller_->GetWorkspaceWindowState() == | 765 in_fullscreen_ = root_window_controller_->GetWorkspaceWindowState() == |
| 770 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN; | 766 wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN; |
| 771 { | 767 { |
| 772 // prevent Relayout from getting called multiple times during this | 768 // prevent Relayout from getting called multiple times during this |
| 773 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); | 769 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); |
| 774 // Use a copy of children array because a call to MinimizeDockedWindow or | 770 // Use a copy of children array because a call to MinimizeDockedWindow or |
| 775 // RestoreDockedWindow can change order. | 771 // RestoreDockedWindow can change order. |
| 776 for (wm::WmWindow* window : dock_container_->GetChildren()) { | 772 for (WmWindow* window : dock_container_->GetChildren()) { |
| 777 if (IsPopupOrTransient(window)) | 773 if (IsPopupOrTransient(window)) |
| 778 continue; | 774 continue; |
| 779 wm::WindowState* window_state = window->GetWindowState(); | 775 wm::WindowState* window_state = window->GetWindowState(); |
| 780 if (in_fullscreen_) { | 776 if (in_fullscreen_) { |
| 781 if (window->IsVisible()) | 777 if (window->IsVisible()) |
| 782 MinimizeDockedWindow(window_state); | 778 MinimizeDockedWindow(window_state); |
| 783 } else { | 779 } else { |
| 784 if (!window_state->IsMinimized()) | 780 if (!window_state->IsMinimized()) |
| 785 RestoreDockedWindow(window_state); | 781 RestoreDockedWindow(window_state); |
| 786 } | 782 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 807 Relayout(); | 803 Relayout(); |
| 808 UpdateDockBounds(DockedWindowLayoutManagerObserver::SHELF_ALIGNMENT_CHANGED); | 804 UpdateDockBounds(DockedWindowLayoutManagerObserver::SHELF_ALIGNMENT_CHANGED); |
| 809 } | 805 } |
| 810 | 806 |
| 811 ///////////////////////////////////////////////////////////////////////////// | 807 ///////////////////////////////////////////////////////////////////////////// |
| 812 // DockedWindowLayoutManager, WindowStateObserver implementation: | 808 // DockedWindowLayoutManager, WindowStateObserver implementation: |
| 813 | 809 |
| 814 void DockedWindowLayoutManager::OnPreWindowStateTypeChange( | 810 void DockedWindowLayoutManager::OnPreWindowStateTypeChange( |
| 815 wm::WindowState* window_state, | 811 wm::WindowState* window_state, |
| 816 wm::WindowStateType old_type) { | 812 wm::WindowStateType old_type) { |
| 817 wm::WmWindow* window = window_state->window(); | 813 WmWindow* window = window_state->window(); |
| 818 if (IsPopupOrTransient(window)) | 814 if (IsPopupOrTransient(window)) |
| 819 return; | 815 return; |
| 820 // The window property will still be set, but no actual change will occur | 816 // The window property will still be set, but no actual change will occur |
| 821 // until OnFullscreenStateChange is called when exiting fullscreen. | 817 // until OnFullscreenStateChange is called when exiting fullscreen. |
| 822 if (in_fullscreen_) | 818 if (in_fullscreen_) |
| 823 return; | 819 return; |
| 824 if (!window_state->IsDocked()) { | 820 if (!window_state->IsDocked()) { |
| 825 if (window != dragged_window_) { | 821 if (window != dragged_window_) { |
| 826 UndockWindow(window); | 822 UndockWindow(window); |
| 827 if (window_state->IsMaximizedOrFullscreen()) | 823 if (window_state->IsMaximizedOrFullscreen()) |
| 828 RecordUmaAction(DOCKED_ACTION_MAXIMIZE, event_source_); | 824 RecordUmaAction(DOCKED_ACTION_MAXIMIZE, event_source_); |
| 829 else | 825 else |
| 830 RecordUmaAction(DOCKED_ACTION_UNDOCK, event_source_); | 826 RecordUmaAction(DOCKED_ACTION_UNDOCK, event_source_); |
| 831 } | 827 } |
| 832 } else if (window_state->IsMinimized()) { | 828 } else if (window_state->IsMinimized()) { |
| 833 MinimizeDockedWindow(window_state); | 829 MinimizeDockedWindow(window_state); |
| 834 } else if (old_type == wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED) { | 830 } else if (old_type == wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED) { |
| 835 RestoreDockedWindow(window_state); | 831 RestoreDockedWindow(window_state); |
| 836 } else if (old_type == wm::WINDOW_STATE_TYPE_MINIMIZED) { | 832 } else if (old_type == wm::WINDOW_STATE_TYPE_MINIMIZED) { |
| 837 NOTREACHED() << "Minimized window in docked layout manager"; | 833 NOTREACHED() << "Minimized window in docked layout manager"; |
| 838 } | 834 } |
| 839 } | 835 } |
| 840 | 836 |
| 841 ///////////////////////////////////////////////////////////////////////////// | 837 ///////////////////////////////////////////////////////////////////////////// |
| 842 // DockedWindowLayoutManager, WindowObserver implementation: | 838 // DockedWindowLayoutManager, WindowObserver implementation: |
| 843 | 839 |
| 844 void DockedWindowLayoutManager::OnWindowBoundsChanged( | 840 void DockedWindowLayoutManager::OnWindowBoundsChanged( |
| 845 wm::WmWindow* window, | 841 WmWindow* window, |
| 846 const gfx::Rect& old_bounds, | 842 const gfx::Rect& old_bounds, |
| 847 const gfx::Rect& new_bounds) { | 843 const gfx::Rect& new_bounds) { |
| 848 // Only relayout if the dragged window would get docked. | 844 // Only relayout if the dragged window would get docked. |
| 849 if (window == dragged_window_ && is_dragged_window_docked_) | 845 if (window == dragged_window_ && is_dragged_window_docked_) |
| 850 Relayout(); | 846 Relayout(); |
| 851 } | 847 } |
| 852 | 848 |
| 853 void DockedWindowLayoutManager::OnWindowVisibilityChanging(wm::WmWindow* window, | 849 void DockedWindowLayoutManager::OnWindowVisibilityChanging(WmWindow* window, |
| 854 bool visible) { | 850 bool visible) { |
| 855 if (IsPopupOrTransient(window)) | 851 if (IsPopupOrTransient(window)) |
| 856 return; | 852 return; |
| 857 int animation_type = ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT; | 853 int animation_type = ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT; |
| 858 if (visible) { | 854 if (visible) { |
| 859 animation_type = ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DROP; | 855 animation_type = ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DROP; |
| 860 window->SetVisibilityAnimationDuration( | 856 window->SetVisibilityAnimationDuration( |
| 861 base::TimeDelta::FromMilliseconds(kFadeDurationMs)); | 857 base::TimeDelta::FromMilliseconds(kFadeDurationMs)); |
| 862 } else if (window->GetWindowState()->IsMinimized()) { | 858 } else if (window->GetWindowState()->IsMinimized()) { |
| 863 animation_type = wm::WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE; | 859 animation_type = wm::WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE; |
| 864 } | 860 } |
| 865 window->SetVisibilityAnimationType(animation_type); | 861 window->SetVisibilityAnimationType(animation_type); |
| 866 } | 862 } |
| 867 | 863 |
| 868 void DockedWindowLayoutManager::OnWindowDestroying(wm::WmWindow* window) { | 864 void DockedWindowLayoutManager::OnWindowDestroying(WmWindow* window) { |
| 869 if (dragged_window_ == window) { | 865 if (dragged_window_ == window) { |
| 870 FinishDragging(DOCKED_ACTION_NONE, DOCKED_ACTION_SOURCE_UNKNOWN); | 866 FinishDragging(DOCKED_ACTION_NONE, DOCKED_ACTION_SOURCE_UNKNOWN); |
| 871 DCHECK(!dragged_window_); | 867 DCHECK(!dragged_window_); |
| 872 DCHECK(!is_dragged_window_docked_); | 868 DCHECK(!is_dragged_window_docked_); |
| 873 } | 869 } |
| 874 if (window == last_active_window_) | 870 if (window == last_active_window_) |
| 875 last_active_window_ = nullptr; | 871 last_active_window_ = nullptr; |
| 876 RecordUmaAction(DOCKED_ACTION_CLOSE, event_source_); | 872 RecordUmaAction(DOCKED_ACTION_CLOSE, event_source_); |
| 877 } | 873 } |
| 878 | 874 |
| 879 //////////////////////////////////////////////////////////////////////////////// | 875 //////////////////////////////////////////////////////////////////////////////// |
| 880 // DockedWindowLayoutManager, wm::WmActivationObserver implementation: | 876 // DockedWindowLayoutManager, WmActivationObserver implementation: |
| 881 | 877 |
| 882 void DockedWindowLayoutManager::OnWindowActivated(wm::WmWindow* gained_active, | 878 void DockedWindowLayoutManager::OnWindowActivated(WmWindow* gained_active, |
| 883 wm::WmWindow* lost_active) { | 879 WmWindow* lost_active) { |
| 884 if (gained_active && IsPopupOrTransient(gained_active)) | 880 if (gained_active && IsPopupOrTransient(gained_active)) |
| 885 return; | 881 return; |
| 886 // Ignore if the window that is not managed by this was activated. | 882 // Ignore if the window that is not managed by this was activated. |
| 887 wm::WmWindow* ancestor = nullptr; | 883 WmWindow* ancestor = nullptr; |
| 888 for (wm::WmWindow* parent = gained_active; parent; | 884 for (WmWindow* parent = gained_active; parent; parent = parent->GetParent()) { |
| 889 parent = parent->GetParent()) { | |
| 890 if (parent->GetParent() == dock_container_) { | 885 if (parent->GetParent() == dock_container_) { |
| 891 ancestor = parent; | 886 ancestor = parent; |
| 892 break; | 887 break; |
| 893 } | 888 } |
| 894 } | 889 } |
| 895 if (ancestor) | 890 if (ancestor) |
| 896 UpdateStacking(ancestor); | 891 UpdateStacking(ancestor); |
| 897 } | 892 } |
| 898 | 893 |
| 899 //////////////////////////////////////////////////////////////////////////////// | 894 //////////////////////////////////////////////////////////////////////////////// |
| 900 // DockedWindowLayoutManager private implementation: | 895 // DockedWindowLayoutManager private implementation: |
| 901 | 896 |
| 902 void DockedWindowLayoutManager::MaybeMinimizeChildrenExcept( | 897 void DockedWindowLayoutManager::MaybeMinimizeChildrenExcept(WmWindow* child) { |
| 903 wm::WmWindow* child) { | |
| 904 // Minimize any windows that don't fit without overlap. | 898 // Minimize any windows that don't fit without overlap. |
| 905 const gfx::Rect work_area = | 899 const gfx::Rect work_area = |
| 906 dock_container_->GetDisplayNearestWindow().work_area(); | 900 dock_container_->GetDisplayNearestWindow().work_area(); |
| 907 int available_room = work_area.height(); | 901 int available_room = work_area.height(); |
| 908 bool gap_needed = !!child; | 902 bool gap_needed = !!child; |
| 909 if (child) | 903 if (child) |
| 910 available_room -= GetWindowHeightCloseTo(child, 0); | 904 available_room -= GetWindowHeightCloseTo(child, 0); |
| 911 // Use a copy of children array because a call to Minimize can change order. | 905 // Use a copy of children array because a call to Minimize can change order. |
| 912 std::vector<wm::WmWindow*> children(dock_container_->GetChildren()); | 906 std::vector<WmWindow*> children(dock_container_->GetChildren()); |
| 913 for (auto iter = children.rbegin(); iter != children.rend(); ++iter) { | 907 for (auto iter = children.rbegin(); iter != children.rend(); ++iter) { |
| 914 wm::WmWindow* window(*iter); | 908 WmWindow* window(*iter); |
| 915 if (window == child || !IsWindowDocked(window)) | 909 if (window == child || !IsWindowDocked(window)) |
| 916 continue; | 910 continue; |
| 917 int room_needed = | 911 int room_needed = |
| 918 GetWindowHeightCloseTo(window, 0) + (gap_needed ? kMinDockGap : 0); | 912 GetWindowHeightCloseTo(window, 0) + (gap_needed ? kMinDockGap : 0); |
| 919 gap_needed = true; | 913 gap_needed = true; |
| 920 if (available_room > room_needed) { | 914 if (available_room > room_needed) { |
| 921 available_room -= room_needed; | 915 available_room -= room_needed; |
| 922 } else { | 916 } else { |
| 923 // Slow down minimizing animations. Lock duration so that it is not | 917 // Slow down minimizing animations. Lock duration so that it is not |
| 924 // overridden by other ScopedLayerAnimationSettings down the stack. | 918 // overridden by other ScopedLayerAnimationSettings down the stack. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 936 wm::WindowState* window_state) { | 930 wm::WindowState* window_state) { |
| 937 DCHECK(!IsPopupOrTransient(window_state->window())); | 931 DCHECK(!IsPopupOrTransient(window_state->window())); |
| 938 window_state->window()->Hide(); | 932 window_state->window()->Hide(); |
| 939 if (window_state->IsActive()) | 933 if (window_state->IsActive()) |
| 940 window_state->Deactivate(); | 934 window_state->Deactivate(); |
| 941 RecordUmaAction(DOCKED_ACTION_MINIMIZE, event_source_); | 935 RecordUmaAction(DOCKED_ACTION_MINIMIZE, event_source_); |
| 942 } | 936 } |
| 943 | 937 |
| 944 void DockedWindowLayoutManager::RestoreDockedWindow( | 938 void DockedWindowLayoutManager::RestoreDockedWindow( |
| 945 wm::WindowState* window_state) { | 939 wm::WindowState* window_state) { |
| 946 wm::WmWindow* window = window_state->window(); | 940 WmWindow* window = window_state->window(); |
| 947 DCHECK(!IsPopupOrTransient(window)); | 941 DCHECK(!IsPopupOrTransient(window)); |
| 948 | 942 |
| 949 // Evict the window if it can no longer be docked because of its height. | 943 // Evict the window if it can no longer be docked because of its height. |
| 950 if (!CanDockWindow(window, DOCKED_ALIGNMENT_NONE)) { | 944 if (!CanDockWindow(window, DOCKED_ALIGNMENT_NONE)) { |
| 951 window_state->Restore(); | 945 window_state->Restore(); |
| 952 RecordUmaAction(DOCKED_ACTION_EVICT, event_source_); | 946 RecordUmaAction(DOCKED_ACTION_EVICT, event_source_); |
| 953 return; | 947 return; |
| 954 } | 948 } |
| 955 | 949 |
| 956 // Always place restored window at the bottom shuffling the other windows up. | 950 // Always place restored window at the bottom shuffling the other windows up. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 976 base::Time time_now = base::Time::Now(); | 970 base::Time time_now = base::Time::Now(); |
| 977 base::TimeDelta time_between_use = time_now - last_action_time_; | 971 base::TimeDelta time_between_use = time_now - last_action_time_; |
| 978 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.Dock.TimeBetweenUse", | 972 UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.Dock.TimeBetweenUse", |
| 979 time_between_use.InSeconds(), 1, | 973 time_between_use.InSeconds(), 1, |
| 980 base::TimeDelta::FromHours(10).InSeconds(), 100); | 974 base::TimeDelta::FromHours(10).InSeconds(), 100); |
| 981 last_action_time_ = time_now; | 975 last_action_time_ = time_now; |
| 982 int docked_all_count = 0; | 976 int docked_all_count = 0; |
| 983 int docked_visible_count = 0; | 977 int docked_visible_count = 0; |
| 984 int docked_panels_count = 0; | 978 int docked_panels_count = 0; |
| 985 int large_windows_count = 0; | 979 int large_windows_count = 0; |
| 986 for (wm::WmWindow* window : dock_container_->GetChildren()) { | 980 for (WmWindow* window : dock_container_->GetChildren()) { |
| 987 if (IsPopupOrTransient(window)) | 981 if (IsPopupOrTransient(window)) |
| 988 continue; | 982 continue; |
| 989 docked_all_count++; | 983 docked_all_count++; |
| 990 if (!IsWindowDocked(window)) | 984 if (!IsWindowDocked(window)) |
| 991 continue; | 985 continue; |
| 992 docked_visible_count++; | 986 docked_visible_count++; |
| 993 if (window->GetType() == ui::wm::WINDOW_TYPE_PANEL) | 987 if (window->GetType() == ui::wm::WINDOW_TYPE_PANEL) |
| 994 docked_panels_count++; | 988 docked_panels_count++; |
| 995 const wm::WindowState* window_state = window->GetWindowState(); | 989 const wm::WindowState* window_state = window->GetWindowState(); |
| 996 if (window_state->HasRestoreBounds()) { | 990 if (window_state->HasRestoreBounds()) { |
| 997 const gfx::Rect restore_bounds = window_state->GetRestoreBoundsInScreen(); | 991 const gfx::Rect restore_bounds = window_state->GetRestoreBoundsInScreen(); |
| 998 if (restore_bounds.width() > kMaxDockWidth) | 992 if (restore_bounds.width() > kMaxDockWidth) |
| 999 large_windows_count++; | 993 large_windows_count++; |
| 1000 } | 994 } |
| 1001 } | 995 } |
| 1002 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsAll", docked_all_count); | 996 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsAll", docked_all_count); |
| 1003 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsLarge", large_windows_count); | 997 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsLarge", large_windows_count); |
| 1004 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsPanels", docked_panels_count); | 998 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsPanels", docked_panels_count); |
| 1005 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsVisible", docked_visible_count); | 999 UMA_HISTOGRAM_COUNTS_100("Ash.Dock.ItemsVisible", docked_visible_count); |
| 1006 } | 1000 } |
| 1007 | 1001 |
| 1008 void DockedWindowLayoutManager::UpdateDockedWidth(int width) { | 1002 void DockedWindowLayoutManager::UpdateDockedWidth(int width) { |
| 1009 if (docked_width_ == width) | 1003 if (docked_width_ == width) |
| 1010 return; | 1004 return; |
| 1011 docked_width_ = width; | 1005 docked_width_ = width; |
| 1012 UMA_HISTOGRAM_COUNTS_10000("Ash.Dock.Width", docked_width_); | 1006 UMA_HISTOGRAM_COUNTS_10000("Ash.Dock.Width", docked_width_); |
| 1013 } | 1007 } |
| 1014 | 1008 |
| 1015 void DockedWindowLayoutManager::OnDraggedWindowDocked(wm::WmWindow* window) { | 1009 void DockedWindowLayoutManager::OnDraggedWindowDocked(WmWindow* window) { |
| 1016 DCHECK(!is_dragged_window_docked_); | 1010 DCHECK(!is_dragged_window_docked_); |
| 1017 is_dragged_window_docked_ = true; | 1011 is_dragged_window_docked_ = true; |
| 1018 } | 1012 } |
| 1019 | 1013 |
| 1020 void DockedWindowLayoutManager::OnDraggedWindowUndocked() { | 1014 void DockedWindowLayoutManager::OnDraggedWindowUndocked() { |
| 1021 DCHECK(is_dragged_window_docked_); | 1015 DCHECK(is_dragged_window_docked_); |
| 1022 is_dragged_window_docked_ = false; | 1016 is_dragged_window_docked_ = false; |
| 1023 } | 1017 } |
| 1024 | 1018 |
| 1025 bool DockedWindowLayoutManager::IsAnyWindowDocked() { | 1019 bool DockedWindowLayoutManager::IsAnyWindowDocked() { |
| 1026 return CalculateAlignment() != DOCKED_ALIGNMENT_NONE; | 1020 return CalculateAlignment() != DOCKED_ALIGNMENT_NONE; |
| 1027 } | 1021 } |
| 1028 | 1022 |
| 1029 DockedAlignment DockedWindowLayoutManager::GetEdgeNearestWindow( | 1023 DockedAlignment DockedWindowLayoutManager::GetEdgeNearestWindow( |
| 1030 const wm::WmWindow* window) const { | 1024 const WmWindow* window) const { |
| 1031 const gfx::Rect bounds(window->GetBoundsInScreen()); | 1025 const gfx::Rect bounds(window->GetBoundsInScreen()); |
| 1032 const gfx::Rect container_bounds = dock_container_->GetBoundsInScreen(); | 1026 const gfx::Rect container_bounds = dock_container_->GetBoundsInScreen(); |
| 1033 // Give one pixel preference for docking on the right side to a window that | 1027 // Give one pixel preference for docking on the right side to a window that |
| 1034 // has odd width and is centered in a screen that has even width (or vice | 1028 // has odd width and is centered in a screen that has even width (or vice |
| 1035 // versa). This only matters to the tests but could be a source of flakiness. | 1029 // versa). This only matters to the tests but could be a source of flakiness. |
| 1036 return (abs(bounds.x() - container_bounds.x()) + 1 < | 1030 return (abs(bounds.x() - container_bounds.x()) + 1 < |
| 1037 abs(bounds.right() - container_bounds.right())) | 1031 abs(bounds.right() - container_bounds.right())) |
| 1038 ? DOCKED_ALIGNMENT_LEFT | 1032 ? DOCKED_ALIGNMENT_LEFT |
| 1039 : DOCKED_ALIGNMENT_RIGHT; | 1033 : DOCKED_ALIGNMENT_RIGHT; |
| 1040 } | 1034 } |
| 1041 | 1035 |
| 1042 void DockedWindowLayoutManager::Relayout() { | 1036 void DockedWindowLayoutManager::Relayout() { |
| 1043 if (in_layout_) | 1037 if (in_layout_) |
| 1044 return; | 1038 return; |
| 1045 if (alignment_ == DOCKED_ALIGNMENT_NONE && !is_dragged_window_docked_) | 1039 if (alignment_ == DOCKED_ALIGNMENT_NONE && !is_dragged_window_docked_) |
| 1046 return; | 1040 return; |
| 1047 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); | 1041 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); |
| 1048 | 1042 |
| 1049 gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen(); | 1043 gfx::Rect dock_bounds = dock_container_->GetBoundsInScreen(); |
| 1050 wm::WmWindow* active_window = nullptr; | 1044 WmWindow* active_window = nullptr; |
| 1051 std::vector<WindowWithHeight> visible_windows; | 1045 std::vector<WindowWithHeight> visible_windows; |
| 1052 for (wm::WmWindow* window : dock_container_->GetChildren()) { | 1046 for (WmWindow* window : dock_container_->GetChildren()) { |
| 1053 if (!IsWindowDocked(window) || window == dragged_window_) | 1047 if (!IsWindowDocked(window) || window == dragged_window_) |
| 1054 continue; | 1048 continue; |
| 1055 | 1049 |
| 1056 // If the shelf is currently hidden (full-screen mode), hide window until | 1050 // If the shelf is currently hidden (full-screen mode), hide window until |
| 1057 // full-screen mode is exited. | 1051 // full-screen mode is exited. |
| 1058 if (in_fullscreen_) { | 1052 if (in_fullscreen_) { |
| 1059 // The call to Hide does not set the minimize property, so the window will | 1053 // The call to Hide does not set the minimize property, so the window will |
| 1060 // be restored when the shelf becomes visible again. | 1054 // be restored when the shelf becomes visible again. |
| 1061 window->Hide(); | 1055 window->Hide(); |
| 1062 continue; | 1056 continue; |
| 1063 } | 1057 } |
| 1064 if (window->IsFocused() || | 1058 if (window->IsFocused() || |
| 1065 window->Contains(window->GetGlobals()->GetFocusedWindow())) { | 1059 window->Contains(window->GetShell()->GetFocusedWindow())) { |
| 1066 DCHECK(!active_window); | 1060 DCHECK(!active_window); |
| 1067 active_window = window; | 1061 active_window = window; |
| 1068 } | 1062 } |
| 1069 visible_windows.push_back(WindowWithHeight(window)); | 1063 visible_windows.push_back(WindowWithHeight(window)); |
| 1070 } | 1064 } |
| 1071 // Consider docked dragged_window_ when fanning out other child windows. | 1065 // Consider docked dragged_window_ when fanning out other child windows. |
| 1072 if (is_dragged_window_docked_) { | 1066 if (is_dragged_window_docked_) { |
| 1073 visible_windows.push_back(WindowWithHeight(dragged_window_)); | 1067 visible_windows.push_back(WindowWithHeight(dragged_window_)); |
| 1074 DCHECK(!active_window); | 1068 DCHECK(!active_window); |
| 1075 active_window = dragged_window_; | 1069 active_window = dragged_window_; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1121 const std::vector<WindowWithHeight>& visible_windows) { | 1115 const std::vector<WindowWithHeight>& visible_windows) { |
| 1122 int smallest_max_width = kMaxDockWidth; | 1116 int smallest_max_width = kMaxDockWidth; |
| 1123 int largest_min_width = kMinDockWidth; | 1117 int largest_min_width = kMinDockWidth; |
| 1124 // Ideal width of the docked area is as close to kIdealWidth as possible | 1118 // Ideal width of the docked area is as close to kIdealWidth as possible |
| 1125 // while still respecting the minimum and maximum width restrictions on the | 1119 // while still respecting the minimum and maximum width restrictions on the |
| 1126 // individual docked windows as well as the width that was possibly set by a | 1120 // individual docked windows as well as the width that was possibly set by a |
| 1127 // user (which needs to be preserved when dragging and rearranging windows). | 1121 // user (which needs to be preserved when dragging and rearranging windows). |
| 1128 for (std::vector<WindowWithHeight>::const_iterator iter = | 1122 for (std::vector<WindowWithHeight>::const_iterator iter = |
| 1129 visible_windows.begin(); | 1123 visible_windows.begin(); |
| 1130 iter != visible_windows.end(); ++iter) { | 1124 iter != visible_windows.end(); ++iter) { |
| 1131 const wm::WmWindow* window = iter->window; | 1125 const WmWindow* window = iter->window; |
| 1132 int min_window_width = window->GetBounds().width(); | 1126 int min_window_width = window->GetBounds().width(); |
| 1133 int max_window_width = min_window_width; | 1127 int max_window_width = min_window_width; |
| 1134 if (!window->GetWindowState()->bounds_changed_by_user()) { | 1128 if (!window->GetWindowState()->bounds_changed_by_user()) { |
| 1135 min_window_width = GetWindowWidthCloseTo(window, kMinDockWidth); | 1129 min_window_width = GetWindowWidthCloseTo(window, kMinDockWidth); |
| 1136 max_window_width = GetWindowWidthCloseTo(window, kMaxDockWidth); | 1130 max_window_width = GetWindowWidthCloseTo(window, kMaxDockWidth); |
| 1137 } | 1131 } |
| 1138 largest_min_width = std::max(largest_min_width, min_window_width); | 1132 largest_min_width = std::max(largest_min_width, min_window_width); |
| 1139 smallest_max_width = std::min(smallest_max_width, max_window_width); | 1133 smallest_max_width = std::min(smallest_max_width, max_window_width); |
| 1140 } | 1134 } |
| 1141 int ideal_width = | 1135 int ideal_width = |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1169 new_width = 0; | 1163 new_width = 0; |
| 1170 } | 1164 } |
| 1171 UpdateDockedWidth(new_width); | 1165 UpdateDockedWidth(new_width); |
| 1172 // Sort windows by their center positions and fan out overlapping | 1166 // Sort windows by their center positions and fan out overlapping |
| 1173 // windows. | 1167 // windows. |
| 1174 std::sort(visible_windows->begin(), visible_windows->end(), | 1168 std::sort(visible_windows->begin(), visible_windows->end(), |
| 1175 CompareWindowPos(is_dragged_from_dock_ ? dragged_window_ : nullptr, | 1169 CompareWindowPos(is_dragged_from_dock_ ? dragged_window_ : nullptr, |
| 1176 dock_container_, delta)); | 1170 dock_container_, delta)); |
| 1177 for (std::vector<WindowWithHeight>::iterator iter = visible_windows->begin(); | 1171 for (std::vector<WindowWithHeight>::iterator iter = visible_windows->begin(); |
| 1178 iter != visible_windows->end(); ++iter) { | 1172 iter != visible_windows->end(); ++iter) { |
| 1179 wm::WmWindow* window = iter->window; | 1173 WmWindow* window = iter->window; |
| 1180 gfx::Rect bounds = | 1174 gfx::Rect bounds = |
| 1181 dock_container_->ConvertRectToScreen(window->GetTargetBounds()); | 1175 dock_container_->ConvertRectToScreen(window->GetTargetBounds()); |
| 1182 // A window is extended or shrunk to be as close as possible to the ideal | 1176 // A window is extended or shrunk to be as close as possible to the ideal |
| 1183 // docked area width. Windows that were resized by a user are kept at their | 1177 // docked area width. Windows that were resized by a user are kept at their |
| 1184 // existing size. | 1178 // existing size. |
| 1185 // This also enforces the min / max restrictions on the docked area width. | 1179 // This also enforces the min / max restrictions on the docked area width. |
| 1186 bounds.set_width(GetWindowWidthCloseTo( | 1180 bounds.set_width(GetWindowWidthCloseTo( |
| 1187 window, window->GetWindowState()->bounds_changed_by_user() | 1181 window, window->GetWindowState()->bounds_changed_by_user() |
| 1188 ? bounds.width() | 1182 ? bounds.width() |
| 1189 : ideal_docked_width)); | 1183 : ideal_docked_width)); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1255 if (docked_width_ > 0) { | 1249 if (docked_width_ > 0) { |
| 1256 if (!background_widget_) | 1250 if (!background_widget_) |
| 1257 background_widget_.reset(new DockedBackgroundWidget(this)); | 1251 background_widget_.reset(new DockedBackgroundWidget(this)); |
| 1258 background_widget_->SetBackgroundBounds(background_bounds, alignment_); | 1252 background_widget_->SetBackgroundBounds(background_bounds, alignment_); |
| 1259 background_widget_->Show(); | 1253 background_widget_->Show(); |
| 1260 } else if (background_widget_) { | 1254 } else if (background_widget_) { |
| 1261 background_widget_->Hide(); | 1255 background_widget_->Hide(); |
| 1262 } | 1256 } |
| 1263 } | 1257 } |
| 1264 | 1258 |
| 1265 void DockedWindowLayoutManager::UpdateStacking(wm::WmWindow* active_window) { | 1259 void DockedWindowLayoutManager::UpdateStacking(WmWindow* active_window) { |
| 1266 if (!active_window) { | 1260 if (!active_window) { |
| 1267 if (!last_active_window_) | 1261 if (!last_active_window_) |
| 1268 return; | 1262 return; |
| 1269 active_window = last_active_window_; | 1263 active_window = last_active_window_; |
| 1270 } | 1264 } |
| 1271 | 1265 |
| 1272 // Windows are stacked like a deck of cards: | 1266 // Windows are stacked like a deck of cards: |
| 1273 // ,------. | 1267 // ,------. |
| 1274 // |,------.| | 1268 // |,------.| |
| 1275 // |,------.| | 1269 // |,------.| |
| 1276 // | active | | 1270 // | active | |
| 1277 // | window | | 1271 // | window | |
| 1278 // |`------'| | 1272 // |`------'| |
| 1279 // |`------'| | 1273 // |`------'| |
| 1280 // `------' | 1274 // `------' |
| 1281 // Use the middle of each window to figure out how to stack the window. | 1275 // Use the middle of each window to figure out how to stack the window. |
| 1282 // This allows us to update the stacking when a window is being dragged around | 1276 // This allows us to update the stacking when a window is being dragged around |
| 1283 // by the titlebar. | 1277 // by the titlebar. |
| 1284 std::map<int, wm::WmWindow*> window_ordering; | 1278 std::map<int, WmWindow*> window_ordering; |
| 1285 for (wm::WmWindow* child : dock_container_->GetChildren()) { | 1279 for (WmWindow* child : dock_container_->GetChildren()) { |
| 1286 if (!IsWindowDocked(child) || | 1280 if (!IsWindowDocked(child) || |
| 1287 (child == dragged_window_ && !is_dragged_window_docked_)) { | 1281 (child == dragged_window_ && !is_dragged_window_docked_)) { |
| 1288 continue; | 1282 continue; |
| 1289 } | 1283 } |
| 1290 gfx::Rect bounds = child->GetBounds(); | 1284 gfx::Rect bounds = child->GetBounds(); |
| 1291 window_ordering.insert( | 1285 window_ordering.insert( |
| 1292 std::make_pair(bounds.y() + bounds.height() / 2, child)); | 1286 std::make_pair(bounds.y() + bounds.height() / 2, child)); |
| 1293 } | 1287 } |
| 1294 int active_center_y = active_window->GetBounds().CenterPoint().y(); | 1288 int active_center_y = active_window->GetBounds().CenterPoint().y(); |
| 1295 | 1289 |
| 1296 wm::WmWindow* previous_window = nullptr; | 1290 WmWindow* previous_window = nullptr; |
| 1297 for (std::map<int, wm::WmWindow*>::const_iterator it = | 1291 for (std::map<int, WmWindow*>::const_iterator it = window_ordering.begin(); |
| 1298 window_ordering.begin(); | |
| 1299 it != window_ordering.end() && it->first < active_center_y; ++it) { | 1292 it != window_ordering.end() && it->first < active_center_y; ++it) { |
| 1300 if (previous_window) | 1293 if (previous_window) |
| 1301 dock_container_->StackChildAbove(it->second, previous_window); | 1294 dock_container_->StackChildAbove(it->second, previous_window); |
| 1302 previous_window = it->second; | 1295 previous_window = it->second; |
| 1303 } | 1296 } |
| 1304 for (std::map<int, wm::WmWindow*>::const_reverse_iterator it = | 1297 for (std::map<int, WmWindow*>::const_reverse_iterator it = |
| 1305 window_ordering.rbegin(); | 1298 window_ordering.rbegin(); |
| 1306 it != window_ordering.rend() && it->first > active_center_y; ++it) { | 1299 it != window_ordering.rend() && it->first > active_center_y; ++it) { |
| 1307 if (previous_window) | 1300 if (previous_window) |
| 1308 dock_container_->StackChildAbove(it->second, previous_window); | 1301 dock_container_->StackChildAbove(it->second, previous_window); |
| 1309 previous_window = it->second; | 1302 previous_window = it->second; |
| 1310 } | 1303 } |
| 1311 | 1304 |
| 1312 if (previous_window && active_window->GetParent() == dock_container_) | 1305 if (previous_window && active_window->GetParent() == dock_container_) |
| 1313 dock_container_->StackChildAbove(active_window, previous_window); | 1306 dock_container_->StackChildAbove(active_window, previous_window); |
| 1314 if (active_window != dragged_window_) | 1307 if (active_window != dragged_window_) |
| 1315 last_active_window_ = active_window; | 1308 last_active_window_ = active_window; |
| 1316 } | 1309 } |
| 1317 | 1310 |
| 1318 //////////////////////////////////////////////////////////////////////////////// | 1311 //////////////////////////////////////////////////////////////////////////////// |
| 1319 // keyboard::KeyboardControllerObserver implementation: | 1312 // keyboard::KeyboardControllerObserver implementation: |
| 1320 | 1313 |
| 1321 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( | 1314 void DockedWindowLayoutManager::OnKeyboardBoundsChanging( |
| 1322 const gfx::Rect& keyboard_bounds) { | 1315 const gfx::Rect& keyboard_bounds) { |
| 1323 // This bounds change will have caused a change to the Shelf which does not | 1316 // This bounds change will have caused a change to the Shelf which does not |
| 1324 // propagate automatically to this class, so manually recalculate bounds. | 1317 // propagate automatically to this class, so manually recalculate bounds. |
| 1325 Relayout(); | 1318 Relayout(); |
| 1326 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); | 1319 UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); |
| 1327 } | 1320 } |
| 1328 | 1321 |
| 1329 } // namespace ash | 1322 } // namespace ash |
| OLD | NEW |