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/snap_sizer.h" | 5 #include "ash/wm/workspace/snap_sizer.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "ash/ash_switches.h" | |
10 #include "ash/launcher/launcher.h" | |
9 #include "ash/screen_ash.h" | 11 #include "ash/screen_ash.h" |
12 #include "ash/shell.h" | |
13 #include "ash/shell_window_ids.h" | |
14 #include "ash/wm/dock/docked_window_layout_manager.h" | |
10 #include "ash/wm/property_util.h" | 15 #include "ash/wm/property_util.h" |
16 #include "ash/wm/window_properties.h" | |
11 #include "ash/wm/window_resizer.h" | 17 #include "ash/wm/window_resizer.h" |
12 #include "ash/wm/window_util.h" | 18 #include "ash/wm/window_util.h" |
19 #include "base/command_line.h" | |
13 #include "ui/aura/window.h" | 20 #include "ui/aura/window.h" |
14 #include "ui/gfx/screen.h" | 21 #include "ui/gfx/screen.h" |
15 | 22 |
16 namespace ash { | 23 namespace ash { |
17 namespace internal { | 24 namespace internal { |
18 | 25 |
19 namespace { | 26 namespace { |
20 | 27 |
21 // A list of ideal window width in pixel which will be used to populate the | 28 // A list of ideal window width in pixel which will be used to populate the |
22 // |usable_width_| list. | 29 // |usable_width_| list. |
23 const int kIdealWidth[] = { 1280, 1024, 768, 640 }; | 30 const int kIdealWidth[] = { 1280, 1024, 768, 640 }; |
24 | 31 |
25 // Windows are initially snapped to the size in |usable_width_| at index 0. | 32 // Windows are initially snapped to the size in |usable_width_| at index 0. |
26 // The index into |usable_width_| is changed if any of the following happen: | 33 // The index into |usable_width_| is changed if any of the following happen: |
27 // . The user stops moving the mouse for |kDelayBeforeIncreaseMS| and then | 34 // . The user stops moving the mouse for |kDelayBeforeIncreaseMS| and then |
28 // moves the mouse again. | 35 // moves the mouse again. |
29 // . The mouse moves |kPixelsBeforeAdjust| horizontal pixels. | 36 // . The mouse moves |kPixelsBeforeAdjust| horizontal pixels. |
30 // . The mouse is against the edge of the screen and the mouse is moved | 37 // . The mouse is against the edge of the screen and the mouse is moved |
31 // |kMovesBeforeAdjust| times. | 38 // |kMovesBeforeAdjust| times. |
32 const int kDelayBeforeIncreaseMS = 500; | 39 const int kDelayBeforeIncreaseMS = 500; |
33 const int kMovesBeforeAdjust = 25; | 40 const int kMovesBeforeAdjust = 25; |
34 const int kPixelsBeforeAdjust = 100; | 41 const int kPixelsBeforeAdjust = 100; |
35 | 42 |
36 // When the smallest resolution does not fit on the screen, we take this | 43 // When the smallest resolution does not fit on the screen, we take this |
37 // fraction of the available space. | 44 // fraction of the available space. |
38 const int kMinimumScreenPercent = 90; | 45 const int kMinimumScreenPercent = 90; |
39 | 46 |
40 // Create the list of possible width for the current screen configuration: | 47 // Create the list of possible width for the current screen configuration: |
41 // Fill the |usable_width_| list with items from |kIdealWidth| which fit on | 48 // Fill the |usable_width_| list with items from |kIdealWidth| which fit on |
flackr
2013/09/06 02:18:43
Looks like an out of date comment, this returns th
varkha
2013/09/09 15:38:42
Done.
| |
42 // the screen and supplement it with the 'half of screen' size. Furthermore, | 49 // the screen and supplement it with the 'half of screen' size. Furthermore, |
43 // add an entry for 90% of the screen size if it is smaller then the biggest | 50 // add an entry for 90% of the screen size if it is smaller then the biggest |
44 // value in the |kIdealWidth| list (to get a step between the values). | 51 // value in the |kIdealWidth| list (to get a step between the values). |
flackr
2013/09/06 02:18:43
Comment |allow_max| and |allow_dock|.
varkha
2013/09/09 15:38:42
Done.
| |
45 std::vector<int> BuildIdealWidthList(aura::Window* window) { | 52 std::vector<int> BuildIdealWidthList(aura::Window* window, |
53 bool allow_max, | |
54 bool allow_dock) { | |
46 std::vector<int> ideal_width_list; | 55 std::vector<int> ideal_width_list; |
47 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window)); | 56 if (allow_max) { |
48 int half_size = work_area.width() / 2; | 57 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window)); |
49 int maximum_width = (kMinimumScreenPercent * work_area.width()) / 100; | 58 int half_size = work_area.width() / 2; |
50 for (size_t i = 0; i < arraysize(kIdealWidth); i++) { | 59 int maximum_width = (kMinimumScreenPercent * work_area.width()) / 100; |
51 if (maximum_width >= kIdealWidth[i]) { | 60 for (size_t i = 0; i < arraysize(kIdealWidth); i++) { |
52 if (i && !ideal_width_list.size() && maximum_width != kIdealWidth[i]) | 61 if (maximum_width >= kIdealWidth[i]) { |
53 ideal_width_list.push_back(maximum_width); | 62 if (i && !ideal_width_list.size() && maximum_width != kIdealWidth[i]) |
54 if (half_size > kIdealWidth[i]) | 63 ideal_width_list.push_back(maximum_width); |
55 ideal_width_list.push_back(half_size); | 64 if (half_size > kIdealWidth[i]) |
56 if (half_size >= kIdealWidth[i]) | 65 ideal_width_list.push_back(half_size); |
57 half_size = 0; | 66 if (half_size >= kIdealWidth[i]) |
58 ideal_width_list.push_back(kIdealWidth[i]); | 67 half_size = 0; |
68 ideal_width_list.push_back(kIdealWidth[i]); | |
69 } | |
59 } | 70 } |
71 if (half_size) | |
72 ideal_width_list.push_back(half_size); | |
60 } | 73 } |
61 if (half_size) | 74 // if (allow_max) { |
62 ideal_width_list.push_back(half_size); | 75 // gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window)); |
76 // ideal_width_list.push_back(work_area.width() / 2); | |
77 // } | |
flackr
2013/09/06 02:18:43
Remove commented code.
varkha
2013/09/09 15:38:42
Done.
| |
78 | |
79 if (allow_dock) | |
80 ideal_width_list.push_back(0); | |
63 | 81 |
64 return ideal_width_list; | 82 return ideal_width_list; |
65 } | 83 } |
66 | 84 |
67 } // namespace | 85 } // namespace |
68 | 86 |
69 SnapSizer::SnapSizer(aura::Window* window, | 87 SnapSizer::SnapSizer(aura::Window* window, |
70 const gfx::Point& start, | 88 const gfx::Point& start, |
71 Edge edge, | 89 Edge edge, |
72 InputType input_type) | 90 InputType input_type) |
73 : window_(window), | 91 : window_(window), |
74 edge_(edge), | 92 edge_(edge), |
75 time_last_update_(base::TimeTicks::Now()), | 93 time_last_update_(base::TimeTicks::Now()), |
76 size_index_(0), | 94 size_index_(0), |
77 resize_disabled_(false), | 95 resize_disabled_(false), |
78 num_moves_since_adjust_(0), | 96 num_moves_since_adjust_(0), |
79 last_adjust_x_(start.x()), | 97 last_adjust_x_(start.x()), |
80 last_update_x_(start.x()), | 98 last_update_x_(start.x()), |
81 start_x_(start.x()), | 99 start_x_(start.x()), |
82 input_type_(input_type), | 100 input_type_(input_type) { |
83 usable_width_(BuildIdealWidthList(window)) { | 101 aura::Window* dock_container = Shell::GetContainer( |
102 window_->GetRootWindow(), kShellWindowId_DockedContainer); | |
103 dock_layout_ = static_cast<DockedWindowLayoutManager*>( | |
104 dock_container->layout_manager()); | |
105 bool allow_dock = | |
106 input_type_ == internal::SnapSizer::WORKSPACE_DRAG_INPUT && | |
107 CanDockWindow(window_, edge_); | |
108 bool allow_snap = | |
109 !allow_dock || | |
flackr
2013/09/06 02:18:43
nit: Move up to previous line.
varkha
2013/09/09 15:38:42
Done.
| |
110 (wm::CanSnapWindow(window_) && | |
111 !dock_layout_->is_dragged_window_docked() && | |
112 window->bounds().width() > DockedWindowLayoutManager::kMaxDockWidth && | |
113 (window_->type() != aura::client::WINDOW_TYPE_PANEL)); | |
114 usable_width_ = BuildIdealWidthList(window, allow_snap, allow_dock); | |
flackr
2013/09/06 02:18:43
In BuildIdealWidthList, you call allow_snap allox_
varkha
2013/09/09 15:38:42
Done (renamed allow_max -> allow_snap for consiste
| |
84 DCHECK(!usable_width_.empty()); | 115 DCHECK(!usable_width_.empty()); |
116 UpdateDockedState(); | |
85 target_bounds_ = GetTargetBounds(); | 117 target_bounds_ = GetTargetBounds(); |
86 } | 118 } |
87 | 119 |
88 SnapSizer::~SnapSizer() { | 120 SnapSizer::~SnapSizer() { |
121 if (dock_layout_->is_dragged_window_docked()) | |
122 dock_layout_->UndockDraggedWindow(); | |
89 } | 123 } |
90 | 124 |
91 void SnapSizer::SnapWindow(aura::Window* window, SnapSizer::Edge edge) { | 125 void SnapSizer::SnapWindow(aura::Window* window, SnapSizer::Edge edge) { |
92 if (!wm::CanSnapWindow(window)) | 126 if (!wm::CanSnapWindow(window)) |
93 return; | 127 return; |
94 internal::SnapSizer sizer(window, gfx::Point(), edge, | 128 internal::SnapSizer sizer(window, gfx::Point(), edge, |
95 internal::SnapSizer::OTHER_INPUT); | 129 internal::SnapSizer::OTHER_INPUT); |
96 if (wm::IsWindowFullscreen(window) || wm::IsWindowMaximized(window)) { | 130 if (wm::IsWindowFullscreen(window) || wm::IsWindowMaximized(window)) { |
97 // Before we can set the bounds we need to restore the window. | 131 // Before we can set the bounds we need to restore the window. |
98 // Restoring the window will set the window to its restored bounds. | 132 // Restoring the window will set the window to its restored bounds. |
99 // To avoid an unnecessary bounds changes (which may have side effects) | 133 // To avoid an unnecessary bounds changes (which may have side effects) |
100 // we set the restore bounds to the bounds we want, restore the window, | 134 // we set the restore bounds to the bounds we want, restore the window, |
101 // then reset the restore bounds. This way no unnecessary bounds | 135 // then reset the restore bounds. This way no unnecessary bounds |
102 // changes occurs and the original restore bounds is remembered. | 136 // changes occurs and the original restore bounds is remembered. |
103 gfx::Rect restore = *GetRestoreBoundsInScreen(window); | 137 gfx::Rect restore = *GetRestoreBoundsInScreen(window); |
104 SetRestoreBoundsInParent(window, sizer.GetSnapBounds(window->bounds())); | 138 SetRestoreBoundsInParent(window, sizer.GetSnapBounds(window->bounds())); |
105 wm::RestoreWindow(window); | 139 wm::RestoreWindow(window); |
106 SetRestoreBoundsInScreen(window, restore); | 140 SetRestoreBoundsInScreen(window, restore); |
107 } else { | 141 } else { |
108 window->SetBounds(sizer.GetSnapBounds(window->bounds())); | 142 window->SetBounds(sizer.GetSnapBounds(window->bounds())); |
109 } | 143 } |
110 } | 144 } |
111 | 145 |
112 void SnapSizer::Update(const gfx::Point& location) { | 146 void SnapSizer::Update(const gfx::Point& location) { |
147 LOG(INFO) << "Update to " << location.ToString(); | |
148 | |
113 // See description above for details on this behavior. | 149 // See description above for details on this behavior. |
114 num_moves_since_adjust_++; | 150 num_moves_since_adjust_++; |
115 if ((base::TimeTicks::Now() - time_last_update_).InMilliseconds() > | 151 if ((base::TimeTicks::Now() - time_last_update_).InMilliseconds() > |
116 kDelayBeforeIncreaseMS) { | 152 kDelayBeforeIncreaseMS) { |
117 ChangeBounds(location.x(), | 153 ChangeBounds(location.x(), |
118 CalculateIncrement(location.x(), last_update_x_)); | 154 CalculateIncrement(location.x(), last_update_x_)); |
119 } else { | 155 } else { |
120 bool along_edge = AlongEdge(location.x()); | 156 bool along_edge = AlongEdge(location.x()); |
121 int pixels_before_adjust = kPixelsBeforeAdjust; | 157 int pixels_before_adjust = kPixelsBeforeAdjust; |
122 if (input_type_ == TOUCH_MAXIMIZE_BUTTON_INPUT) { | 158 if (input_type_ == TOUCH_MAXIMIZE_BUTTON_INPUT) { |
123 const gfx::Rect& workspace_bounds = window_->parent()->bounds(); | 159 const gfx::Rect& workspace_bounds = window_->parent()->bounds(); |
124 if (start_x_ > location.x()) { | 160 if (start_x_ > location.x()) { |
125 pixels_before_adjust = | 161 pixels_before_adjust = |
126 std::min(pixels_before_adjust, start_x_ / 10); | 162 std::min(pixels_before_adjust, start_x_ / 10); |
127 } else { | 163 } else { |
128 pixels_before_adjust = | 164 pixels_before_adjust = |
129 std::min(pixels_before_adjust, | 165 std::min(pixels_before_adjust, |
130 (workspace_bounds.width() - start_x_) / 10); | 166 (workspace_bounds.width() - start_x_) / 10); |
131 } | 167 } |
132 } | 168 } |
133 if (std::abs(location.x() - last_adjust_x_) >= pixels_before_adjust || | 169 if (std::abs(location.x() - last_adjust_x_) >= pixels_before_adjust || |
134 (along_edge && num_moves_since_adjust_ >= kMovesBeforeAdjust)) { | 170 (along_edge && num_moves_since_adjust_ >= kMovesBeforeAdjust)) { |
135 ChangeBounds(location.x(), | 171 ChangeBounds(location.x(), |
136 CalculateIncrement(location.x(), last_adjust_x_)); | 172 CalculateIncrement(location.x(), last_adjust_x_)); |
137 } | 173 } |
138 } | 174 } |
175 UpdateDockedState(); | |
139 last_update_x_ = location.x(); | 176 last_update_x_ = location.x(); |
140 time_last_update_ = base::TimeTicks::Now(); | 177 time_last_update_ = base::TimeTicks::Now(); |
141 } | 178 } |
142 | 179 |
143 gfx::Rect SnapSizer::GetSnapBounds(const gfx::Rect& bounds) { | 180 gfx::Rect SnapSizer::GetSnapBounds(const gfx::Rect& bounds) { |
144 int current = 0; | 181 int current = 0; |
145 if (!resize_disabled_) { | 182 if (!resize_disabled_) { |
146 for (current = usable_width_.size() - 1; current >= 0; current--) { | 183 for (current = usable_width_.size() - 1; current >= 0; current--) { |
147 gfx::Rect target = GetTargetBoundsForSize(current); | 184 gfx::Rect target = GetTargetBoundsForSize(current); |
148 if (target == bounds) { | 185 if (target == bounds) { |
149 ++current; | 186 ++current; |
150 break; | 187 break; |
151 } | 188 } |
152 } | 189 } |
153 } | 190 } |
154 return GetTargetBoundsForSize(current % usable_width_.size()); | 191 return GetTargetBoundsForSize(current % usable_width_.size()); |
155 } | 192 } |
156 | 193 |
157 void SnapSizer::SelectDefaultSizeAndDisableResize() { | 194 void SnapSizer::SelectDefaultSizeAndDisableResize() { |
158 resize_disabled_ = true; | 195 resize_disabled_ = true; |
159 size_index_ = 0; | 196 size_index_ = 0; |
197 UpdateDockedState(); | |
160 target_bounds_ = GetTargetBounds(); | 198 target_bounds_ = GetTargetBounds(); |
161 } | 199 } |
162 | 200 |
163 gfx::Rect SnapSizer::GetTargetBoundsForSize(size_t size_index) const { | 201 gfx::Rect SnapSizer::GetTargetBoundsForSize(size_t size_index) const { |
164 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_)); | 202 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_)); |
165 int y = work_area.y(); | 203 int y = work_area.y(); |
166 // We don't align to the bottom of the grid as the launcher may not | 204 // We don't align to the bottom of the grid as the launcher may not |
167 // necessarily align to the grid (happens when auto-hidden). | 205 // necessarily align to the grid (happens when auto-hidden). |
168 int max_y = work_area.bottom(); | 206 int max_y = work_area.bottom(); |
169 int width = 0; | 207 int width = 0; |
170 if (resize_disabled_) { | 208 if (resize_disabled_) { |
171 // Make sure that we keep the size of the window smaller then a certain | 209 // Make sure that we keep the size of the window smaller then a certain |
172 // fraction of the screen space. | 210 // fraction of the screen space. |
173 int minimum_size = (kMinimumScreenPercent * work_area.width()) / 100; | 211 int minimum_size = (kMinimumScreenPercent * work_area.width()) / 100; |
174 width = std::max(std::min(minimum_size, 1024), work_area.width() / 2); | 212 width = std::max(std::min(minimum_size, 1024), work_area.width() / 2); |
175 } else { | 213 } else { |
176 DCHECK(size_index < usable_width_.size()); | 214 DCHECK(size_index < usable_width_.size()); |
177 width = usable_width_[size_index]; | 215 width = usable_width_[size_index]; |
178 } | 216 } |
179 | 217 |
218 if (width == 0) { | |
219 LOG(INFO) << "snap bounds " << dock_layout_->dragged_bounds().ToString(); | |
220 return ScreenAsh::ConvertRectFromScreen(window_->parent(), | |
221 dock_layout_->dragged_bounds()); | |
222 } | |
223 | |
180 if (edge_ == LEFT_EDGE) { | 224 if (edge_ == LEFT_EDGE) { |
181 int x = work_area.x(); | 225 int x = work_area.x(); |
182 int mid_x = x + width; | 226 int mid_x = x + width; |
183 return gfx::Rect(x, y, mid_x - x, max_y - y); | 227 return gfx::Rect(x, y, mid_x - x, max_y - y); |
184 } | 228 } |
185 int max_x = work_area.right(); | 229 int max_x = work_area.right(); |
186 int x = max_x - width; | 230 int x = max_x - width; |
187 return gfx::Rect(x , y, max_x - x, max_y - y); | 231 return gfx::Rect(x , y, max_x - x, max_y - y); |
188 } | 232 } |
189 | 233 |
234 bool SnapSizer::ShouldDockWindow() const { | |
235 if (!CanDockWindow(window_, edge_)) | |
flackr
2013/09/06 02:18:43
If !CanDockWindow, 0 shouldn't be in the list of u
varkha
2013/09/09 15:38:42
Done.
| |
236 return false; | |
237 // Avoid returning true when the last step is not docking. | |
flackr
2013/09/06 02:18:43
This comment is confusing. The last step is the on
varkha
2013/09/09 15:38:42
More to do with how this code was modified. This i
| |
238 // TODO(varkha): use dedicated state. | |
239 return (usable_width_[size_index_] == 0 && | |
240 size_index_ == static_cast<int>(usable_width_.size()) - 1); | |
flackr
2013/09/06 02:18:43
Shouldn't 0 always be the last element in usable_w
varkha
2013/09/09 15:38:42
Done.
| |
241 } | |
242 | |
243 // static | |
244 bool SnapSizer::CanDockWindow(aura::Window* window, SnapSizer::Edge edge) { | |
245 if (!CommandLine::ForCurrentProcess()->HasSwitch( | |
246 switches::kAshEnableDockedWindows)) { | |
247 return false; | |
248 } | |
249 // Cannot dock on the other size from an existing dock. | |
250 aura::Window* dock_container = Shell::GetContainer( | |
251 window->GetRootWindow(), kShellWindowId_DockedContainer); | |
252 DockedWindowLayoutManager* dock_layout = | |
253 static_cast<DockedWindowLayoutManager*>(dock_container->layout_manager()); | |
254 const DockedAlignment alignment = dock_layout->CalculateAlignment(); | |
255 if ((edge == LEFT_EDGE && alignment == DOCKED_ALIGNMENT_RIGHT) || | |
256 (edge == RIGHT_EDGE && alignment == DOCKED_ALIGNMENT_LEFT)) { | |
257 return false; | |
258 } | |
259 | |
260 // Do not allow docking on the same side as launcher shelf. | |
261 Launcher* launcher = Launcher::ForWindow(window); | |
262 if (!launcher) | |
263 return true; | |
264 return (edge == LEFT_EDGE && launcher->alignment() != SHELF_ALIGNMENT_LEFT) || | |
265 (edge == RIGHT_EDGE && launcher->alignment() != SHELF_ALIGNMENT_RIGHT); | |
266 | |
267 } | |
268 | |
190 int SnapSizer::CalculateIncrement(int x, int reference_x) const { | 269 int SnapSizer::CalculateIncrement(int x, int reference_x) const { |
191 if (AlongEdge(x)) | 270 if (AlongEdge(x)) |
192 return 1; | 271 return 1; |
193 if (x == reference_x) | 272 if (x == reference_x) |
194 return 0; | 273 return 0; |
195 if (edge_ == LEFT_EDGE) { | 274 if (edge_ == LEFT_EDGE) { |
196 if (x < reference_x) | 275 if (x < reference_x) |
197 return 1; | 276 return 1; |
198 return -1; | 277 return -1; |
199 } | 278 } |
(...skipping 12 matching lines...) Expand all Loading... | |
212 } | 291 } |
213 num_moves_since_adjust_ = 0; | 292 num_moves_since_adjust_ = 0; |
214 last_adjust_x_ = x; | 293 last_adjust_x_ = x; |
215 } | 294 } |
216 | 295 |
217 gfx::Rect SnapSizer::GetTargetBounds() const { | 296 gfx::Rect SnapSizer::GetTargetBounds() const { |
218 return GetTargetBoundsForSize(size_index_); | 297 return GetTargetBoundsForSize(size_index_); |
219 } | 298 } |
220 | 299 |
221 bool SnapSizer::AlongEdge(int x) const { | 300 bool SnapSizer::AlongEdge(int x) const { |
222 gfx::Rect area(ScreenAsh::GetDisplayBoundsInParent(window_)); | 301 gfx::Rect area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_)); |
223 return (x <= area.x()) || (x >= area.right() - 1); | 302 return (x <= area.x()) || (x >= area.right() - 1); |
224 } | 303 } |
225 | 304 |
305 void SnapSizer::UpdateDockedState() { | |
306 if (ShouldDockWindow() && | |
307 dock_layout_->GetAlignmentOfWindow(window_) != DOCKED_ALIGNMENT_NONE) { | |
308 if (!dock_layout_->is_dragged_window_docked()) { | |
309 LOG(INFO) << "dock"; | |
310 dock_layout_->DockDraggedWindow(window_); | |
311 } | |
312 target_bounds_ = GetTargetBounds(); | |
313 } else { | |
314 if (dock_layout_->is_dragged_window_docked()) { | |
315 LOG(INFO) << "undock"; | |
316 dock_layout_->UndockDraggedWindow(); | |
317 } | |
318 } | |
319 } | |
320 | |
226 } // namespace internal | 321 } // namespace internal |
227 } // namespace ash | 322 } // namespace ash |
OLD | NEW |