Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(445)

Side by Side Diff: ash/wm/workspace/workspace_window_resizer.cc

Issue 14273008: Add ash-enable-sticky-edges for 'sticky' instead of 'snap' behavior. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698