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 |