Chromium Code Reviews| 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/display/display_controller.h" | 13 #include "ash/display/display_controller.h" |
| 13 #include "ash/screen_ash.h" | 14 #include "ash/screen_ash.h" |
| 14 #include "ash/shell.h" | 15 #include "ash/shell.h" |
| 15 #include "ash/shell_window_ids.h" | 16 #include "ash/shell_window_ids.h" |
| 16 #include "ash/wm/coordinate_conversion.h" | 17 #include "ash/wm/coordinate_conversion.h" |
| 17 #include "ash/wm/default_window_resizer.h" | 18 #include "ash/wm/default_window_resizer.h" |
| 18 #include "ash/wm/drag_window_resizer.h" | 19 #include "ash/wm/drag_window_resizer.h" |
| 19 #include "ash/wm/panels/panel_window_resizer.h" | 20 #include "ash/wm/panels/panel_window_resizer.h" |
| 20 #include "ash/wm/property_util.h" | 21 #include "ash/wm/property_util.h" |
| 21 #include "ash/wm/window_properties.h" | 22 #include "ash/wm/window_properties.h" |
| 22 #include "ash/wm/window_util.h" | 23 #include "ash/wm/window_util.h" |
| 23 #include "ash/wm/workspace/phantom_window_controller.h" | 24 #include "ash/wm/workspace/phantom_window_controller.h" |
| 24 #include "ash/wm/workspace/snap_sizer.h" | 25 #include "ash/wm/workspace/snap_sizer.h" |
| 26 #include "base/command_line.h" | |
| 25 #include "ui/aura/client/aura_constants.h" | 27 #include "ui/aura/client/aura_constants.h" |
| 26 #include "ui/aura/client/window_types.h" | 28 #include "ui/aura/client/window_types.h" |
| 27 #include "ui/aura/root_window.h" | 29 #include "ui/aura/root_window.h" |
| 28 #include "ui/aura/window.h" | 30 #include "ui/aura/window.h" |
| 29 #include "ui/aura/window_delegate.h" | 31 #include "ui/aura/window_delegate.h" |
| 30 #include "ui/base/hit_test.h" | 32 #include "ui/base/hit_test.h" |
| 31 #include "ui/compositor/layer.h" | 33 #include "ui/compositor/layer.h" |
| 32 #include "ui/gfx/screen.h" | 34 #include "ui/gfx/screen.h" |
| 33 #include "ui/gfx/transform.h" | 35 #include "ui/gfx/transform.h" |
| 34 | 36 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 window_resizer = PanelWindowResizer::Create( | 69 window_resizer = PanelWindowResizer::Create( |
| 68 window_resizer, window, point_in_parent, window_component); | 70 window_resizer, window, point_in_parent, window_component); |
| 69 } | 71 } |
| 70 return make_scoped_ptr<WindowResizer>(window_resizer); | 72 return make_scoped_ptr<WindowResizer>(window_resizer); |
| 71 } | 73 } |
| 72 | 74 |
| 73 namespace internal { | 75 namespace internal { |
| 74 | 76 |
| 75 namespace { | 77 namespace { |
| 76 | 78 |
| 77 // Duration of the animation when snapping the window into place. | 79 const int kStickySize = 64; |
|
sky
2013/04/22 17:20:00
Comment.
stevenjb
2013/04/22 18:09:41
Done.
| |
| 78 const int kSnapDurationMS = 100; | |
| 79 | 80 |
| 80 // Returns true if should snap to the edge. | 81 // Returns true if the window should stick to the edge. |
| 81 bool ShouldSnapToEdge(int distance_from_edge, int grid_size) { | 82 bool ShouldStickToEdge(int distance_from_edge, int sticky_size) { |
| 82 return distance_from_edge < grid_size && | 83 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 83 distance_from_edge > -grid_size * 2; | 84 switches::kAshEnableStickyEdges)) { |
| 85 return distance_from_edge < 0 && | |
| 86 distance_from_edge > -sticky_size; | |
| 87 } else { | |
|
sky
2013/04/22 17:20:00
no else.
stevenjb
2013/04/22 18:09:41
Done.
| |
| 88 return distance_from_edge < sticky_size && | |
| 89 distance_from_edge > -sticky_size * 2; | |
| 90 } | |
| 84 } | 91 } |
| 85 | 92 |
| 86 // Returns the coordinate along the secondary axis to snap to. | 93 // Returns the coordinate along the secondary axis to stick to. |
|
sky
2013/04/22 17:20:00
This isn't used in what you are calling sticking.
stevenjb
2013/04/22 18:09:41
Done.
| |
| 87 int CoordinateAlongSecondaryAxis(SecondaryMagnetismEdge edge, | 94 int CoordinateAlongSecondaryAxis(SecondaryMagnetismEdge edge, |
| 88 int leading, | 95 int leading, |
| 89 int trailing, | 96 int trailing, |
| 90 int none) { | 97 int none) { |
| 91 switch (edge) { | 98 switch (edge) { |
| 92 case SECONDARY_MAGNETISM_EDGE_LEADING: | 99 case SECONDARY_MAGNETISM_EDGE_LEADING: |
| 93 return leading; | 100 return leading; |
| 94 case SECONDARY_MAGNETISM_EDGE_TRAILING: | 101 case SECONDARY_MAGNETISM_EDGE_TRAILING: |
| 95 return trailing; | 102 return trailing; |
| 96 case SECONDARY_MAGNETISM_EDGE_NONE: | 103 case SECONDARY_MAGNETISM_EDGE_NONE: |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 x = attach_origin.x(); | 187 x = attach_origin.x(); |
| 181 w = src.right() - x; | 188 w = src.right() - x; |
| 182 } else if (edge.secondary_edge == SECONDARY_MAGNETISM_EDGE_TRAILING) { | 189 } else if (edge.secondary_edge == SECONDARY_MAGNETISM_EDGE_TRAILING) { |
| 183 w += attach_origin.x() - src.x(); | 190 w += attach_origin.x() - src.x(); |
| 184 } | 191 } |
| 185 break; | 192 break; |
| 186 } | 193 } |
| 187 return gfx::Rect(x, y, w, h); | 194 return gfx::Rect(x, y, w, h); |
| 188 } | 195 } |
| 189 | 196 |
| 190 // Converts a window comopnent edge to the magnetic edge to snap to. | 197 // Converts a window component edge to the magnetic edge to snap to. |
| 191 uint32 WindowComponentToMagneticEdge(int window_component) { | 198 uint32 WindowComponentToMagneticEdge(int window_component) { |
| 192 switch (window_component) { | 199 switch (window_component) { |
| 193 case HTTOPLEFT: | 200 case HTTOPLEFT: |
| 194 return MAGNETISM_EDGE_LEFT | MAGNETISM_EDGE_TOP; | 201 return MAGNETISM_EDGE_LEFT | MAGNETISM_EDGE_TOP; |
| 195 case HTTOPRIGHT: | 202 case HTTOPRIGHT: |
| 196 return MAGNETISM_EDGE_TOP | MAGNETISM_EDGE_RIGHT; | 203 return MAGNETISM_EDGE_TOP | MAGNETISM_EDGE_RIGHT; |
| 197 case HTBOTTOMLEFT: | 204 case HTBOTTOMLEFT: |
| 198 return MAGNETISM_EDGE_LEFT | MAGNETISM_EDGE_BOTTOM; | 205 return MAGNETISM_EDGE_LEFT | MAGNETISM_EDGE_BOTTOM; |
| 199 case HTBOTTOMRIGHT: | 206 case HTBOTTOMRIGHT: |
| 200 return MAGNETISM_EDGE_RIGHT | MAGNETISM_EDGE_BOTTOM; | 207 return MAGNETISM_EDGE_RIGHT | MAGNETISM_EDGE_BOTTOM; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 const std::vector<aura::Window*>& attached_windows) { | 312 const std::vector<aura::Window*>& attached_windows) { |
| 306 Details details(window, location_in_parent, window_component); | 313 Details details(window, location_in_parent, window_component); |
| 307 return details.is_resizable ? | 314 return details.is_resizable ? |
| 308 new WorkspaceWindowResizer(details, attached_windows) : NULL; | 315 new WorkspaceWindowResizer(details, attached_windows) : NULL; |
| 309 } | 316 } |
| 310 | 317 |
| 311 void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_parent, | 318 void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_parent, |
| 312 int event_flags) { | 319 int event_flags) { |
| 313 last_mouse_location_ = location_in_parent; | 320 last_mouse_location_ = location_in_parent; |
| 314 | 321 |
| 315 const int snap_size = | 322 int snap_size; |
|
sky
2013/04/22 17:20:00
sticky_size
stevenjb
2013/04/22 18:09:41
Done.
| |
| 316 event_flags & ui::EF_CONTROL_DOWN ? 0 : kScreenEdgeInset; | 323 if (event_flags & ui::EF_CONTROL_DOWN) { |
| 324 snap_size = 0; | |
| 325 } else if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 326 switches::kAshEnableStickyEdges)) { | |
| 327 snap_size = kStickySize; | |
| 328 } else { | |
| 329 snap_size = kScreenEdgeInset; | |
| 330 } | |
| 317 // |bounds| is in |window()->parent()|'s coordinates. | 331 // |bounds| is in |window()->parent()|'s coordinates. |
| 318 gfx::Rect bounds = CalculateBoundsForDrag(details_, location_in_parent); | 332 gfx::Rect bounds = CalculateBoundsForDrag(details_, location_in_parent); |
| 319 | 333 |
| 320 if (wm::IsWindowNormal(window())) | 334 if (wm::IsWindowNormal(window())) |
| 321 AdjustBoundsForMainWindow(snap_size, &bounds); | 335 AdjustBoundsForMainWindow(snap_size, &bounds); |
| 322 | 336 |
| 323 if (bounds != window()->bounds()) { | 337 if (bounds != window()->bounds()) { |
| 324 if (!did_move_or_resize_) { | 338 if (!did_move_or_resize_) { |
| 325 if (!details_.restore_bounds.IsEmpty()) | 339 if (!details_.restore_bounds.IsEmpty()) |
| 326 ClearRestoreBounds(window()); | 340 ClearRestoreBounds(window()); |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 659 int max_y = work_area.bottom() - kMinOnscreenHeight; | 673 int max_y = work_area.bottom() - kMinOnscreenHeight; |
| 660 if (bounds->y() > max_y) { | 674 if (bounds->y() > max_y) { |
| 661 bounds->set_y(max_y); | 675 bounds->set_y(max_y); |
| 662 } else if (bounds->y() <= work_area.y()) { | 676 } else if (bounds->y() <= work_area.y()) { |
| 663 // Don't allow dragging above the top of the display until the mouse | 677 // Don't allow dragging above the top of the display until the mouse |
| 664 // cursor reaches the work area above if any. | 678 // cursor reaches the work area above if any. |
| 665 bounds->set_y(work_area.y()); | 679 bounds->set_y(work_area.y()); |
| 666 } | 680 } |
| 667 | 681 |
| 668 if (snap_size > 0) { | 682 if (snap_size > 0) { |
| 669 SnapToWorkAreaEdges(work_area, snap_size, bounds); | 683 StickToWorkAreaEdges(work_area, snap_size, bounds); |
| 670 MagneticallySnapToOtherWindows(bounds); | 684 MagneticallySnapToOtherWindows(bounds); |
| 671 } | 685 } |
| 672 } else if (snap_size > 0) { | 686 } else if (snap_size > 0) { |
| 673 MagneticallySnapResizeToOtherWindows(bounds); | 687 MagneticallySnapResizeToOtherWindows(bounds); |
| 674 if (!magnetism_window_ && snap_size > 0) | 688 if (!magnetism_window_ && snap_size > 0) |
| 675 SnapResizeToWorkAreaBounds(work_area, snap_size, bounds); | 689 StickyResizeToWorkAreaBounds(work_area, snap_size, bounds); |
| 676 } | 690 } |
| 677 | 691 |
| 678 if (attached_windows_.empty()) | 692 if (attached_windows_.empty()) |
| 679 return; | 693 return; |
| 680 | 694 |
| 681 if (details_.window_component == HTRIGHT) { | 695 if (details_.window_component == HTRIGHT) { |
| 682 bounds->set_width(std::min(bounds->width(), | 696 bounds->set_width(std::min(bounds->width(), |
| 683 work_area.right() - total_min_ - bounds->x())); | 697 work_area.right() - total_min_ - bounds->x())); |
| 684 } else { | 698 } else { |
| 685 DCHECK_EQ(HTBOTTOM, details_.window_component); | 699 DCHECK_EQ(HTBOTTOM, details_.window_component); |
| 686 bounds->set_height(std::min(bounds->height(), | 700 bounds->set_height(std::min(bounds->height(), |
| 687 work_area.bottom() - total_min_ - bounds->y())); | 701 work_area.bottom() - total_min_ - bounds->y())); |
| 688 } | 702 } |
| 689 } | 703 } |
| 690 | 704 |
| 691 void WorkspaceWindowResizer::SnapToWorkAreaEdges( | 705 void WorkspaceWindowResizer::StickToWorkAreaEdges( |
| 692 const gfx::Rect& work_area, | 706 const gfx::Rect& work_area, |
| 693 int snap_size, | 707 int sticky_size, |
| 694 gfx::Rect* bounds) const { | 708 gfx::Rect* bounds) const { |
| 695 const int left_edge = work_area.x(); | 709 const int left_edge = work_area.x(); |
| 696 const int right_edge = work_area.right(); | 710 const int right_edge = work_area.right(); |
| 697 const int top_edge = work_area.y(); | 711 const int top_edge = work_area.y(); |
| 698 const int bottom_edge = work_area.bottom(); | 712 const int bottom_edge = work_area.bottom(); |
| 699 if (ShouldSnapToEdge(bounds->x() - left_edge, snap_size)) { | 713 if (ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) { |
| 700 bounds->set_x(left_edge); | 714 bounds->set_x(left_edge); |
| 701 } else if (ShouldSnapToEdge(right_edge - bounds->right(), | 715 } else if (ShouldStickToEdge(right_edge - bounds->right(), sticky_size)) { |
| 702 snap_size)) { | |
| 703 bounds->set_x(right_edge - bounds->width()); | 716 bounds->set_x(right_edge - bounds->width()); |
| 704 } | 717 } |
| 705 if (ShouldSnapToEdge(bounds->y() - top_edge, snap_size)) { | 718 if (ShouldStickToEdge(bounds->y() - top_edge, sticky_size)) { |
| 706 bounds->set_y(top_edge); | 719 bounds->set_y(top_edge); |
| 707 } else if (ShouldSnapToEdge(bottom_edge - bounds->bottom(), snap_size) && | 720 } else if (ShouldStickToEdge(bottom_edge - bounds->bottom(), sticky_size) && |
| 708 bounds->height() < (bottom_edge - top_edge)) { | 721 bounds->height() < (bottom_edge - top_edge)) { |
| 709 // Only snap to the bottom if the window is smaller than the work area. | 722 // Only snap to the bottom if the window is smaller than the work area. |
| 710 // Doing otherwise can lead to window snapping in weird ways as it bounces | 723 // Doing otherwise can lead to window snapping in weird ways as it bounces |
| 711 // between snapping to top then bottom. | 724 // between snapping to top then bottom. |
| 712 bounds->set_y(bottom_edge - bounds->height()); | 725 bounds->set_y(bottom_edge - bounds->height()); |
| 713 } | 726 } |
| 714 } | 727 } |
| 715 | 728 |
| 716 void WorkspaceWindowResizer::SnapResizeToWorkAreaBounds( | 729 void WorkspaceWindowResizer::StickyResizeToWorkAreaBounds( |
| 717 const gfx::Rect& work_area, | 730 const gfx::Rect& work_area, |
| 718 int snap_size, | 731 int sticky_size, |
| 719 gfx::Rect* bounds) const { | 732 gfx::Rect* bounds) const { |
| 720 const uint32 edges = WindowComponentToMagneticEdge(details_.window_component); | 733 const uint32 edges = WindowComponentToMagneticEdge(details_.window_component); |
| 721 const int left_edge = work_area.x(); | 734 const int left_edge = work_area.x(); |
| 722 const int right_edge = work_area.right(); | 735 const int right_edge = work_area.right(); |
| 723 const int top_edge = work_area.y(); | 736 const int top_edge = work_area.y(); |
| 724 const int bottom_edge = work_area.bottom(); | 737 const int bottom_edge = work_area.bottom(); |
| 725 if (edges & MAGNETISM_EDGE_TOP && | 738 if (edges & MAGNETISM_EDGE_TOP && |
| 726 ShouldSnapToEdge(bounds->y() - top_edge, snap_size)) { | 739 ShouldStickToEdge(bounds->y() - top_edge, sticky_size)) { |
| 727 bounds->set_height(bounds->bottom() - top_edge); | 740 bounds->set_height(bounds->bottom() - top_edge); |
| 728 bounds->set_y(top_edge); | 741 bounds->set_y(top_edge); |
| 729 } | 742 } |
| 730 if (edges & MAGNETISM_EDGE_LEFT && | 743 if (edges & MAGNETISM_EDGE_LEFT && |
| 731 ShouldSnapToEdge(bounds->x() - left_edge, snap_size)) { | 744 ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) { |
| 732 bounds->set_width(bounds->right() - left_edge); | 745 bounds->set_width(bounds->right() - left_edge); |
| 733 bounds->set_x(left_edge); | 746 bounds->set_x(left_edge); |
| 734 } | 747 } |
| 735 if (edges & MAGNETISM_EDGE_BOTTOM && | 748 if (edges & MAGNETISM_EDGE_BOTTOM && |
| 736 ShouldSnapToEdge(bottom_edge - bounds->bottom(), snap_size)) { | 749 ShouldStickToEdge(bottom_edge - bounds->bottom(), sticky_size)) { |
| 737 bounds->set_height(bottom_edge - bounds->y()); | 750 bounds->set_height(bottom_edge - bounds->y()); |
| 738 } | 751 } |
| 739 if (edges & MAGNETISM_EDGE_RIGHT && | 752 if (edges & MAGNETISM_EDGE_RIGHT && |
| 740 ShouldSnapToEdge(right_edge - bounds->right(), snap_size)) { | 753 ShouldStickToEdge(right_edge - bounds->right(), sticky_size)) { |
| 741 bounds->set_width(right_edge - bounds->x()); | 754 bounds->set_width(right_edge - bounds->x()); |
| 742 } | 755 } |
| 743 } | 756 } |
| 744 | 757 |
| 745 int WorkspaceWindowResizer::PrimaryAxisSize(const gfx::Size& size) const { | 758 int WorkspaceWindowResizer::PrimaryAxisSize(const gfx::Size& size) const { |
| 746 return PrimaryAxisCoordinate(size.width(), size.height()); | 759 return PrimaryAxisCoordinate(size.width(), size.height()); |
| 747 } | 760 } |
| 748 | 761 |
| 749 int WorkspaceWindowResizer::PrimaryAxisCoordinate(int x, int y) const { | 762 int WorkspaceWindowResizer::PrimaryAxisCoordinate(int x, int y) const { |
| 750 switch (details_.window_component) { | 763 switch (details_.window_component) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 830 gfx::Rect area(ScreenAsh::GetDisplayBoundsInParent(window())); | 843 gfx::Rect area(ScreenAsh::GetDisplayBoundsInParent(window())); |
| 831 if (location.x() <= area.x()) | 844 if (location.x() <= area.x()) |
| 832 return SNAP_LEFT_EDGE; | 845 return SNAP_LEFT_EDGE; |
| 833 if (location.x() >= area.right() - 1) | 846 if (location.x() >= area.right() - 1) |
| 834 return SNAP_RIGHT_EDGE; | 847 return SNAP_RIGHT_EDGE; |
| 835 return SNAP_NONE; | 848 return SNAP_NONE; |
| 836 } | 849 } |
| 837 | 850 |
| 838 } // namespace internal | 851 } // namespace internal |
| 839 } // namespace ash | 852 } // namespace ash |
| OLD | NEW |