OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/wm/workspace/workspace_window_resizer.h" | 5 #include "ash/wm/workspace/workspace_window_resizer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 // classes using reparenting during drag operations it becomes challenging to | 60 // classes using reparenting during drag operations it becomes challenging to |
61 // implement proper transition from one resizer to another during or at the | 61 // implement proper transition from one resizer to another during or at the |
62 // end of the drag. This also causes http://crbug.com/247085. | 62 // end of the drag. This also causes http://crbug.com/247085. |
63 // It seems the only thing the panel or dock resizer needs to do is notify the | 63 // It seems the only thing the panel or dock resizer needs to do is notify the |
64 // layout manager when a docked window is being dragged. We should have a | 64 // layout manager when a docked window is being dragged. We should have a |
65 // better way of doing this, perhaps by having a way of observing drags or | 65 // better way of doing this, perhaps by having a way of observing drags or |
66 // having a generic drag window wrapper which informs a layout manager that a | 66 // having a generic drag window wrapper which informs a layout manager that a |
67 // drag has started or stopped. | 67 // drag has started or stopped. |
68 // It may be possible to refactor and eliminate chaining. | 68 // It may be possible to refactor and eliminate chaining. |
69 WindowResizer* window_resizer = NULL; | 69 WindowResizer* window_resizer = NULL; |
| 70 |
| 71 if (!window_state->IsNormalShowState()) { |
| 72 if (window->parent() && |
| 73 (window->parent()->id() == internal::kShellWindowId_DefaultContainer || |
| 74 window->parent()->id() == internal::kShellWindowId_DockedContainer || |
| 75 window->parent()->id() == internal::kShellWindowId_PanelContainer)) { |
| 76 // Allow dragging maximized windows only when dragged by a tab. |
| 77 if (window_component != HTCAPTION || !window_state->is_dragged()) |
| 78 return scoped_ptr<WindowResizer>(); |
| 79 } else { |
| 80 return scoped_ptr<WindowResizer>(); |
| 81 } |
| 82 } |
| 83 |
| 84 if (!window_state->CreateDragDetails( |
| 85 window, point_in_parent, window_component, source)) { |
| 86 return scoped_ptr<WindowResizer>(); |
| 87 } |
70 if (window->parent() && | 88 if (window->parent() && |
71 (window->parent()->id() == internal::kShellWindowId_DefaultContainer || | 89 (window->parent()->id() == internal::kShellWindowId_DefaultContainer || |
72 window->parent()->id() == internal::kShellWindowId_DockedContainer || | 90 window->parent()->id() == internal::kShellWindowId_DockedContainer || |
73 window->parent()->id() == internal::kShellWindowId_PanelContainer)) { | 91 window->parent()->id() == internal::kShellWindowId_PanelContainer)) { |
74 // Allow dragging maximized windows if it's not tracked by workspace. This | |
75 // is set by tab dragging code. | |
76 if (!window_state->IsNormalShowState() && | |
77 (window_component != HTCAPTION || | |
78 !window_state->is_dragged())) { | |
79 return scoped_ptr<WindowResizer>(); | |
80 } | |
81 window_resizer = internal::WorkspaceWindowResizer::Create( | 92 window_resizer = internal::WorkspaceWindowResizer::Create( |
82 window, | 93 window_state, |
83 point_in_parent, | |
84 window_component, | |
85 source, | |
86 std::vector<aura::Window*>()); | 94 std::vector<aura::Window*>()); |
87 } else if (window_state->IsNormalShowState()) { | 95 } else { |
88 window_resizer = DefaultWindowResizer::Create( | 96 window_resizer = DefaultWindowResizer::Create(window_state); |
89 window, point_in_parent, window_component, source); | |
90 } | 97 } |
91 if (window_resizer) { | 98 if (window_resizer) { |
92 window_resizer = internal::DragWindowResizer::Create( | 99 window_resizer = internal::DragWindowResizer::Create(window_resizer, |
93 window_resizer, window, point_in_parent, window_component, source); | 100 window_state); |
94 } | 101 } |
95 if (window_resizer && window->type() == ui::wm::WINDOW_TYPE_PANEL) { | 102 if (window_resizer && window->type() == ui::wm::WINDOW_TYPE_PANEL) |
96 window_resizer = PanelWindowResizer::Create( | 103 window_resizer = PanelWindowResizer::Create(window_resizer, window_state); |
97 window_resizer, window, point_in_parent, window_component, source); | |
98 } | |
99 if (switches::UseDockedWindows() && | 104 if (switches::UseDockedWindows() && |
100 window_resizer && window->parent() && | 105 window_resizer && window->parent() && |
101 !views::corewm::GetTransientParent(window) && | 106 !views::corewm::GetTransientParent(window) && |
102 (window->parent()->id() == internal::kShellWindowId_DefaultContainer || | 107 (window->parent()->id() == internal::kShellWindowId_DefaultContainer || |
103 window->parent()->id() == internal::kShellWindowId_DockedContainer || | 108 window->parent()->id() == internal::kShellWindowId_DockedContainer || |
104 window->parent()->id() == internal::kShellWindowId_PanelContainer)) { | 109 window->parent()->id() == internal::kShellWindowId_PanelContainer)) { |
105 window_resizer = internal::DockedWindowResizer::Create( | 110 window_resizer = internal::DockedWindowResizer::Create(window_resizer, |
106 window_resizer, window, point_in_parent, window_component, source); | 111 window_state); |
107 } | 112 } |
108 window_state->set_window_resizer_(window_resizer); | 113 window_state->drag_details()->window_resizer = window_resizer; |
109 return make_scoped_ptr<WindowResizer>(window_resizer); | 114 return make_scoped_ptr<WindowResizer>(window_resizer); |
110 } | 115 } |
111 | 116 |
112 namespace internal { | 117 namespace internal { |
113 | 118 |
114 namespace { | 119 namespace { |
115 | 120 |
116 // Snapping distance used instead of WorkspaceWindowResizer::kScreenEdgeInset | 121 // Snapping distance used instead of WorkspaceWindowResizer::kScreenEdgeInset |
117 // when resizing a window using touchscreen. | 122 // when resizing a window using touchscreen. |
118 const int kScreenEdgeInsetForTouchResize = 32; | 123 const int kScreenEdgeInsetForTouchResize = 32; |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 if (did_lock_cursor_) { | 353 if (did_lock_cursor_) { |
349 Shell* shell = Shell::GetInstance(); | 354 Shell* shell = Shell::GetInstance(); |
350 shell->cursor_manager()->UnlockCursor(); | 355 shell->cursor_manager()->UnlockCursor(); |
351 } | 356 } |
352 if (instance_ == this) | 357 if (instance_ == this) |
353 instance_ = NULL; | 358 instance_ = NULL; |
354 } | 359 } |
355 | 360 |
356 // static | 361 // static |
357 WorkspaceWindowResizer* WorkspaceWindowResizer::Create( | 362 WorkspaceWindowResizer* WorkspaceWindowResizer::Create( |
358 aura::Window* window, | 363 wm::WindowState* window_state, |
359 const gfx::Point& location_in_parent, | |
360 int window_component, | |
361 aura::client::WindowMoveSource source, | |
362 const std::vector<aura::Window*>& attached_windows) { | 364 const std::vector<aura::Window*>& attached_windows) { |
363 Details details(window, location_in_parent, window_component, source); | 365 return new WorkspaceWindowResizer(window_state, attached_windows); |
364 return details.is_resizable ? | |
365 new WorkspaceWindowResizer(details, attached_windows) : NULL; | |
366 } | 366 } |
367 | 367 |
368 void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_parent, | 368 void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_parent, |
369 int event_flags) { | 369 int event_flags) { |
370 last_mouse_location_ = location_in_parent; | 370 last_mouse_location_ = location_in_parent; |
371 | 371 |
372 int sticky_size; | 372 int sticky_size; |
373 if (event_flags & ui::EF_CONTROL_DOWN) { | 373 if (event_flags & ui::EF_CONTROL_DOWN) { |
374 sticky_size = 0; | 374 sticky_size = 0; |
375 } else if (CommandLine::ForCurrentProcess()->HasSwitch( | 375 } else if (CommandLine::ForCurrentProcess()->HasSwitch( |
376 switches::kAshEnableStickyEdges)) { | 376 switches::kAshEnableStickyEdges)) { |
377 sticky_size = kStickyDistancePixels; | 377 sticky_size = kStickyDistancePixels; |
378 } else if ((details_.bounds_change & kBoundsChange_Resizes) && | 378 } else if ((details().bounds_change & kBoundsChange_Resizes) && |
379 details_.source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) { | 379 details().source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) { |
380 sticky_size = kScreenEdgeInsetForTouchResize; | 380 sticky_size = kScreenEdgeInsetForTouchResize; |
381 } else { | 381 } else { |
382 sticky_size = kScreenEdgeInset; | 382 sticky_size = kScreenEdgeInset; |
383 } | 383 } |
384 // |bounds| is in |window()->parent()|'s coordinates. | 384 // |bounds| is in |GetTarget()->parent()|'s coordinates. |
385 gfx::Rect bounds = CalculateBoundsForDrag(details_, location_in_parent); | 385 gfx::Rect bounds = CalculateBoundsForDrag(location_in_parent); |
386 if (window_state()->IsNormalShowState()) | 386 if (window_state()->IsNormalShowState()) |
387 AdjustBoundsForMainWindow(sticky_size, &bounds); | 387 AdjustBoundsForMainWindow(sticky_size, &bounds); |
388 | 388 |
389 if (bounds != window()->bounds()) { | 389 if (bounds != GetTarget()->bounds()) { |
390 if (!did_move_or_resize_) { | 390 if (!did_move_or_resize_) { |
391 if (!details_.restore_bounds.IsEmpty()) | 391 if (!details().restore_bounds.IsEmpty()) |
392 window_state()->ClearRestoreBounds(); | 392 window_state()->ClearRestoreBounds(); |
393 RestackWindows(); | 393 RestackWindows(); |
394 } | 394 } |
395 did_move_or_resize_ = true; | 395 did_move_or_resize_ = true; |
396 } | 396 } |
397 | 397 |
398 gfx::Point location_in_screen = location_in_parent; | 398 gfx::Point location_in_screen = location_in_parent; |
399 wm::ConvertPointToScreen(window()->parent(), &location_in_screen); | 399 wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen); |
400 | 400 |
401 aura::Window* root = NULL; | 401 aura::Window* root = NULL; |
402 gfx::Display display = | 402 gfx::Display display = |
403 ScreenAsh::FindDisplayContainingPoint(location_in_screen); | 403 ScreenAsh::FindDisplayContainingPoint(location_in_screen); |
404 // Track the last screen that the pointer was on to keep the snap phantom | 404 // Track the last screen that the pointer was on to keep the snap phantom |
405 // window there. | 405 // window there. |
406 if (display.is_valid()) { | 406 if (display.is_valid()) { |
407 root = Shell::GetInstance()->display_controller()-> | 407 root = Shell::GetInstance()->display_controller()-> |
408 GetRootWindowForDisplayId(display.id()); | 408 GetRootWindowForDisplayId(display.id()); |
409 } | 409 } |
410 if (!attached_windows_.empty()) | 410 if (!attached_windows_.empty()) |
411 LayoutAttachedWindows(&bounds); | 411 LayoutAttachedWindows(&bounds); |
412 if (bounds != window()->bounds()) { | 412 if (bounds != GetTarget()->bounds()) { |
413 // SetBounds needs to be called to update the layout which affects where the | 413 // SetBounds needs to be called to update the layout which affects where the |
414 // phantom window is drawn. Keep track if the window was destroyed during | 414 // phantom window is drawn. Keep track if the window was destroyed during |
415 // the drag and quit early if so. | 415 // the drag and quit early if so. |
416 base::WeakPtr<WorkspaceWindowResizer> resizer( | 416 base::WeakPtr<WorkspaceWindowResizer> resizer( |
417 weak_ptr_factory_.GetWeakPtr()); | 417 weak_ptr_factory_.GetWeakPtr()); |
418 window()->SetBounds(bounds); | 418 GetTarget()->SetBounds(bounds); |
419 if (!resizer) | 419 if (!resizer) |
420 return; | 420 return; |
421 } | 421 } |
422 const bool in_original_root = !root || root == window()->GetRootWindow(); | 422 const bool in_original_root = !root || root == GetTarget()->GetRootWindow(); |
423 // Hide a phantom window for snapping if the cursor is in another root window. | 423 // Hide a phantom window for snapping if the cursor is in another root window. |
424 if (in_original_root) { | 424 if (in_original_root) { |
425 UpdateSnapPhantomWindow(location_in_parent, bounds); | 425 UpdateSnapPhantomWindow(location_in_parent, bounds); |
426 } else { | 426 } else { |
427 snap_type_ = SNAP_NONE; | 427 snap_type_ = SNAP_NONE; |
428 snap_phantom_window_controller_.reset(); | 428 snap_phantom_window_controller_.reset(); |
429 snap_sizer_.reset(); | 429 snap_sizer_.reset(); |
430 SetDraggedWindowDocked(false); | 430 SetDraggedWindowDocked(false); |
431 } | 431 } |
432 } | 432 } |
433 | 433 |
434 void WorkspaceWindowResizer::CompleteDrag() { | 434 void WorkspaceWindowResizer::CompleteDrag() { |
435 window_state()->set_bounds_changed_by_user(true); | 435 window_state()->set_bounds_changed_by_user(true); |
436 snap_phantom_window_controller_.reset(); | 436 snap_phantom_window_controller_.reset(); |
437 if (!did_move_or_resize_ || details_.window_component != HTCAPTION) | 437 if (!did_move_or_resize_ || details().window_component != HTCAPTION) |
438 return; | 438 return; |
439 | 439 |
440 bool snapped = false; | 440 bool snapped = false; |
441 // When the window is not in the normal show state, we do not snap the window. | 441 // When the window is not in the normal show state, we do not snap the window. |
442 // This happens when the user minimizes or maximizes the window by keyboard | 442 // This happens when the user minimizes or maximizes the window by keyboard |
443 // shortcut while dragging it. If the window is the result of dragging a tab | 443 // shortcut while dragging it. If the window is the result of dragging a tab |
444 // out of a maximized window, it's already in the normal show state when this | 444 // out of a maximized window, it's already in the normal show state when this |
445 // is called, so it does not matter. | 445 // is called, so it does not matter. |
446 if (window_state()->IsNormalShowState() && | 446 if (window_state()->IsNormalShowState() && |
447 (window()->type() != ui::wm::WINDOW_TYPE_PANEL || | 447 (GetTarget()->type() != ui::wm::WINDOW_TYPE_PANEL || |
448 !window_state()->panel_attached() || | 448 !window_state()->panel_attached() || |
449 dock_layout_->is_dragged_window_docked()) && | 449 dock_layout_->is_dragged_window_docked()) && |
450 (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) { | 450 (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) { |
451 if (!window_state()->HasRestoreBounds()) { | 451 if (!window_state()->HasRestoreBounds()) { |
452 gfx::Rect initial_bounds = ScreenAsh::ConvertRectToScreen( | 452 gfx::Rect initial_bounds = ScreenAsh::ConvertRectToScreen( |
453 window()->parent(), details_.initial_bounds_in_parent); | 453 GetTarget()->parent(), details().initial_bounds_in_parent); |
454 window_state()->SetRestoreBoundsInScreen( | 454 window_state()->SetRestoreBoundsInScreen( |
455 details_.restore_bounds.IsEmpty() ? | 455 details().restore_bounds.IsEmpty() ? |
456 initial_bounds : | 456 initial_bounds : |
457 details_.restore_bounds); | 457 details().restore_bounds); |
458 } | 458 } |
459 DCHECK(snap_sizer_); | 459 DCHECK(snap_sizer_); |
460 if (window_state()->CanResize() && | 460 if (window_state()->CanResize() && |
461 !dock_layout_->is_dragged_window_docked()) { | 461 !dock_layout_->is_dragged_window_docked()) { |
462 snap_sizer_->SnapWindowToTargetBounds(); | 462 snap_sizer_->SnapWindowToTargetBounds(); |
463 snapped = true; | 463 snapped = true; |
464 } | 464 } |
465 } | 465 } |
466 if (window_state()->IsSnapped() && !snapped) | 466 if (window_state()->IsSnapped() && !snapped) |
467 window_state()->Restore(); | 467 window_state()->Restore(); |
468 } | 468 } |
469 | 469 |
470 void WorkspaceWindowResizer::RevertDrag() { | 470 void WorkspaceWindowResizer::RevertDrag() { |
471 window_state()->set_bounds_changed_by_user(initial_bounds_changed_by_user_); | 471 window_state()->set_bounds_changed_by_user(initial_bounds_changed_by_user_); |
472 snap_phantom_window_controller_.reset(); | 472 snap_phantom_window_controller_.reset(); |
473 | 473 |
474 if (!did_move_or_resize_) | 474 if (!did_move_or_resize_) |
475 return; | 475 return; |
476 | 476 |
477 window()->SetBounds(details_.initial_bounds_in_parent); | 477 GetTarget()->SetBounds(details().initial_bounds_in_parent); |
478 if (!details_.restore_bounds.IsEmpty()) { | 478 if (!details().restore_bounds.IsEmpty()) { |
479 window_state()->SetRestoreBoundsInScreen(details_.restore_bounds); | 479 window_state()->SetRestoreBoundsInScreen(details().restore_bounds); |
480 } | 480 } |
481 | 481 |
482 if (details_.window_component == HTRIGHT) { | 482 if (details().window_component == HTRIGHT) { |
483 int last_x = details_.initial_bounds_in_parent.right(); | 483 int last_x = details().initial_bounds_in_parent.right(); |
484 for (size_t i = 0; i < attached_windows_.size(); ++i) { | 484 for (size_t i = 0; i < attached_windows_.size(); ++i) { |
485 gfx::Rect bounds(attached_windows_[i]->bounds()); | 485 gfx::Rect bounds(attached_windows_[i]->bounds()); |
486 bounds.set_x(last_x); | 486 bounds.set_x(last_x); |
487 bounds.set_width(initial_size_[i]); | 487 bounds.set_width(initial_size_[i]); |
488 attached_windows_[i]->SetBounds(bounds); | 488 attached_windows_[i]->SetBounds(bounds); |
489 last_x = attached_windows_[i]->bounds().right(); | 489 last_x = attached_windows_[i]->bounds().right(); |
490 } | 490 } |
491 } else { | 491 } else { |
492 int last_y = details_.initial_bounds_in_parent.bottom(); | 492 int last_y = details().initial_bounds_in_parent.bottom(); |
493 for (size_t i = 0; i < attached_windows_.size(); ++i) { | 493 for (size_t i = 0; i < attached_windows_.size(); ++i) { |
494 gfx::Rect bounds(attached_windows_[i]->bounds()); | 494 gfx::Rect bounds(attached_windows_[i]->bounds()); |
495 bounds.set_y(last_y); | 495 bounds.set_y(last_y); |
496 bounds.set_height(initial_size_[i]); | 496 bounds.set_height(initial_size_[i]); |
497 attached_windows_[i]->SetBounds(bounds); | 497 attached_windows_[i]->SetBounds(bounds); |
498 last_y = attached_windows_[i]->bounds().bottom(); | 498 last_y = attached_windows_[i]->bounds().bottom(); |
499 } | 499 } |
500 } | 500 } |
501 } | 501 } |
502 | 502 |
503 aura::Window* WorkspaceWindowResizer::GetTarget() { | |
504 return details_.window; | |
505 } | |
506 | |
507 const gfx::Point& WorkspaceWindowResizer::GetInitialLocation() const { | |
508 return details_.initial_location_in_parent; | |
509 } | |
510 | |
511 WorkspaceWindowResizer::WorkspaceWindowResizer( | 503 WorkspaceWindowResizer::WorkspaceWindowResizer( |
512 const Details& details, | 504 wm::WindowState* window_state, |
513 const std::vector<aura::Window*>& attached_windows) | 505 const std::vector<aura::Window*>& attached_windows) |
514 : details_(details), | 506 : WindowResizer(window_state), |
515 attached_windows_(attached_windows), | 507 attached_windows_(attached_windows), |
516 did_lock_cursor_(false), | 508 did_lock_cursor_(false), |
517 did_move_or_resize_(false), | 509 did_move_or_resize_(false), |
518 initial_bounds_changed_by_user_( | 510 initial_bounds_changed_by_user_(window_state_->bounds_changed_by_user()), |
519 details.window_state->bounds_changed_by_user()), | |
520 total_min_(0), | 511 total_min_(0), |
521 total_initial_size_(0), | 512 total_initial_size_(0), |
522 snap_type_(SNAP_NONE), | 513 snap_type_(SNAP_NONE), |
523 num_mouse_moves_since_bounds_change_(0), | 514 num_mouse_moves_since_bounds_change_(0), |
524 magnetism_window_(NULL), | 515 magnetism_window_(NULL), |
525 weak_ptr_factory_(this) { | 516 weak_ptr_factory_(this) { |
526 DCHECK(details_.is_resizable); | 517 DCHECK(details().is_resizable); |
527 | 518 |
528 // A mousemove should still show the cursor even if the window is | 519 // A mousemove should still show the cursor even if the window is |
529 // being moved or resized with touch, so do not lock the cursor. | 520 // being moved or resized with touch, so do not lock the cursor. |
530 if (details.source != aura::client::WINDOW_MOVE_SOURCE_TOUCH) { | 521 if (details().source != aura::client::WINDOW_MOVE_SOURCE_TOUCH) { |
531 Shell* shell = Shell::GetInstance(); | 522 Shell* shell = Shell::GetInstance(); |
532 shell->cursor_manager()->LockCursor(); | 523 shell->cursor_manager()->LockCursor(); |
533 did_lock_cursor_ = true; | 524 did_lock_cursor_ = true; |
534 } | 525 } |
535 | 526 |
536 aura::Window* dock_container = Shell::GetContainer( | 527 aura::Window* dock_container = Shell::GetContainer( |
537 window()->GetRootWindow(), kShellWindowId_DockedContainer); | 528 GetTarget()->GetRootWindow(), kShellWindowId_DockedContainer); |
538 dock_layout_ = static_cast<DockedWindowLayoutManager*>( | 529 dock_layout_ = static_cast<DockedWindowLayoutManager*>( |
539 dock_container->layout_manager()); | 530 dock_container->layout_manager()); |
540 | 531 |
541 // Only support attaching to the right/bottom. | 532 // Only support attaching to the right/bottom. |
542 DCHECK(attached_windows_.empty() || | 533 DCHECK(attached_windows_.empty() || |
543 (details.window_component == HTRIGHT || | 534 (details().window_component == HTRIGHT || |
544 details.window_component == HTBOTTOM)); | 535 details().window_component == HTBOTTOM)); |
545 | 536 |
546 // TODO: figure out how to deal with window going off the edge. | 537 // TODO: figure out how to deal with window going off the edge. |
547 | 538 |
548 // Calculate sizes so that we can maintain the ratios if we need to resize. | 539 // Calculate sizes so that we can maintain the ratios if we need to resize. |
549 int total_available = 0; | 540 int total_available = 0; |
550 for (size_t i = 0; i < attached_windows_.size(); ++i) { | 541 for (size_t i = 0; i < attached_windows_.size(); ++i) { |
551 gfx::Size min(attached_windows_[i]->delegate()->GetMinimumSize()); | 542 gfx::Size min(attached_windows_[i]->delegate()->GetMinimumSize()); |
552 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size()); | 543 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size()); |
553 initial_size_.push_back(initial_size); | 544 initial_size_.push_back(initial_size); |
554 // If current size is smaller than the min, use the current size as the min. | 545 // If current size is smaller than the min, use the current size as the min. |
(...skipping 11 matching lines...) Expand all Loading... |
566 const gfx::Rect& bounds) const { | 557 const gfx::Rect& bounds) const { |
567 if (snap_phantom_window_controller_.get() && | 558 if (snap_phantom_window_controller_.get() && |
568 snap_phantom_window_controller_->IsShowing()) { | 559 snap_phantom_window_controller_->IsShowing()) { |
569 return snap_phantom_window_controller_->bounds_in_screen(); | 560 return snap_phantom_window_controller_->bounds_in_screen(); |
570 } | 561 } |
571 return bounds; | 562 return bounds; |
572 } | 563 } |
573 | 564 |
574 void WorkspaceWindowResizer::LayoutAttachedWindows( | 565 void WorkspaceWindowResizer::LayoutAttachedWindows( |
575 gfx::Rect* bounds) { | 566 gfx::Rect* bounds) { |
576 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); | 567 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(GetTarget())); |
577 int initial_size = PrimaryAxisSize(details_.initial_bounds_in_parent.size()); | 568 int initial_size = PrimaryAxisSize(details().initial_bounds_in_parent.size()); |
578 int current_size = PrimaryAxisSize(bounds->size()); | 569 int current_size = PrimaryAxisSize(bounds->size()); |
579 int start = PrimaryAxisCoordinate(bounds->right(), bounds->bottom()); | 570 int start = PrimaryAxisCoordinate(bounds->right(), bounds->bottom()); |
580 int end = PrimaryAxisCoordinate(work_area.right(), work_area.bottom()); | 571 int end = PrimaryAxisCoordinate(work_area.right(), work_area.bottom()); |
581 | 572 |
582 int delta = current_size - initial_size; | 573 int delta = current_size - initial_size; |
583 int available_size = end - start; | 574 int available_size = end - start; |
584 std::vector<int> sizes; | 575 std::vector<int> sizes; |
585 int leftovers = CalculateAttachedSizes(delta, available_size, &sizes); | 576 int leftovers = CalculateAttachedSizes(delta, available_size, &sizes); |
586 | 577 |
587 // leftovers > 0 means that the attached windows can't grow to compensate for | 578 // leftovers > 0 means that the attached windows can't grow to compensate for |
588 // the shrinkage of the main window. This line causes the attached windows to | 579 // the shrinkage of the main window. This line causes the attached windows to |
589 // be moved so they are still flush against the main window, rather than the | 580 // be moved so they are still flush against the main window, rather than the |
590 // main window being prevented from shrinking. | 581 // main window being prevented from shrinking. |
591 leftovers = std::min(0, leftovers); | 582 leftovers = std::min(0, leftovers); |
592 // Reallocate any leftover pixels back into the main window. This is | 583 // Reallocate any leftover pixels back into the main window. This is |
593 // necessary when, for example, the main window shrinks, but none of the | 584 // necessary when, for example, the main window shrinks, but none of the |
594 // attached windows can grow without exceeding their max size constraints. | 585 // attached windows can grow without exceeding their max size constraints. |
595 // Adding the pixels back to the main window effectively prevents the main | 586 // Adding the pixels back to the main window effectively prevents the main |
596 // window from resizing too far. | 587 // window from resizing too far. |
597 if (details_.window_component == HTRIGHT) | 588 if (details().window_component == HTRIGHT) |
598 bounds->set_width(bounds->width() + leftovers); | 589 bounds->set_width(bounds->width() + leftovers); |
599 else | 590 else |
600 bounds->set_height(bounds->height() + leftovers); | 591 bounds->set_height(bounds->height() + leftovers); |
601 | 592 |
602 DCHECK_EQ(attached_windows_.size(), sizes.size()); | 593 DCHECK_EQ(attached_windows_.size(), sizes.size()); |
603 int last = PrimaryAxisCoordinate(bounds->right(), bounds->bottom()); | 594 int last = PrimaryAxisCoordinate(bounds->right(), bounds->bottom()); |
604 for (size_t i = 0; i < attached_windows_.size(); ++i) { | 595 for (size_t i = 0; i < attached_windows_.size(); ++i) { |
605 gfx::Rect attached_bounds(attached_windows_[i]->bounds()); | 596 gfx::Rect attached_bounds(attached_windows_[i]->bounds()); |
606 if (details_.window_component == HTRIGHT) { | 597 if (details().window_component == HTRIGHT) { |
607 attached_bounds.set_x(last); | 598 attached_bounds.set_x(last); |
608 attached_bounds.set_width(sizes[i]); | 599 attached_bounds.set_width(sizes[i]); |
609 } else { | 600 } else { |
610 attached_bounds.set_y(last); | 601 attached_bounds.set_y(last); |
611 attached_bounds.set_height(sizes[i]); | 602 attached_bounds.set_height(sizes[i]); |
612 } | 603 } |
613 attached_windows_[i]->SetBounds(attached_bounds); | 604 attached_windows_[i]->SetBounds(attached_bounds); |
614 last += sizes[i]; | 605 last += sizes[i]; |
615 } | 606 } |
616 } | 607 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 int min = PrimaryAxisSize(delegate->GetMinimumSize()); | 697 int min = PrimaryAxisSize(delegate->GetMinimumSize()); |
707 int max = PrimaryAxisSize(delegate->GetMaximumSize()); | 698 int max = PrimaryAxisSize(delegate->GetMaximumSize()); |
708 | 699 |
709 sizes->push_back(WindowSize(initial_size, min, max)); | 700 sizes->push_back(WindowSize(initial_size, min, max)); |
710 } | 701 } |
711 } | 702 } |
712 | 703 |
713 void WorkspaceWindowResizer::MagneticallySnapToOtherWindows(gfx::Rect* bounds) { | 704 void WorkspaceWindowResizer::MagneticallySnapToOtherWindows(gfx::Rect* bounds) { |
714 if (UpdateMagnetismWindow(*bounds, kAllMagnetismEdges)) { | 705 if (UpdateMagnetismWindow(*bounds, kAllMagnetismEdges)) { |
715 gfx::Point point = OriginForMagneticAttach( | 706 gfx::Point point = OriginForMagneticAttach( |
716 ScreenAsh::ConvertRectToScreen(window()->parent(), *bounds), | 707 ScreenAsh::ConvertRectToScreen(GetTarget()->parent(), *bounds), |
717 magnetism_window_->GetBoundsInScreen(), | 708 magnetism_window_->GetBoundsInScreen(), |
718 magnetism_edge_); | 709 magnetism_edge_); |
719 aura::client::GetScreenPositionClient(window()->GetRootWindow())-> | 710 aura::client::GetScreenPositionClient(GetTarget()->GetRootWindow())-> |
720 ConvertPointFromScreen(window()->parent(), &point); | 711 ConvertPointFromScreen(GetTarget()->parent(), &point); |
721 bounds->set_origin(point); | 712 bounds->set_origin(point); |
722 } | 713 } |
723 } | 714 } |
724 | 715 |
725 void WorkspaceWindowResizer::MagneticallySnapResizeToOtherWindows( | 716 void WorkspaceWindowResizer::MagneticallySnapResizeToOtherWindows( |
726 gfx::Rect* bounds) { | 717 gfx::Rect* bounds) { |
727 const uint32 edges = WindowComponentToMagneticEdge(details_.window_component); | 718 const uint32 edges = WindowComponentToMagneticEdge( |
| 719 details().window_component); |
728 if (UpdateMagnetismWindow(*bounds, edges)) { | 720 if (UpdateMagnetismWindow(*bounds, edges)) { |
729 *bounds = ScreenAsh::ConvertRectFromScreen( | 721 *bounds = ScreenAsh::ConvertRectFromScreen( |
730 window()->parent(), | 722 GetTarget()->parent(), |
731 BoundsForMagneticResizeAttach( | 723 BoundsForMagneticResizeAttach( |
732 ScreenAsh::ConvertRectToScreen(window()->parent(), *bounds), | 724 ScreenAsh::ConvertRectToScreen(GetTarget()->parent(), *bounds), |
733 magnetism_window_->GetBoundsInScreen(), | 725 magnetism_window_->GetBoundsInScreen(), |
734 magnetism_edge_)); | 726 magnetism_edge_)); |
735 } | 727 } |
736 } | 728 } |
737 | 729 |
738 bool WorkspaceWindowResizer::UpdateMagnetismWindow(const gfx::Rect& bounds, | 730 bool WorkspaceWindowResizer::UpdateMagnetismWindow(const gfx::Rect& bounds, |
739 uint32 edges) { | 731 uint32 edges) { |
740 // |bounds| are in coordinates of original window's parent. | 732 // |bounds| are in coordinates of original window's parent. |
741 gfx::Rect bounds_in_screen = | 733 gfx::Rect bounds_in_screen = |
742 ScreenAsh::ConvertRectToScreen(window()->parent(), bounds); | 734 ScreenAsh::ConvertRectToScreen(GetTarget()->parent(), bounds); |
743 MagnetismMatcher matcher(bounds_in_screen, edges); | 735 MagnetismMatcher matcher(bounds_in_screen, edges); |
744 | 736 |
745 // If we snapped to a window then check it first. That way we don't bounce | 737 // If we snapped to a window then check it first. That way we don't bounce |
746 // around when close to multiple edges. | 738 // around when close to multiple edges. |
747 if (magnetism_window_) { | 739 if (magnetism_window_) { |
748 if (window_tracker_.Contains(magnetism_window_) && | 740 if (window_tracker_.Contains(magnetism_window_) && |
749 matcher.ShouldAttach(magnetism_window_->GetBoundsInScreen(), | 741 matcher.ShouldAttach(magnetism_window_->GetBoundsInScreen(), |
750 &magnetism_edge_)) { | 742 &magnetism_edge_)) { |
751 return true; | 743 return true; |
752 } | 744 } |
753 window_tracker_.Remove(magnetism_window_); | 745 window_tracker_.Remove(magnetism_window_); |
754 magnetism_window_ = NULL; | 746 magnetism_window_ = NULL; |
755 } | 747 } |
756 | 748 |
757 // Avoid magnetically snapping windows that are not resizable. | 749 // Avoid magnetically snapping windows that are not resizable. |
758 // TODO(oshima): change this to window.type() == TYPE_NORMAL. | 750 // TODO(oshima): change this to window.type() == TYPE_NORMAL. |
759 if (!window_state()->CanResize()) | 751 if (!window_state()->CanResize()) |
760 return false; | 752 return false; |
761 | 753 |
762 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | 754 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
763 for (aura::Window::Windows::iterator iter = root_windows.begin(); | 755 for (aura::Window::Windows::iterator iter = root_windows.begin(); |
764 iter != root_windows.end(); ++iter) { | 756 iter != root_windows.end(); ++iter) { |
765 const aura::Window* root_window = *iter; | 757 const aura::Window* root_window = *iter; |
766 // Test all children from the desktop in each root window. | 758 // Test all children from the desktop in each root window. |
767 const aura::Window::Windows& children = Shell::GetContainer( | 759 const aura::Window::Windows& children = Shell::GetContainer( |
768 root_window, kShellWindowId_DefaultContainer)->children(); | 760 root_window, kShellWindowId_DefaultContainer)->children(); |
769 for (aura::Window::Windows::const_reverse_iterator i = children.rbegin(); | 761 for (aura::Window::Windows::const_reverse_iterator i = children.rbegin(); |
770 i != children.rend() && !matcher.AreEdgesObscured(); ++i) { | 762 i != children.rend() && !matcher.AreEdgesObscured(); ++i) { |
771 wm::WindowState* other_state = wm::GetWindowState(*i); | 763 wm::WindowState* other_state = wm::GetWindowState(*i); |
772 if (other_state->window() == window() || | 764 if (other_state->window() == GetTarget() || |
773 !other_state->window()->IsVisible() || | 765 !other_state->window()->IsVisible() || |
774 !other_state->IsNormalShowState() || | 766 !other_state->IsNormalShowState() || |
775 !other_state->CanResize()) { | 767 !other_state->CanResize()) { |
776 continue; | 768 continue; |
777 } | 769 } |
778 if (matcher.ShouldAttach( | 770 if (matcher.ShouldAttach( |
779 other_state->window()->GetBoundsInScreen(), &magnetism_edge_)) { | 771 other_state->window()->GetBoundsInScreen(), &magnetism_edge_)) { |
780 magnetism_window_ = other_state->window(); | 772 magnetism_window_ = other_state->window(); |
781 window_tracker_.Add(magnetism_window_); | 773 window_tracker_.Add(magnetism_window_); |
782 return true; | 774 return true; |
783 } | 775 } |
784 } | 776 } |
785 } | 777 } |
786 return false; | 778 return false; |
787 } | 779 } |
788 | 780 |
789 void WorkspaceWindowResizer::AdjustBoundsForMainWindow( | 781 void WorkspaceWindowResizer::AdjustBoundsForMainWindow( |
790 int sticky_size, | 782 int sticky_size, |
791 gfx::Rect* bounds) { | 783 gfx::Rect* bounds) { |
792 gfx::Point last_mouse_location_in_screen = last_mouse_location_; | 784 gfx::Point last_mouse_location_in_screen = last_mouse_location_; |
793 wm::ConvertPointToScreen(window()->parent(), &last_mouse_location_in_screen); | 785 wm::ConvertPointToScreen(GetTarget()->parent(), |
| 786 &last_mouse_location_in_screen); |
794 gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint( | 787 gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint( |
795 last_mouse_location_in_screen); | 788 last_mouse_location_in_screen); |
796 gfx::Rect work_area = | 789 gfx::Rect work_area = |
797 ScreenAsh::ConvertRectFromScreen(window()->parent(), display.work_area()); | 790 ScreenAsh::ConvertRectFromScreen(GetTarget()->parent(), |
798 if (details_.window_component == HTCAPTION) { | 791 display.work_area()); |
| 792 if (details().window_component == HTCAPTION) { |
799 // Adjust the bounds to the work area where the mouse cursor is located. | 793 // Adjust the bounds to the work area where the mouse cursor is located. |
800 // Always keep kMinOnscreenHeight or the window height (whichever is less) | 794 // Always keep kMinOnscreenHeight or the window height (whichever is less) |
801 // on the bottom. | 795 // on the bottom. |
802 int max_y = work_area.bottom() - std::min(kMinOnscreenHeight, | 796 int max_y = work_area.bottom() - std::min(kMinOnscreenHeight, |
803 bounds->height()); | 797 bounds->height()); |
804 if (bounds->y() > max_y) { | 798 if (bounds->y() > max_y) { |
805 bounds->set_y(max_y); | 799 bounds->set_y(max_y); |
806 } else if (bounds->y() <= work_area.y()) { | 800 } else if (bounds->y() <= work_area.y()) { |
807 // Don't allow dragging above the top of the display until the mouse | 801 // Don't allow dragging above the top of the display until the mouse |
808 // cursor reaches the work area above if any. | 802 // cursor reaches the work area above if any. |
(...skipping 10 matching lines...) Expand all Loading... |
819 } | 813 } |
820 } else if (sticky_size > 0) { | 814 } else if (sticky_size > 0) { |
821 MagneticallySnapResizeToOtherWindows(bounds); | 815 MagneticallySnapResizeToOtherWindows(bounds); |
822 if (!magnetism_window_ && sticky_size > 0) | 816 if (!magnetism_window_ && sticky_size > 0) |
823 StickToWorkAreaOnResize(work_area, sticky_size, bounds); | 817 StickToWorkAreaOnResize(work_area, sticky_size, bounds); |
824 } | 818 } |
825 | 819 |
826 if (attached_windows_.empty()) | 820 if (attached_windows_.empty()) |
827 return; | 821 return; |
828 | 822 |
829 if (details_.window_component == HTRIGHT) { | 823 if (details().window_component == HTRIGHT) { |
830 bounds->set_width(std::min(bounds->width(), | 824 bounds->set_width(std::min(bounds->width(), |
831 work_area.right() - total_min_ - bounds->x())); | 825 work_area.right() - total_min_ - bounds->x())); |
832 } else { | 826 } else { |
833 DCHECK_EQ(HTBOTTOM, details_.window_component); | 827 DCHECK_EQ(HTBOTTOM, details().window_component); |
834 bounds->set_height(std::min(bounds->height(), | 828 bounds->set_height(std::min(bounds->height(), |
835 work_area.bottom() - total_min_ - bounds->y())); | 829 work_area.bottom() - total_min_ - bounds->y())); |
836 } | 830 } |
837 } | 831 } |
838 | 832 |
839 bool WorkspaceWindowResizer::StickToWorkAreaOnMove( | 833 bool WorkspaceWindowResizer::StickToWorkAreaOnMove( |
840 const gfx::Rect& work_area, | 834 const gfx::Rect& work_area, |
841 int sticky_size, | 835 int sticky_size, |
842 gfx::Rect* bounds) const { | 836 gfx::Rect* bounds) const { |
843 const int left_edge = work_area.x(); | 837 const int left_edge = work_area.x(); |
(...skipping 19 matching lines...) Expand all Loading... |
863 bounds->set_y(bottom_edge - bounds->height()); | 857 bounds->set_y(bottom_edge - bounds->height()); |
864 updated = true; | 858 updated = true; |
865 } | 859 } |
866 return updated; | 860 return updated; |
867 } | 861 } |
868 | 862 |
869 void WorkspaceWindowResizer::StickToWorkAreaOnResize( | 863 void WorkspaceWindowResizer::StickToWorkAreaOnResize( |
870 const gfx::Rect& work_area, | 864 const gfx::Rect& work_area, |
871 int sticky_size, | 865 int sticky_size, |
872 gfx::Rect* bounds) const { | 866 gfx::Rect* bounds) const { |
873 const uint32 edges = WindowComponentToMagneticEdge(details_.window_component); | 867 const uint32 edges = WindowComponentToMagneticEdge( |
| 868 details().window_component); |
874 const int left_edge = work_area.x(); | 869 const int left_edge = work_area.x(); |
875 const int right_edge = work_area.right(); | 870 const int right_edge = work_area.right(); |
876 const int top_edge = work_area.y(); | 871 const int top_edge = work_area.y(); |
877 const int bottom_edge = work_area.bottom(); | 872 const int bottom_edge = work_area.bottom(); |
878 if (edges & MAGNETISM_EDGE_TOP && | 873 if (edges & MAGNETISM_EDGE_TOP && |
879 ShouldStickToEdge(bounds->y() - top_edge, sticky_size)) { | 874 ShouldStickToEdge(bounds->y() - top_edge, sticky_size)) { |
880 bounds->set_height(bounds->bottom() - top_edge); | 875 bounds->set_height(bounds->bottom() - top_edge); |
881 bounds->set_y(top_edge); | 876 bounds->set_y(top_edge); |
882 } | 877 } |
883 if (edges & MAGNETISM_EDGE_LEFT && | 878 if (edges & MAGNETISM_EDGE_LEFT && |
884 ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) { | 879 ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) { |
885 bounds->set_width(bounds->right() - left_edge); | 880 bounds->set_width(bounds->right() - left_edge); |
886 bounds->set_x(left_edge); | 881 bounds->set_x(left_edge); |
887 } | 882 } |
888 if (edges & MAGNETISM_EDGE_BOTTOM && | 883 if (edges & MAGNETISM_EDGE_BOTTOM && |
889 ShouldStickToEdge(bottom_edge - bounds->bottom(), sticky_size)) { | 884 ShouldStickToEdge(bottom_edge - bounds->bottom(), sticky_size)) { |
890 bounds->set_height(bottom_edge - bounds->y()); | 885 bounds->set_height(bottom_edge - bounds->y()); |
891 } | 886 } |
892 if (edges & MAGNETISM_EDGE_RIGHT && | 887 if (edges & MAGNETISM_EDGE_RIGHT && |
893 ShouldStickToEdge(right_edge - bounds->right(), sticky_size)) { | 888 ShouldStickToEdge(right_edge - bounds->right(), sticky_size)) { |
894 bounds->set_width(right_edge - bounds->x()); | 889 bounds->set_width(right_edge - bounds->x()); |
895 } | 890 } |
896 } | 891 } |
897 | 892 |
898 int WorkspaceWindowResizer::PrimaryAxisSize(const gfx::Size& size) const { | 893 int WorkspaceWindowResizer::PrimaryAxisSize(const gfx::Size& size) const { |
899 return PrimaryAxisCoordinate(size.width(), size.height()); | 894 return PrimaryAxisCoordinate(size.width(), size.height()); |
900 } | 895 } |
901 | 896 |
902 int WorkspaceWindowResizer::PrimaryAxisCoordinate(int x, int y) const { | 897 int WorkspaceWindowResizer::PrimaryAxisCoordinate(int x, int y) const { |
903 switch (details_.window_component) { | 898 switch (details().window_component) { |
904 case HTRIGHT: | 899 case HTRIGHT: |
905 return x; | 900 return x; |
906 case HTBOTTOM: | 901 case HTBOTTOM: |
907 return y; | 902 return y; |
908 default: | 903 default: |
909 NOTREACHED(); | 904 NOTREACHED(); |
910 } | 905 } |
911 return 0; | 906 return 0; |
912 } | 907 } |
913 | 908 |
914 void WorkspaceWindowResizer::UpdateSnapPhantomWindow(const gfx::Point& location, | 909 void WorkspaceWindowResizer::UpdateSnapPhantomWindow(const gfx::Point& location, |
915 const gfx::Rect& bounds) { | 910 const gfx::Rect& bounds) { |
916 if (!did_move_or_resize_ || details_.window_component != HTCAPTION) | 911 if (!did_move_or_resize_ || details().window_component != HTCAPTION) |
917 return; | 912 return; |
918 | 913 |
919 SnapType last_type = snap_type_; | 914 SnapType last_type = snap_type_; |
920 snap_type_ = GetSnapType(location); | 915 snap_type_ = GetSnapType(location); |
921 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) { | 916 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) { |
922 snap_phantom_window_controller_.reset(); | 917 snap_phantom_window_controller_.reset(); |
923 snap_sizer_.reset(); | 918 snap_sizer_.reset(); |
924 if (snap_type_ == SNAP_NONE) { | 919 if (snap_type_ == SNAP_NONE) { |
925 SetDraggedWindowDocked(false); | 920 SetDraggedWindowDocked(false); |
926 return; | 921 return; |
927 } | 922 } |
928 } | 923 } |
929 const bool can_dock = dock_layout_->CanDockWindow(window(), snap_type_); | 924 const bool can_dock = dock_layout_->CanDockWindow(GetTarget(), snap_type_); |
930 const bool can_snap = window_state()->CanSnap(); | 925 const bool can_snap = window_state()->CanSnap(); |
931 if (!can_snap && !can_dock) { | 926 if (!can_snap && !can_dock) { |
932 snap_type_ = SNAP_NONE; | 927 snap_type_ = SNAP_NONE; |
933 snap_phantom_window_controller_.reset(); | 928 snap_phantom_window_controller_.reset(); |
934 snap_sizer_.reset(); | 929 snap_sizer_.reset(); |
935 SetDraggedWindowDocked(false); | 930 SetDraggedWindowDocked(false); |
936 return; | 931 return; |
937 } | 932 } |
938 SnapSizer::Edge edge = (snap_type_ == SNAP_LEFT) ? | 933 SnapSizer::Edge edge = (snap_type_ == SNAP_LEFT) ? |
939 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE; | 934 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE; |
940 if (!snap_sizer_) { | 935 if (!snap_sizer_) { |
941 snap_sizer_.reset(new SnapSizer(window_state(), | 936 snap_sizer_.reset(new SnapSizer(window_state(), |
942 location, | 937 location, |
943 edge, | 938 edge, |
944 internal::SnapSizer::OTHER_INPUT)); | 939 internal::SnapSizer::OTHER_INPUT)); |
945 } else { | 940 } else { |
946 snap_sizer_->Update(location); | 941 snap_sizer_->Update(location); |
947 } | 942 } |
948 | 943 |
949 // Update phantom window with snapped or docked guide bounds. | 944 // Update phantom window with snapped or docked guide bounds. |
950 // Windows that cannot be snapped or are less wide than kMaxDockWidth can get | 945 // Windows that cannot be snapped or are less wide than kMaxDockWidth can get |
951 // docked without going through a snapping sequence. | 946 // docked without going through a snapping sequence. |
952 gfx::Rect phantom_bounds; | 947 gfx::Rect phantom_bounds; |
953 if (can_snap && | 948 if (can_snap && (!can_dock || GetTarget()->bounds().width() > |
954 (!can_dock || | 949 DockedWindowLayoutManager::kMaxDockWidth)) { |
955 window()->bounds().width() > DockedWindowLayoutManager::kMaxDockWidth)) | |
956 phantom_bounds = snap_sizer_->target_bounds(); | 950 phantom_bounds = snap_sizer_->target_bounds(); |
| 951 } |
957 const bool should_dock = can_dock && | 952 const bool should_dock = can_dock && |
958 (phantom_bounds.IsEmpty() || | 953 (phantom_bounds.IsEmpty() || |
959 snap_sizer_->end_of_sequence() || | 954 snap_sizer_->end_of_sequence() || |
960 dock_layout_->is_dragged_window_docked()); | 955 dock_layout_->is_dragged_window_docked()); |
961 SetDraggedWindowDocked(should_dock); | 956 SetDraggedWindowDocked(should_dock); |
962 snap_type_ = GetSnapType(location); | 957 snap_type_ = GetSnapType(location); |
963 if (dock_layout_->is_dragged_window_docked()) { | 958 if (dock_layout_->is_dragged_window_docked()) { |
964 phantom_bounds = ScreenAsh::ConvertRectFromScreen( | 959 phantom_bounds = ScreenAsh::ConvertRectFromScreen( |
965 window()->parent(), dock_layout_->dragged_bounds()); | 960 GetTarget()->parent(), dock_layout_->dragged_bounds()); |
966 } | 961 } |
967 | 962 |
968 if (phantom_bounds.IsEmpty()) { | 963 if (phantom_bounds.IsEmpty()) { |
969 snap_phantom_window_controller_.reset(); | 964 snap_phantom_window_controller_.reset(); |
970 return; | 965 return; |
971 } | 966 } |
972 | 967 |
973 if (!snap_phantom_window_controller_) { | 968 if (!snap_phantom_window_controller_) { |
974 snap_phantom_window_controller_.reset( | 969 snap_phantom_window_controller_.reset( |
975 new PhantomWindowController(window())); | 970 new PhantomWindowController(GetTarget())); |
976 } | 971 } |
977 snap_phantom_window_controller_->Show(ScreenAsh::ConvertRectToScreen( | 972 snap_phantom_window_controller_->Show(ScreenAsh::ConvertRectToScreen( |
978 window()->parent(), phantom_bounds)); | 973 GetTarget()->parent(), phantom_bounds)); |
979 } | 974 } |
980 | 975 |
981 void WorkspaceWindowResizer::RestackWindows() { | 976 void WorkspaceWindowResizer::RestackWindows() { |
982 if (attached_windows_.empty()) | 977 if (attached_windows_.empty()) |
983 return; | 978 return; |
984 // Build a map from index in children to window, returning if there is a | 979 // Build a map from index in children to window, returning if there is a |
985 // window with a different parent. | 980 // window with a different parent. |
986 typedef std::map<size_t, aura::Window*> IndexToWindowMap; | 981 typedef std::map<size_t, aura::Window*> IndexToWindowMap; |
987 IndexToWindowMap map; | 982 IndexToWindowMap map; |
988 aura::Window* parent = window()->parent(); | 983 aura::Window* parent = GetTarget()->parent(); |
989 const aura::Window::Windows& windows(parent->children()); | 984 const aura::Window::Windows& windows(parent->children()); |
990 map[std::find(windows.begin(), windows.end(), window()) - | 985 map[std::find(windows.begin(), windows.end(), GetTarget()) - |
991 windows.begin()] = window(); | 986 windows.begin()] = GetTarget(); |
992 for (std::vector<aura::Window*>::const_iterator i = | 987 for (std::vector<aura::Window*>::const_iterator i = |
993 attached_windows_.begin(); i != attached_windows_.end(); ++i) { | 988 attached_windows_.begin(); i != attached_windows_.end(); ++i) { |
994 if ((*i)->parent() != parent) | 989 if ((*i)->parent() != parent) |
995 return; | 990 return; |
996 size_t index = | 991 size_t index = |
997 std::find(windows.begin(), windows.end(), *i) - windows.begin(); | 992 std::find(windows.begin(), windows.end(), *i) - windows.begin(); |
998 map[index] = *i; | 993 map[index] = *i; |
999 } | 994 } |
1000 | 995 |
1001 // Reorder the windows starting at the topmost. | 996 // Reorder the windows starting at the topmost. |
1002 parent->StackChildAtTop(map.rbegin()->second); | 997 parent->StackChildAtTop(map.rbegin()->second); |
1003 for (IndexToWindowMap::const_reverse_iterator i = map.rbegin(); | 998 for (IndexToWindowMap::const_reverse_iterator i = map.rbegin(); |
1004 i != map.rend(); ) { | 999 i != map.rend(); ) { |
1005 aura::Window* window = i->second; | 1000 aura::Window* window = i->second; |
1006 ++i; | 1001 ++i; |
1007 if (i != map.rend()) | 1002 if (i != map.rend()) |
1008 parent->StackChildBelow(i->second, window); | 1003 parent->StackChildBelow(i->second, window); |
1009 } | 1004 } |
1010 } | 1005 } |
1011 | 1006 |
1012 SnapType WorkspaceWindowResizer::GetSnapType( | 1007 SnapType WorkspaceWindowResizer::GetSnapType( |
1013 const gfx::Point& location) const { | 1008 const gfx::Point& location) const { |
1014 // TODO: this likely only wants total display area, not the area of a single | 1009 // TODO: this likely only wants total display area, not the area of a single |
1015 // display. | 1010 // display. |
1016 gfx::Rect area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); | 1011 gfx::Rect area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(GetTarget())); |
1017 if (details_.source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) { | 1012 if (details().source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) { |
1018 // Increase tolerance for touch-snapping near the screen edges. This is only | 1013 // Increase tolerance for touch-snapping near the screen edges. This is only |
1019 // necessary when the work area left or right edge is same as screen edge. | 1014 // necessary when the work area left or right edge is same as screen edge. |
1020 gfx::Rect display_bounds(ScreenAsh::GetDisplayBoundsInParent(window())); | 1015 gfx::Rect display_bounds(ScreenAsh::GetDisplayBoundsInParent(GetTarget())); |
1021 int inset_left = 0; | 1016 int inset_left = 0; |
1022 if (area.x() == display_bounds.x()) | 1017 if (area.x() == display_bounds.x()) |
1023 inset_left = kScreenEdgeInsetForTouchResize; | 1018 inset_left = kScreenEdgeInsetForTouchResize; |
1024 int inset_right = 0; | 1019 int inset_right = 0; |
1025 if (area.right() == display_bounds.right()) | 1020 if (area.right() == display_bounds.right()) |
1026 inset_right = kScreenEdgeInsetForTouchResize; | 1021 inset_right = kScreenEdgeInsetForTouchResize; |
1027 area.Inset(inset_left, 0, inset_right, 0); | 1022 area.Inset(inset_left, 0, inset_right, 0); |
1028 } | 1023 } |
1029 if (location.x() <= area.x()) | 1024 if (location.x() <= area.x()) |
1030 return SNAP_LEFT; | 1025 return SNAP_LEFT; |
1031 if (location.x() >= area.right() - 1) | 1026 if (location.x() >= area.right() - 1) |
1032 return SNAP_RIGHT; | 1027 return SNAP_RIGHT; |
1033 return SNAP_NONE; | 1028 return SNAP_NONE; |
1034 } | 1029 } |
1035 | 1030 |
1036 void WorkspaceWindowResizer::SetDraggedWindowDocked(bool should_dock) { | 1031 void WorkspaceWindowResizer::SetDraggedWindowDocked(bool should_dock) { |
1037 if (should_dock && | 1032 if (should_dock && |
1038 dock_layout_->GetAlignmentOfWindow(window()) != DOCKED_ALIGNMENT_NONE) { | 1033 dock_layout_->GetAlignmentOfWindow(GetTarget()) != |
| 1034 DOCKED_ALIGNMENT_NONE) { |
1039 if (!dock_layout_->is_dragged_window_docked()) { | 1035 if (!dock_layout_->is_dragged_window_docked()) { |
1040 window_state()->set_bounds_changed_by_user(false); | 1036 window_state()->set_bounds_changed_by_user(false); |
1041 dock_layout_->DockDraggedWindow(window()); | 1037 dock_layout_->DockDraggedWindow(GetTarget()); |
1042 } | 1038 } |
1043 } else { | 1039 } else { |
1044 if (dock_layout_->is_dragged_window_docked()) { | 1040 if (dock_layout_->is_dragged_window_docked()) { |
1045 dock_layout_->UndockDraggedWindow(); | 1041 dock_layout_->UndockDraggedWindow(); |
1046 window_state()->set_bounds_changed_by_user(true); | 1042 window_state()->set_bounds_changed_by_user(true); |
1047 } | 1043 } |
1048 } | 1044 } |
1049 } | 1045 } |
1050 | 1046 |
1051 } // namespace internal | 1047 } // namespace internal |
1052 } // namespace ash | 1048 } // namespace ash |
OLD | NEW |