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 | 9 |
10 #include "ash/display/display_controller.h" | 10 #include "ash/display/display_controller.h" |
11 #include "ash/display/mouse_cursor_event_filter.h" | 11 #include "ash/display/mouse_cursor_event_filter.h" |
12 #include "ash/screen_ash.h" | 12 #include "ash/screen_ash.h" |
13 #include "ash/shell.h" | 13 #include "ash/shell.h" |
14 #include "ash/wm/coordinate_conversion.h" | 14 #include "ash/wm/coordinate_conversion.h" |
15 #include "ash/wm/cursor_manager.h" | 15 #include "ash/wm/cursor_manager.h" |
16 #include "ash/wm/property_util.h" | 16 #include "ash/wm/property_util.h" |
17 #include "ash/wm/window_util.h" | 17 #include "ash/wm/window_util.h" |
18 #include "ash/wm/workspace/phantom_window_controller.h" | 18 #include "ash/wm/workspace/phantom_window_controller.h" |
19 #include "ash/wm/workspace/snap_sizer.h" | 19 #include "ash/wm/workspace/snap_sizer.h" |
20 #include "ui/aura/client/aura_constants.h" | 20 #include "ui/aura/client/aura_constants.h" |
21 #include "ui/aura/root_window.h" | 21 #include "ui/aura/root_window.h" |
22 #include "ui/aura/window.h" | 22 #include "ui/aura/window.h" |
23 #include "ui/aura/window_delegate.h" | 23 #include "ui/aura/window_delegate.h" |
24 #include "ui/base/hit_test.h" | 24 #include "ui/base/hit_test.h" |
25 #include "ui/compositor/layer.h" | 25 #include "ui/compositor/layer.h" |
26 #include "ui/compositor/scoped_layer_animation_settings.h" | |
27 #include "ui/gfx/screen.h" | 26 #include "ui/gfx/screen.h" |
28 #include "ui/gfx/transform.h" | 27 #include "ui/gfx/transform.h" |
29 | 28 |
30 namespace ash { | 29 namespace ash { |
31 namespace internal { | 30 namespace internal { |
32 | 31 |
33 namespace { | 32 namespace { |
34 | 33 |
35 // Duration of the animation when snapping the window into place. | 34 // Duration of the animation when snapping the window into place. |
36 const int kSnapDurationMS = 100; | 35 const int kSnapDurationMS = 100; |
37 | 36 |
38 // The maximum opacity of the drag phantom window. | 37 // The maximum opacity of the drag phantom window. |
39 const float kMaxOpacity = 0.8f; | 38 const float kMaxOpacity = 0.8f; |
40 | 39 |
41 // Returns true if should snap to the edge. | 40 // Returns true if should snap to the edge. |
42 bool ShouldSnapToEdge(int distance_from_edge, int grid_size) { | 41 bool ShouldSnapToEdge(int distance_from_edge, int grid_size) { |
43 return distance_from_edge <= grid_size / 2 && | 42 return distance_from_edge < grid_size && |
44 distance_from_edge > -grid_size * 2; | 43 distance_from_edge > -grid_size * 2; |
45 } | 44 } |
46 | 45 |
47 // Returns true if Ash has more than one root window. | 46 // Returns true if Ash has more than one root window. |
48 bool HasSecondaryRootWindow() { | 47 bool HasSecondaryRootWindow() { |
49 return Shell::GetAllRootWindows().size() > 1; | 48 return Shell::GetAllRootWindows().size() > 1; |
50 } | 49 } |
51 | 50 |
52 // When there are two root windows, returns one of the root windows which is not | 51 // When there are two root windows, returns one of the root windows which is not |
53 // |root_window|. Returns NULL if only one root window exists. | 52 // |root_window|. Returns NULL if only one root window exists. |
54 aura::RootWindow* GetAnotherRootWindow(aura::RootWindow* root_window) { | 53 aura::RootWindow* GetAnotherRootWindow(aura::RootWindow* root_window) { |
55 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); | 54 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); |
56 if (root_windows.size() < 2) | 55 if (root_windows.size() < 2) |
57 return NULL; | 56 return NULL; |
58 DCHECK_EQ(2U, root_windows.size()); | 57 DCHECK_EQ(2U, root_windows.size()); |
59 if (root_windows[0] == root_window) | 58 if (root_windows[0] == root_window) |
60 return root_windows[1]; | 59 return root_windows[1]; |
61 return root_windows[0]; | 60 return root_windows[0]; |
62 } | 61 } |
63 | 62 |
64 } // namespace | 63 } // namespace |
65 | 64 |
66 // static | 65 // static |
67 const int WorkspaceWindowResizer::kMinOnscreenSize = 20; | 66 const int WorkspaceWindowResizer::kMinOnscreenSize = 20; |
68 | 67 |
69 // static | 68 // static |
70 const int WorkspaceWindowResizer::kMinOnscreenHeight = 32; | 69 const int WorkspaceWindowResizer::kMinOnscreenHeight = 32; |
71 | 70 |
| 71 // static |
| 72 const int WorkspaceWindowResizer::kScreenEdgeInset = 8; |
| 73 |
72 WorkspaceWindowResizer::~WorkspaceWindowResizer() { | 74 WorkspaceWindowResizer::~WorkspaceWindowResizer() { |
73 Shell* shell = Shell::GetInstance(); | 75 Shell* shell = Shell::GetInstance(); |
74 shell->mouse_cursor_filter()->set_mouse_warp_mode( | 76 shell->mouse_cursor_filter()->set_mouse_warp_mode( |
75 MouseCursorEventFilter::WARP_ALWAYS); | 77 MouseCursorEventFilter::WARP_ALWAYS); |
76 shell->mouse_cursor_filter()->HideSharedEdgeIndicator(); | 78 shell->mouse_cursor_filter()->HideSharedEdgeIndicator(); |
77 shell->cursor_manager()->UnlockCursor(); | 79 shell->cursor_manager()->UnlockCursor(); |
78 | 80 |
79 // Delete phantom controllers first so that they will never see the deleted | 81 // Delete phantom controllers first so that they will never see the deleted |
80 // |layer_|. | 82 // |layer_|. |
81 snap_phantom_window_controller_.reset(); | 83 snap_phantom_window_controller_.reset(); |
(...skipping 27 matching lines...) Expand all Loading... |
109 &location_in_parent); | 111 &location_in_parent); |
110 last_mouse_location_ = location_in_parent; | 112 last_mouse_location_ = location_in_parent; |
111 | 113 |
112 // Do not use |location| below this point, use |location_in_parent| instead. | 114 // Do not use |location| below this point, use |location_in_parent| instead. |
113 // When the pointer is on |window()->GetRootWindow()|, |location| and | 115 // When the pointer is on |window()->GetRootWindow()|, |location| and |
114 // |location_in_parent| have the same value and both of them are in | 116 // |location_in_parent| have the same value and both of them are in |
115 // |window()->parent()|'s coordinates, but once the pointer enters the | 117 // |window()->parent()|'s coordinates, but once the pointer enters the |
116 // other root window, you will see an unexpected value on the former. See | 118 // other root window, you will see an unexpected value on the former. See |
117 // comments in wm::GetRootWindowRelativeToWindow() for details. | 119 // comments in wm::GetRootWindowRelativeToWindow() for details. |
118 | 120 |
119 int grid_size = event_flags & ui::EF_CONTROL_DOWN ? | 121 int grid_size = event_flags & ui::EF_CONTROL_DOWN ? 0 : kScreenEdgeInset; |
120 0 : ash::Shell::GetInstance()->GetGridSize(); | |
121 gfx::Rect bounds = // in |window()->parent()|'s coordinates. | 122 gfx::Rect bounds = // in |window()->parent()|'s coordinates. |
122 CalculateBoundsForDrag(details_, location_in_parent, grid_size); | 123 CalculateBoundsForDrag(details_, location_in_parent); |
123 | 124 |
124 if (wm::IsWindowNormal(window())) | 125 if (wm::IsWindowNormal(window())) |
125 AdjustBoundsForMainWindow(&bounds, grid_size); | 126 AdjustBoundsForMainWindow(&bounds, grid_size); |
126 if (bounds != window()->bounds()) { | 127 if (bounds != window()->bounds()) { |
127 if (!did_move_or_resize_) | 128 if (!did_move_or_resize_) |
128 RestackWindows(); | 129 RestackWindows(); |
129 did_move_or_resize_ = true; | 130 did_move_or_resize_ = true; |
130 } | 131 } |
131 | 132 |
132 const bool in_original_root = (window()->GetRootWindow() == current_root); | 133 const bool in_original_root = (window()->GetRootWindow() == current_root); |
133 // Hide a phantom window for snapping if the cursor is in another root window. | 134 // Hide a phantom window for snapping if the cursor is in another root window. |
134 if (in_original_root) | 135 if (in_original_root) |
135 UpdateSnapPhantomWindow(location_in_parent, bounds, grid_size); | 136 UpdateSnapPhantomWindow(location_in_parent, bounds); |
136 else | 137 else |
137 snap_phantom_window_controller_.reset(); | 138 snap_phantom_window_controller_.reset(); |
138 | 139 |
139 if (!attached_windows_.empty()) | 140 if (!attached_windows_.empty()) |
140 LayoutAttachedWindows(bounds, grid_size); | 141 LayoutAttachedWindows(bounds); |
141 if (bounds != window()->bounds()) { | 142 if (bounds != window()->bounds()) { |
142 bool destroyed = false; | 143 bool destroyed = false; |
143 destroyed_ = &destroyed; | 144 destroyed_ = &destroyed; |
144 window()->SetBounds(bounds); | 145 window()->SetBounds(bounds); |
145 if (destroyed) | 146 if (destroyed) |
146 return; | 147 return; |
147 destroyed_ = NULL; | 148 destroyed_ = NULL; |
148 } | 149 } |
149 // Show a phantom window for dragging in another root window. | 150 // Show a phantom window for dragging in another root window. |
150 if (HasSecondaryRootWindow()) | 151 if (HasSecondaryRootWindow()) |
(...skipping 10 matching lines...) Expand all Loading... |
161 if (!did_move_or_resize_ || details_.window_component != HTCAPTION) | 162 if (!did_move_or_resize_ || details_.window_component != HTCAPTION) |
162 return; | 163 return; |
163 | 164 |
164 if (snap_type_ == SNAP_LEFT_EDGE || snap_type_ == SNAP_RIGHT_EDGE) { | 165 if (snap_type_ == SNAP_LEFT_EDGE || snap_type_ == SNAP_RIGHT_EDGE) { |
165 if (!GetRestoreBoundsInScreen(window())) | 166 if (!GetRestoreBoundsInScreen(window())) |
166 SetRestoreBoundsInParent(window(), details_.initial_bounds); | 167 SetRestoreBoundsInParent(window(), details_.initial_bounds); |
167 window()->SetBounds(snap_sizer_->target_bounds()); | 168 window()->SetBounds(snap_sizer_->target_bounds()); |
168 return; | 169 return; |
169 } | 170 } |
170 | 171 |
171 int grid_size = event_flags & ui::EF_CONTROL_DOWN ? | 172 gfx::Rect bounds(GetFinalBounds(window()->bounds())); |
172 0 : ash::Shell::GetInstance()->GetGridSize(); | |
173 gfx::Rect bounds(GetFinalBounds(window()->bounds(), grid_size)); | |
174 | 173 |
175 // Check if the destination is another display. | 174 // Check if the destination is another display. |
176 gfx::Point last_mouse_location_in_screen = last_mouse_location_; | 175 gfx::Point last_mouse_location_in_screen = last_mouse_location_; |
177 wm::ConvertPointToScreen(window()->parent(), &last_mouse_location_in_screen); | 176 wm::ConvertPointToScreen(window()->parent(), &last_mouse_location_in_screen); |
178 const gfx::Display dst_display = | 177 const gfx::Display dst_display = |
179 gfx::Screen::GetDisplayNearestPoint(last_mouse_location_in_screen); | 178 gfx::Screen::GetDisplayNearestPoint(last_mouse_location_in_screen); |
180 | 179 |
181 if (dst_display.id() != | 180 if (dst_display.id() != |
182 gfx::Screen::GetDisplayNearestWindow(window()->GetRootWindow()).id()) { | 181 gfx::Screen::GetDisplayNearestWindow(window()->GetRootWindow()).id()) { |
183 // Don't animate when moving to another display. | 182 // Don't animate when moving to another display. |
184 const gfx::Rect dst_bounds = | 183 const gfx::Rect dst_bounds = |
185 ScreenAsh::ConvertRectToScreen(window()->parent(), bounds); | 184 ScreenAsh::ConvertRectToScreen(window()->parent(), bounds); |
186 window()->SetBoundsInScreen(dst_bounds, dst_display); | 185 window()->SetBoundsInScreen(dst_bounds, dst_display); |
187 return; | |
188 } | 186 } |
189 | |
190 if (grid_size <= 1 || bounds == window()->bounds()) | |
191 return; | |
192 | |
193 if (bounds.size() != window()->bounds().size()) { | |
194 // Don't attempt to animate a size change. | |
195 window()->SetBounds(bounds); | |
196 return; | |
197 } | |
198 | |
199 ui::ScopedLayerAnimationSettings scoped_setter( | |
200 window()->layer()->GetAnimator()); | |
201 // Use a small duration since the grid is small. | |
202 scoped_setter.SetTransitionDuration( | |
203 base::TimeDelta::FromMilliseconds(kSnapDurationMS)); | |
204 window()->SetBounds(bounds); | |
205 } | 187 } |
206 | 188 |
207 void WorkspaceWindowResizer::RevertDrag() { | 189 void WorkspaceWindowResizer::RevertDrag() { |
208 window()->layer()->SetOpacity(details_.initial_opacity); | 190 window()->layer()->SetOpacity(details_.initial_opacity); |
209 drag_phantom_window_controller_.reset(); | 191 drag_phantom_window_controller_.reset(); |
210 snap_phantom_window_controller_.reset(); | 192 snap_phantom_window_controller_.reset(); |
211 Shell::GetInstance()->mouse_cursor_filter()->HideSharedEdgeIndicator(); | 193 Shell::GetInstance()->mouse_cursor_filter()->HideSharedEdgeIndicator(); |
212 | 194 |
213 if (!did_move_or_resize_) | 195 if (!did_move_or_resize_) |
214 return; | 196 return; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 | 254 |
273 // Only support attaching to the right/bottom. | 255 // Only support attaching to the right/bottom. |
274 DCHECK(attached_windows_.empty() || | 256 DCHECK(attached_windows_.empty() || |
275 (details.window_component == HTRIGHT || | 257 (details.window_component == HTRIGHT || |
276 details.window_component == HTBOTTOM)); | 258 details.window_component == HTBOTTOM)); |
277 | 259 |
278 // TODO: figure out how to deal with window going off the edge. | 260 // TODO: figure out how to deal with window going off the edge. |
279 | 261 |
280 // Calculate sizes so that we can maintain the ratios if we need to resize. | 262 // Calculate sizes so that we can maintain the ratios if we need to resize. |
281 int total_available = 0; | 263 int total_available = 0; |
282 int grid_size = ash::Shell::GetInstance()->GetGridSize(); | |
283 for (size_t i = 0; i < attached_windows_.size(); ++i) { | 264 for (size_t i = 0; i < attached_windows_.size(); ++i) { |
284 gfx::Size min(attached_windows_[i]->delegate()->GetMinimumSize()); | 265 gfx::Size min(attached_windows_[i]->delegate()->GetMinimumSize()); |
285 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size()); | 266 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size()); |
286 initial_size_.push_back(initial_size); | 267 initial_size_.push_back(initial_size); |
287 // If current size is smaller than the min, use the current size as the min. | 268 // If current size is smaller than the min, use the current size as the min. |
288 // This way we don't snap on resize. | 269 // This way we don't snap on resize. |
289 int min_size = std::min(initial_size, | 270 int min_size = std::min(initial_size, |
290 std::max(PrimaryAxisSize(min), kMinOnscreenSize)); | 271 std::max(PrimaryAxisSize(min), kMinOnscreenSize)); |
291 // Make sure the min size falls on the grid. | |
292 if (grid_size > 1 && min_size % grid_size != 0) | |
293 min_size = (min_size / grid_size + 1) * grid_size; | |
294 min_size_.push_back(min_size); | 272 min_size_.push_back(min_size); |
295 total_min_ += min_size; | 273 total_min_ += min_size; |
296 total_initial_size_ += initial_size; | 274 total_initial_size_ += initial_size; |
297 total_available += std::max(min_size, initial_size) - min_size; | 275 total_available += std::max(min_size, initial_size) - min_size; |
298 } | 276 } |
299 | 277 |
300 for (size_t i = 0; i < attached_windows_.size(); ++i) { | 278 for (size_t i = 0; i < attached_windows_.size(); ++i) { |
301 expand_fraction_.push_back( | 279 expand_fraction_.push_back( |
302 static_cast<float>(initial_size_[i]) / | 280 static_cast<float>(initial_size_[i]) / |
303 static_cast<float>(total_initial_size_)); | 281 static_cast<float>(total_initial_size_)); |
304 if (total_initial_size_ != total_min_) { | 282 if (total_initial_size_ != total_min_) { |
305 compress_fraction_.push_back( | 283 compress_fraction_.push_back( |
306 static_cast<float>(initial_size_[i] - min_size_[i]) / | 284 static_cast<float>(initial_size_[i] - min_size_[i]) / |
307 static_cast<float>(total_available)); | 285 static_cast<float>(total_available)); |
308 } else { | 286 } else { |
309 compress_fraction_.push_back(0.0f); | 287 compress_fraction_.push_back(0.0f); |
310 } | 288 } |
311 } | 289 } |
312 } | 290 } |
313 | 291 |
314 gfx::Rect WorkspaceWindowResizer::GetFinalBounds( | 292 gfx::Rect WorkspaceWindowResizer::GetFinalBounds( |
315 const gfx::Rect& bounds, | 293 const gfx::Rect& bounds) const { |
316 int grid_size) const { | |
317 if (snap_phantom_window_controller_.get() && | 294 if (snap_phantom_window_controller_.get() && |
318 snap_phantom_window_controller_->IsShowing()) { | 295 snap_phantom_window_controller_->IsShowing()) { |
319 return snap_phantom_window_controller_->bounds(); | 296 return snap_phantom_window_controller_->bounds(); |
320 } | 297 } |
321 return AdjustBoundsToGrid(bounds, grid_size); | 298 return bounds; |
322 } | 299 } |
323 | 300 |
324 void WorkspaceWindowResizer::LayoutAttachedWindows( | 301 void WorkspaceWindowResizer::LayoutAttachedWindows( |
325 const gfx::Rect& bounds, | 302 const gfx::Rect& bounds) { |
326 int grid_size) { | |
327 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); | 303 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); |
328 std::vector<int> sizes; | 304 std::vector<int> sizes; |
329 CalculateAttachedSizes( | 305 CalculateAttachedSizes( |
330 PrimaryAxisSize(details_.initial_bounds.size()), | 306 PrimaryAxisSize(details_.initial_bounds.size()), |
331 PrimaryAxisSize(bounds.size()), | 307 PrimaryAxisSize(bounds.size()), |
332 PrimaryAxisCoordinate(bounds.right(), bounds.bottom()), | 308 PrimaryAxisCoordinate(bounds.right(), bounds.bottom()), |
333 PrimaryAxisCoordinate(work_area.right(), work_area.bottom()), | 309 PrimaryAxisCoordinate(work_area.right(), work_area.bottom()), |
334 grid_size, | |
335 &sizes); | 310 &sizes); |
336 DCHECK_EQ(attached_windows_.size(), sizes.size()); | 311 DCHECK_EQ(attached_windows_.size(), sizes.size()); |
337 int last = PrimaryAxisCoordinate(bounds.right(), bounds.bottom()); | 312 int last = PrimaryAxisCoordinate(bounds.right(), bounds.bottom()); |
338 for (size_t i = 0; i < attached_windows_.size(); ++i) { | 313 for (size_t i = 0; i < attached_windows_.size(); ++i) { |
339 gfx::Rect attached_bounds(attached_windows_[i]->bounds()); | 314 gfx::Rect attached_bounds(attached_windows_[i]->bounds()); |
340 if (details_.window_component == HTRIGHT) { | 315 if (details_.window_component == HTRIGHT) { |
341 attached_bounds.set_x(last); | 316 attached_bounds.set_x(last); |
342 attached_bounds.set_width(sizes[i]); | 317 attached_bounds.set_width(sizes[i]); |
343 } else { | 318 } else { |
344 attached_bounds.set_y(last); | 319 attached_bounds.set_y(last); |
345 attached_bounds.set_height(sizes[i]); | 320 attached_bounds.set_height(sizes[i]); |
346 } | 321 } |
347 attached_windows_[i]->SetBounds(attached_bounds); | 322 attached_windows_[i]->SetBounds(attached_bounds); |
348 last += sizes[i]; | 323 last += sizes[i]; |
349 } | 324 } |
350 } | 325 } |
351 | 326 |
352 void WorkspaceWindowResizer::CalculateAttachedSizes( | 327 void WorkspaceWindowResizer::CalculateAttachedSizes( |
353 int initial_size, | 328 int initial_size, |
354 int current_size, | 329 int current_size, |
355 int start, | 330 int start, |
356 int end, | 331 int end, |
357 int grid_size, | |
358 std::vector<int>* sizes) const { | 332 std::vector<int>* sizes) const { |
359 sizes->clear(); | 333 sizes->clear(); |
360 if (current_size < initial_size) { | 334 if (current_size < initial_size) { |
361 // If the primary window is sized smaller, resize the attached windows. | 335 // If the primary window is sized smaller, resize the attached windows. |
362 int current = start; | 336 int current = start; |
363 int delta = initial_size - current_size; | 337 int delta = initial_size - current_size; |
364 for (size_t i = 0; i < attached_windows_.size(); ++i) { | 338 for (size_t i = 0; i < attached_windows_.size(); ++i) { |
365 int next = AlignToGrid( | 339 int next = current + initial_size_[i] + expand_fraction_[i] * delta; |
366 current + initial_size_[i] + expand_fraction_[i] * delta, | 340 if (i + 1 == attached_windows_.size()) |
367 grid_size); | 341 next = start + total_initial_size_ + (initial_size - current_size); |
368 if (i == attached_windows_.size()) | |
369 next = end; | |
370 sizes->push_back(next - current); | 342 sizes->push_back(next - current); |
371 current = next; | 343 current = next; |
372 } | 344 } |
373 } else if (start <= end - total_initial_size_) { | 345 } else if (start <= end - total_initial_size_) { |
374 // All the windows fit at their initial size; tile them horizontally. | 346 // All the windows fit at their initial size; tile them horizontally. |
375 for (size_t i = 0; i < attached_windows_.size(); ++i) | 347 for (size_t i = 0; i < attached_windows_.size(); ++i) |
376 sizes->push_back(initial_size_[i]); | 348 sizes->push_back(initial_size_[i]); |
377 } else { | 349 } else { |
378 DCHECK_NE(total_initial_size_, total_min_); | 350 DCHECK_NE(total_initial_size_, total_min_); |
379 int delta = total_initial_size_ - (end - start); | 351 int delta = total_initial_size_ - (end - start); |
380 int current = start; | 352 int current = start; |
381 for (size_t i = 0; i < attached_windows_.size(); ++i) { | 353 for (size_t i = 0; i < attached_windows_.size(); ++i) { |
382 int size = initial_size_[i] - | 354 int size = initial_size_[i] - |
383 static_cast<int>(compress_fraction_[i] * delta); | 355 static_cast<int>(compress_fraction_[i] * delta); |
384 size = AlignToGrid(size, grid_size); | 356 if (i + 1 == attached_windows_.size()) |
385 if (i == attached_windows_.size()) | |
386 size = end - current; | 357 size = end - current; |
387 current += size; | 358 current += size; |
388 sizes->push_back(size); | 359 sizes->push_back(size); |
389 } | 360 } |
390 } | 361 } |
391 } | 362 } |
392 | 363 |
393 void WorkspaceWindowResizer::AdjustBoundsForMainWindow( | 364 void WorkspaceWindowResizer::AdjustBoundsForMainWindow( |
394 gfx::Rect* bounds, int grid_size) const { | 365 gfx::Rect* bounds, |
| 366 int grid_size) const { |
395 // Always keep kMinOnscreenHeight on the bottom except when an extended | 367 // Always keep kMinOnscreenHeight on the bottom except when an extended |
396 // display is available and a window is being dragged. | 368 // display is available and a window is being dragged. |
397 gfx::Rect work_area( | 369 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); |
398 ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); | 370 int max_y = work_area.bottom() - kMinOnscreenHeight; |
399 int max_y = AlignToGridRoundUp(work_area.bottom() - kMinOnscreenHeight, | |
400 grid_size); | |
401 if ((details_.window_component != HTCAPTION || !HasSecondaryRootWindow()) && | 371 if ((details_.window_component != HTCAPTION || !HasSecondaryRootWindow()) && |
402 bounds->y() > max_y) { | 372 bounds->y() > max_y) { |
403 bounds->set_y(max_y); | 373 bounds->set_y(max_y); |
404 } | 374 } |
405 | 375 |
406 // Don't allow dragging above the top of the display except when an extended | 376 // Don't allow dragging above the top of the display except when an extended |
407 // display is available and a window is being dragged. | 377 // display is available and a window is being dragged. |
408 if ((details_.window_component != HTCAPTION || !HasSecondaryRootWindow()) && | 378 if ((details_.window_component != HTCAPTION || !HasSecondaryRootWindow()) && |
409 bounds->y() <= work_area.y()) { | 379 bounds->y() <= work_area.y()) { |
410 bounds->set_y(work_area.y()); | 380 bounds->set_y(work_area.y()); |
(...skipping 12 matching lines...) Expand all Loading... |
423 DCHECK_EQ(HTBOTTOM, details_.window_component); | 393 DCHECK_EQ(HTBOTTOM, details_.window_component); |
424 bounds->set_height(std::min(bounds->height(), | 394 bounds->set_height(std::min(bounds->height(), |
425 work_area.bottom() - total_min_ - bounds->y())); | 395 work_area.bottom() - total_min_ - bounds->y())); |
426 } | 396 } |
427 } | 397 } |
428 | 398 |
429 void WorkspaceWindowResizer::SnapToWorkAreaEdges( | 399 void WorkspaceWindowResizer::SnapToWorkAreaEdges( |
430 const gfx::Rect& work_area, | 400 const gfx::Rect& work_area, |
431 gfx::Rect* bounds, | 401 gfx::Rect* bounds, |
432 int grid_size) const { | 402 int grid_size) const { |
433 int left_edge = AlignToGridRoundUp(work_area.x(), grid_size); | 403 int left_edge = work_area.x(); |
434 int right_edge = AlignToGridRoundDown(work_area.right(), grid_size); | 404 int right_edge = work_area.right(); |
435 int top_edge = AlignToGridRoundUp(work_area.y(), grid_size); | 405 int top_edge = work_area.y(); |
436 int bottom_edge = AlignToGridRoundDown(work_area.bottom(), | 406 int bottom_edge = work_area.bottom(); |
437 grid_size); | |
438 if (ShouldSnapToEdge(bounds->x() - left_edge, grid_size)) { | 407 if (ShouldSnapToEdge(bounds->x() - left_edge, grid_size)) { |
439 bounds->set_x(left_edge); | 408 bounds->set_x(left_edge); |
440 } else if (ShouldSnapToEdge(right_edge - bounds->right(), | 409 } else if (ShouldSnapToEdge(right_edge - bounds->right(), |
441 grid_size)) { | 410 grid_size)) { |
442 bounds->set_x(right_edge - bounds->width()); | 411 bounds->set_x(right_edge - bounds->width()); |
443 } | 412 } |
444 if (ShouldSnapToEdge(bounds->y() - top_edge, grid_size)) { | 413 if (ShouldSnapToEdge(bounds->y() - top_edge, grid_size)) { |
445 bounds->set_y(top_edge); | 414 bounds->set_y(top_edge); |
446 } else if (ShouldSnapToEdge(bottom_edge - bounds->bottom(), grid_size) && | 415 } else if (ShouldSnapToEdge(bottom_edge - bounds->bottom(), grid_size) && |
447 bounds->height() < (bottom_edge - top_edge)) { | 416 bounds->height() < (bottom_edge - top_edge)) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 } | 488 } |
520 drag_phantom_window_controller_->SetOpacity(phantom_opacity); | 489 drag_phantom_window_controller_->SetOpacity(phantom_opacity); |
521 window()->layer()->SetOpacity(window_opacity); | 490 window()->layer()->SetOpacity(window_opacity); |
522 } else { | 491 } else { |
523 drag_phantom_window_controller_.reset(); | 492 drag_phantom_window_controller_.reset(); |
524 window()->layer()->SetOpacity(1.0f); | 493 window()->layer()->SetOpacity(1.0f); |
525 } | 494 } |
526 } | 495 } |
527 | 496 |
528 void WorkspaceWindowResizer::UpdateSnapPhantomWindow(const gfx::Point& location, | 497 void WorkspaceWindowResizer::UpdateSnapPhantomWindow(const gfx::Point& location, |
529 const gfx::Rect& bounds, | 498 const gfx::Rect& bounds) { |
530 int grid_size) { | |
531 if (!did_move_or_resize_ || details_.window_component != HTCAPTION) | 499 if (!did_move_or_resize_ || details_.window_component != HTCAPTION) |
532 return; | 500 return; |
533 | 501 |
534 SnapType last_type = snap_type_; | 502 SnapType last_type = snap_type_; |
535 snap_type_ = GetSnapType(location); | 503 snap_type_ = GetSnapType(location); |
536 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) { | 504 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) { |
537 snap_phantom_window_controller_.reset(); | 505 snap_phantom_window_controller_.reset(); |
538 snap_sizer_.reset(); | 506 snap_sizer_.reset(); |
539 if (snap_type_ == SNAP_NONE) | 507 if (snap_type_ == SNAP_NONE) |
540 return; | 508 return; |
541 } | 509 } |
542 if (!snap_sizer_.get()) { | 510 if (!snap_sizer_.get()) { |
543 SnapSizer::Edge edge = (snap_type_ == SNAP_LEFT_EDGE) ? | 511 SnapSizer::Edge edge = (snap_type_ == SNAP_LEFT_EDGE) ? |
544 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE; | 512 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE; |
545 snap_sizer_.reset( | 513 snap_sizer_.reset(new SnapSizer(window(), location, edge)); |
546 new SnapSizer(window(), location, edge, grid_size)); | |
547 } else { | 514 } else { |
548 snap_sizer_->Update(location); | 515 snap_sizer_->Update(location); |
549 } | 516 } |
550 if (!snap_phantom_window_controller_.get()) { | 517 if (!snap_phantom_window_controller_.get()) { |
551 snap_phantom_window_controller_.reset( | 518 snap_phantom_window_controller_.reset( |
552 new PhantomWindowController(window())); | 519 new PhantomWindowController(window())); |
553 } | 520 } |
554 snap_phantom_window_controller_->Show(ScreenAsh::ConvertRectToScreen( | 521 snap_phantom_window_controller_->Show(ScreenAsh::ConvertRectToScreen( |
555 window()->parent(), snap_sizer_->target_bounds()), NULL); | 522 window()->parent(), snap_sizer_->target_bounds()), NULL); |
556 } | 523 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 gfx::Rect layer_bounds = layer_->bounds(); | 582 gfx::Rect layer_bounds = layer_->bounds(); |
616 layer_bounds.set_origin(gfx::Point(0, 0)); | 583 layer_bounds.set_origin(gfx::Point(0, 0)); |
617 layer_->SetBounds(layer_bounds); | 584 layer_->SetBounds(layer_bounds); |
618 layer_->SetVisible(false); | 585 layer_->SetVisible(false); |
619 // Detach it from the current container. | 586 // Detach it from the current container. |
620 layer_->parent()->Remove(layer_); | 587 layer_->parent()->Remove(layer_); |
621 } | 588 } |
622 | 589 |
623 } // namespace internal | 590 } // namespace internal |
624 } // namespace ash | 591 } // namespace ash |
OLD | NEW |