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> |
11 | 11 |
12 #include "ash/ash_switches.h" | 12 #include "ash/ash_switches.h" |
13 #include "ash/root_window_controller.h" | 13 #include "ash/root_window_controller.h" |
14 #include "ash/screen_ash.h" | 14 #include "ash/screen_ash.h" |
15 #include "ash/shell.h" | 15 #include "ash/shell.h" |
16 #include "ash/shell_window_ids.h" | 16 #include "ash/shell_window_ids.h" |
17 #include "ash/wm/coordinate_conversion.h" | 17 #include "ash/wm/coordinate_conversion.h" |
18 #include "ash/wm/default_window_resizer.h" | 18 #include "ash/wm/default_window_resizer.h" |
19 #include "ash/wm/dock/docked_window_resizer.h" | 19 #include "ash/wm/dock/docked_window_resizer.h" |
20 #include "ash/wm/drag_window_resizer.h" | 20 #include "ash/wm/drag_window_resizer.h" |
21 #include "ash/wm/panels/panel_window_resizer.h" | 21 #include "ash/wm/panels/panel_window_resizer.h" |
22 #include "ash/wm/property_util.h" | 22 #include "ash/wm/property_util.h" |
23 #include "ash/wm/window_properties.h" | 23 #include "ash/wm/window_properties.h" |
24 #include "ash/wm/window_util.h" | 24 #include "ash/wm/window_util.h" |
25 #include "ash/wm/workspace/phantom_window_controller.h" | 25 #include "ash/wm/workspace/phantom_window_controller.h" |
26 #include "ash/wm/workspace/snap_sizer.h" | |
27 #include "base/command_line.h" | 26 #include "base/command_line.h" |
28 #include "ui/aura/client/aura_constants.h" | 27 #include "ui/aura/client/aura_constants.h" |
29 #include "ui/aura/client/screen_position_client.h" | 28 #include "ui/aura/client/screen_position_client.h" |
30 #include "ui/aura/client/window_types.h" | 29 #include "ui/aura/client/window_types.h" |
31 #include "ui/aura/root_window.h" | 30 #include "ui/aura/root_window.h" |
32 #include "ui/aura/window.h" | 31 #include "ui/aura/window.h" |
33 #include "ui/aura/window_delegate.h" | 32 #include "ui/aura/window_delegate.h" |
34 #include "ui/base/hit_test.h" | 33 #include "ui/base/hit_test.h" |
35 #include "ui/compositor/layer.h" | 34 #include "ui/compositor/layer.h" |
36 #include "ui/gfx/screen.h" | 35 #include "ui/gfx/screen.h" |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 return; | 406 return; |
408 | 407 |
409 // When the window is not in the normal show state, we do not snap the window. | 408 // When the window is not in the normal show state, we do not snap the window. |
410 // This happens when the user minimizes or maximizes the window by keyboard | 409 // This happens when the user minimizes or maximizes the window by keyboard |
411 // shortcut while dragging it. If the window is the result of dragging a tab | 410 // shortcut while dragging it. If the window is the result of dragging a tab |
412 // out of a maximized window, it's already in the normal show state when this | 411 // out of a maximized window, it's already in the normal show state when this |
413 // is called, so it does not matter. | 412 // is called, so it does not matter. |
414 if (wm::IsWindowNormal(window()) && | 413 if (wm::IsWindowNormal(window()) && |
415 (window()->type() != aura::client::WINDOW_TYPE_PANEL || | 414 (window()->type() != aura::client::WINDOW_TYPE_PANEL || |
416 !window()->GetProperty(kPanelAttachedKey)) && | 415 !window()->GetProperty(kPanelAttachedKey)) && |
417 (snap_type_ == SNAP_LEFT_EDGE || snap_type_ == SNAP_RIGHT_EDGE)) { | 416 (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) { |
418 if (!GetRestoreBoundsInScreen(window())) { | 417 if (!GetRestoreBoundsInScreen(window())) { |
419 gfx::Rect initial_bounds = ScreenAsh::ConvertRectToScreen( | 418 gfx::Rect initial_bounds = ScreenAsh::ConvertRectToScreen( |
420 window()->parent(), details_.initial_bounds_in_parent); | 419 window()->parent(), details_.initial_bounds_in_parent); |
421 SetRestoreBoundsInScreen(window(), details_.restore_bounds.IsEmpty() ? | 420 SetRestoreBoundsInScreen(window(), details_.restore_bounds.IsEmpty() ? |
422 initial_bounds : | 421 initial_bounds : |
423 details_.restore_bounds); | 422 details_.restore_bounds); |
424 } | 423 } |
425 window()->SetBounds(snap_sizer_->target_bounds()); | 424 if (snap_type_ == SNAP_LEFT) |
426 return; | 425 wm::SnapWindowToEdge(window(), wm::SNAP_LEFT_EDGE); |
| 426 else if (snap_type_ == SNAP_RIGHT) |
| 427 wm::SnapWindowToEdge(window(), wm::SNAP_RIGHT_EDGE); |
427 } | 428 } |
428 } | 429 } |
429 | 430 |
430 void WorkspaceWindowResizer::RevertDrag() { | 431 void WorkspaceWindowResizer::RevertDrag() { |
431 snap_phantom_window_controller_.reset(); | 432 snap_phantom_window_controller_.reset(); |
432 | 433 |
433 if (!did_move_or_resize_) | 434 if (!did_move_or_resize_) |
434 return; | 435 return; |
435 | 436 |
436 window()->SetBounds(details_.initial_bounds_in_parent); | 437 window()->SetBounds(details_.initial_bounds_in_parent); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 shell->cursor_manager()->LockCursor(); | 484 shell->cursor_manager()->LockCursor(); |
484 | 485 |
485 // Only support attaching to the right/bottom. | 486 // Only support attaching to the right/bottom. |
486 DCHECK(attached_windows_.empty() || | 487 DCHECK(attached_windows_.empty() || |
487 (details.window_component == HTRIGHT || | 488 (details.window_component == HTRIGHT || |
488 details.window_component == HTBOTTOM)); | 489 details.window_component == HTBOTTOM)); |
489 | 490 |
490 // TODO: figure out how to deal with window going off the edge. | 491 // TODO: figure out how to deal with window going off the edge. |
491 | 492 |
492 // Calculate sizes so that we can maintain the ratios if we need to resize. | 493 // Calculate sizes so that we can maintain the ratios if we need to resize. |
493 int total_available = 0; | |
494 for (size_t i = 0; i < attached_windows_.size(); ++i) { | 494 for (size_t i = 0; i < attached_windows_.size(); ++i) { |
495 gfx::Size min(attached_windows_[i]->delegate()->GetMinimumSize()); | 495 gfx::Size min(attached_windows_[i]->delegate()->GetMinimumSize()); |
496 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size()); | 496 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size()); |
497 initial_size_.push_back(initial_size); | 497 initial_size_.push_back(initial_size); |
498 // If current size is smaller than the min, use the current size as the min. | 498 // If current size is smaller than the min, use the current size as the min. |
499 // This way we don't snap on resize. | 499 // This way we don't snap on resize. |
500 int min_size = std::min(initial_size, | 500 int min_size = std::min(initial_size, |
501 std::max(PrimaryAxisSize(min), kMinOnscreenSize)); | 501 std::max(PrimaryAxisSize(min), kMinOnscreenSize)); |
502 total_min_ += min_size; | 502 total_min_ += min_size; |
503 total_initial_size_ += initial_size; | 503 total_initial_size_ += initial_size; |
504 total_available += std::max(min_size, initial_size) - min_size; | |
505 } | 504 } |
506 } | 505 } |
507 | 506 |
508 gfx::Rect WorkspaceWindowResizer::GetFinalBounds( | |
509 const gfx::Rect& bounds) const { | |
510 if (snap_phantom_window_controller_.get() && | |
511 snap_phantom_window_controller_->IsShowing()) { | |
512 return snap_phantom_window_controller_->bounds_in_screen(); | |
513 } | |
514 return bounds; | |
515 } | |
516 | |
517 void WorkspaceWindowResizer::LayoutAttachedWindows( | 507 void WorkspaceWindowResizer::LayoutAttachedWindows( |
518 gfx::Rect* bounds) { | 508 gfx::Rect* bounds) { |
519 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); | 509 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); |
520 int initial_size = PrimaryAxisSize(details_.initial_bounds_in_parent.size()); | 510 int initial_size = PrimaryAxisSize(details_.initial_bounds_in_parent.size()); |
521 int current_size = PrimaryAxisSize(bounds->size()); | 511 int current_size = PrimaryAxisSize(bounds->size()); |
522 int start = PrimaryAxisCoordinate(bounds->right(), bounds->bottom()); | 512 int start = PrimaryAxisCoordinate(bounds->right(), bounds->bottom()); |
523 int end = PrimaryAxisCoordinate(work_area.right(), work_area.bottom()); | 513 int end = PrimaryAxisCoordinate(work_area.right(), work_area.bottom()); |
524 | 514 |
525 int delta = current_size - initial_size; | 515 int delta = current_size - initial_size; |
526 int available_size = end - start; | 516 int available_size = end - start; |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
860 | 850 |
861 if (window()->type() == aura::client::WINDOW_TYPE_PANEL && | 851 if (window()->type() == aura::client::WINDOW_TYPE_PANEL && |
862 window()->GetProperty(kPanelAttachedKey)) { | 852 window()->GetProperty(kPanelAttachedKey)) { |
863 return; | 853 return; |
864 } | 854 } |
865 | 855 |
866 SnapType last_type = snap_type_; | 856 SnapType last_type = snap_type_; |
867 snap_type_ = GetSnapType(location); | 857 snap_type_ = GetSnapType(location); |
868 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) { | 858 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) { |
869 snap_phantom_window_controller_.reset(); | 859 snap_phantom_window_controller_.reset(); |
870 snap_sizer_.reset(); | |
871 if (snap_type_ == SNAP_NONE) | 860 if (snap_type_ == SNAP_NONE) |
872 return; | 861 return; |
873 } | 862 } |
874 if (!snap_sizer_) { | |
875 SnapSizer::Edge edge = (snap_type_ == SNAP_LEFT_EDGE) ? | |
876 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE; | |
877 snap_sizer_.reset(new SnapSizer(window(), | |
878 location, | |
879 edge, | |
880 internal::SnapSizer::OTHER_INPUT)); | |
881 } else { | |
882 snap_sizer_->Update(location); | |
883 } | |
884 if (!snap_phantom_window_controller_) { | 863 if (!snap_phantom_window_controller_) { |
885 snap_phantom_window_controller_.reset( | 864 snap_phantom_window_controller_.reset( |
886 new PhantomWindowController(window())); | 865 new PhantomWindowController(window())); |
887 } | 866 } |
| 867 |
| 868 wm::SnapEdge edge = (snap_type_ == SNAP_LEFT) ? |
| 869 wm::SNAP_LEFT_EDGE : wm::SNAP_RIGHT_EDGE; |
| 870 gfx::Rect target_bounds = wm::GetSnappedWindowBoundsInParent(window(), edge); |
888 snap_phantom_window_controller_->Show(ScreenAsh::ConvertRectToScreen( | 871 snap_phantom_window_controller_->Show(ScreenAsh::ConvertRectToScreen( |
889 window()->parent(), snap_sizer_->target_bounds())); | 872 window()->parent(), target_bounds)); |
890 } | 873 } |
891 | 874 |
892 void WorkspaceWindowResizer::RestackWindows() { | 875 void WorkspaceWindowResizer::RestackWindows() { |
893 if (attached_windows_.empty()) | 876 if (attached_windows_.empty()) |
894 return; | 877 return; |
895 // Build a map from index in children to window, returning if there is a | 878 // Build a map from index in children to window, returning if there is a |
896 // window with a different parent. | 879 // window with a different parent. |
897 typedef std::map<size_t, aura::Window*> IndexToWindowMap; | 880 typedef std::map<size_t, aura::Window*> IndexToWindowMap; |
898 IndexToWindowMap map; | 881 IndexToWindowMap map; |
899 aura::Window* parent = window()->parent(); | 882 aura::Window* parent = window()->parent(); |
(...skipping 19 matching lines...) Expand all Loading... |
919 parent->StackChildBelow(i->second, window); | 902 parent->StackChildBelow(i->second, window); |
920 } | 903 } |
921 } | 904 } |
922 | 905 |
923 WorkspaceWindowResizer::SnapType WorkspaceWindowResizer::GetSnapType( | 906 WorkspaceWindowResizer::SnapType WorkspaceWindowResizer::GetSnapType( |
924 const gfx::Point& location) const { | 907 const gfx::Point& location) const { |
925 // TODO: this likely only wants total display area, not the area of a single | 908 // TODO: this likely only wants total display area, not the area of a single |
926 // display. | 909 // display. |
927 gfx::Rect area(ScreenAsh::GetDisplayBoundsInParent(window())); | 910 gfx::Rect area(ScreenAsh::GetDisplayBoundsInParent(window())); |
928 if (location.x() <= area.x()) | 911 if (location.x() <= area.x()) |
929 return SNAP_LEFT_EDGE; | 912 return SNAP_LEFT; |
930 if (location.x() >= area.right() - 1) | 913 if (location.x() >= area.right() - 1) |
931 return SNAP_RIGHT_EDGE; | 914 return SNAP_RIGHT; |
932 return SNAP_NONE; | 915 return SNAP_NONE; |
933 } | 916 } |
934 | 917 |
935 } // namespace internal | 918 } // namespace internal |
936 } // namespace ash | 919 } // namespace ash |
OLD | NEW |