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

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

Issue 21979005: Make sure that 30%of restored window is always visible. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: AdjustWindowBoundsWhenAdded Created 7 years, 4 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_layout_manager.h" 5 #include "ash/wm/workspace/workspace_layout_manager.h"
6 6
7 #include "ash/root_window_controller.h" 7 #include "ash/root_window_controller.h"
8 #include "ash/screen_ash.h" 8 #include "ash/screen_ash.h"
9 #include "ash/shelf/shelf_layout_manager.h" 9 #include "ash/shelf/shelf_layout_manager.h"
10 #include "ash/shell.h" 10 #include "ash/shell.h"
(...skipping 14 matching lines...) Expand all
25 #include "ui/views/corewm/window_util.h" 25 #include "ui/views/corewm/window_util.h"
26 26
27 using aura::Window; 27 using aura::Window;
28 28
29 namespace ash { 29 namespace ash {
30 30
31 namespace internal { 31 namespace internal {
32 32
33 namespace { 33 namespace {
34 34
35 // This specifies how much percent (2/3=66%) of a window must be visible when 35 // This specifies how much percent 30% of a window rect (width / height)
36 // the window is added to the workspace. 36 // must be visible when the window is added to the workspace.
37 const float kMinimumPercentOnScreenArea = 0.66f; 37 const float kMinimumPercentOnScreenArea = 0.3f;
38 38
39 bool IsMaximizedState(ui::WindowShowState state) { 39 bool IsMaximizedState(ui::WindowShowState state) {
40 return state == ui::SHOW_STATE_MAXIMIZED || 40 return state == ui::SHOW_STATE_MAXIMIZED ||
41 state == ui::SHOW_STATE_FULLSCREEN; 41 state == ui::SHOW_STATE_FULLSCREEN;
42 } 42 }
43 43
44 } // namespace 44 } // namespace
45 45
46 WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window) 46 WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window)
47 : BaseLayoutManager(window->GetRootWindow()), 47 : BaseLayoutManager(window->GetRootWindow()),
48 shelf_(NULL), 48 shelf_(NULL),
49 window_(window), 49 window_(window),
50 work_area_(ScreenAsh::GetDisplayWorkAreaBoundsInParent( 50 work_area_(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
51 window->parent())) { 51 window->parent())) {
52 } 52 }
53 53
54 WorkspaceLayoutManager::~WorkspaceLayoutManager() { 54 WorkspaceLayoutManager::~WorkspaceLayoutManager() {
55 } 55 }
56 56
57 void WorkspaceLayoutManager::SetShelf(internal::ShelfLayoutManager* shelf) { 57 void WorkspaceLayoutManager::SetShelf(internal::ShelfLayoutManager* shelf) {
58 shelf_ = shelf; 58 shelf_ = shelf;
59 } 59 }
60 60
61 void WorkspaceLayoutManager::OnWindowAddedToLayout(Window* child) { 61 void WorkspaceLayoutManager::OnWindowAddedToLayout(Window* child) {
62 // Adjust window bounds in case that the new child is out of the workspace. 62 // Adjust window bounds in case that the new child is given the bounds that
63 AdjustWindowSizeForScreenChange(child, ADJUST_WINDOW_WINDOW_ADDED); 63 // is out of the workspace. Exclude the case where bounds is empty
64 // (this happens when a views::Widget is created), or the window
65 // is added with the bounds because a user explicitly moved to
66 // this position (drag and drop for example).
67 if (!child->bounds().IsEmpty() &&
68 !wm::HasUserChangedWindowPositionOrSize(child))
69 AdjustWindowBoundsWhenAdded(child);
64 BaseLayoutManager::OnWindowAddedToLayout(child); 70 BaseLayoutManager::OnWindowAddedToLayout(child);
65 UpdateDesktopVisibility(); 71 UpdateDesktopVisibility();
66 RearrangeVisibleWindowOnShow(child); 72 RearrangeVisibleWindowOnShow(child);
67 } 73 }
68 74
69 void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout(Window* child) { 75 void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout(Window* child) {
70 BaseLayoutManager::OnWillRemoveWindowFromLayout(child); 76 BaseLayoutManager::OnWillRemoveWindowFromLayout(child);
71 if (child->TargetVisibility()) 77 if (child->TargetVisibility())
72 RearrangeVisibleWindowOnHideOrRemove(child); 78 RearrangeVisibleWindowOnHideOrRemove(child);
73 } 79 }
(...skipping 29 matching lines...) Expand all
103 child_bounds.set_height( 109 child_bounds.set_height(
104 std::min(work_area_.height(), child_bounds.height())); 110 std::min(work_area_.height(), child_bounds.height()));
105 SetChildBoundsDirect(child, child_bounds); 111 SetChildBoundsDirect(child, child_bounds);
106 } 112 }
107 UpdateDesktopVisibility(); 113 UpdateDesktopVisibility();
108 } 114 }
109 115
110 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() { 116 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() {
111 const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent( 117 const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
112 window_->parent())); 118 window_->parent()));
113 if (work_area != work_area_) 119 if (work_area != work_area_) {
114 AdjustWindowSizesForScreenChange(ADJUST_WINDOW_DISPLAY_INSETS_CHANGED); 120 AdjustWindowsBoundsForWorkAreaChange(
121 ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED);
122 }
115 } 123 }
116 124
117 void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window, 125 void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window,
118 const void* key, 126 const void* key,
119 intptr_t old) { 127 intptr_t old) {
120 if (key == aura::client::kShowStateKey) { 128 if (key == aura::client::kShowStateKey) {
121 ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old); 129 ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old);
122 ui::WindowShowState new_state = 130 ui::WindowShowState new_state =
123 window->GetProperty(aura::client::kShowStateKey); 131 window->GetProperty(aura::client::kShowStateKey);
124 if (old_state != ui::SHOW_STATE_MINIMIZED && 132 if (old_state != ui::SHOW_STATE_MINIMIZED &&
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 } 171 }
164 } 172 }
165 173
166 void WorkspaceLayoutManager::ShowStateChanged( 174 void WorkspaceLayoutManager::ShowStateChanged(
167 Window* window, 175 Window* window,
168 ui::WindowShowState last_show_state) { 176 ui::WindowShowState last_show_state) {
169 BaseLayoutManager::ShowStateChanged(window, last_show_state); 177 BaseLayoutManager::ShowStateChanged(window, last_show_state);
170 UpdateDesktopVisibility(); 178 UpdateDesktopVisibility();
171 } 179 }
172 180
173 void WorkspaceLayoutManager::AdjustWindowSizesForScreenChange( 181 void WorkspaceLayoutManager::AdjustWindowsBoundsForWorkAreaChange(
174 AdjustWindowReason reason) { 182 AdjustWindowReason reason) {
175 work_area_ = ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_->parent()); 183 work_area_ = ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_->parent());
176 BaseLayoutManager::AdjustWindowSizesForScreenChange(reason); 184 BaseLayoutManager::AdjustWindowsBoundsForWorkAreaChange(reason);
177 } 185 }
178 186
179 void WorkspaceLayoutManager::AdjustWindowSizeForScreenChange( 187 void WorkspaceLayoutManager::AdjustWindowBoundsForWorkAreaChange(
180 Window* window, 188 Window* window,
181 AdjustWindowReason reason) { 189 AdjustWindowReason reason) {
182 if (!GetTrackedByWorkspace(window)) 190 if (!GetTrackedByWorkspace(window))
183 return; 191 return;
184 192
185 // Use cross fade transition for the maximized window if the adjustment 193 // Use cross fade transition for the maximized window if the adjustment
186 // happens due to the shelf's visibility change. Otherwise the background 194 // happens due to the shelf's visibility change. Otherwise the background
187 // can be seen slightly between the bottom edge of resized-window and 195 // can be seen slightly between the bottom edge of resized-window and
188 // the animating shelf. 196 // the animating shelf.
189 // TODO(mukai): this cause slight blur at the window frame because of the 197 // TODO(mukai): this cause slight blur at the window frame because of the
190 // cross fade. I think this is better, but should reconsider if someone 198 // cross fade. I think this is better, but should reconsider if someone
191 // raises voice for this. 199 // raises voice for this.
192 if (wm::IsWindowMaximized(window) && 200 if (wm::IsWindowMaximized(window) &&
193 reason == ADJUST_WINDOW_DISPLAY_INSETS_CHANGED) { 201 reason == ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED) {
194 CrossFadeToBounds(window, ScreenAsh::GetMaximizedWindowBoundsInParent( 202 CrossFadeToBounds(window, ScreenAsh::GetMaximizedWindowBoundsInParent(
195 window->parent()->parent())); 203 window->parent()->parent()));
196 return; 204 return;
197 } 205 }
198 206
199 if (SetMaximizedOrFullscreenBounds(window)) 207 if (SetMaximizedOrFullscreenBounds(window))
200 return; 208 return;
201 209
202 gfx::Rect bounds = window->bounds(); 210 gfx::Rect bounds = window->bounds();
203 if (reason == ADJUST_WINDOW_SCREEN_SIZE_CHANGED) { 211 switch (reason) {
204 // The work area may be smaller than the full screen. Put as much of the 212 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED:
205 // window as possible within the display area. 213 // The work area may be smaller than the full screen. Put as much of the
206 bounds.AdjustToFit(work_area_); 214 // window as possible within the display area.
207 } else if (reason == ADJUST_WINDOW_DISPLAY_INSETS_CHANGED) { 215 bounds.AdjustToFit(work_area_);
208 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area_, &bounds); 216 break;
209 } else if (reason == ADJUST_WINDOW_WINDOW_ADDED) { 217 case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED:
210 int min_width = bounds.width() * kMinimumPercentOnScreenArea; 218 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area_, &bounds);
211 int min_height = bounds.height() * kMinimumPercentOnScreenArea; 219 break;
212 ash::wm::AdjustBoundsToEnsureWindowVisibility(
213 work_area_, min_width, min_height, &bounds);
214 } 220 }
215 if (window->bounds() != bounds) 221 if (window->bounds() != bounds)
216 window->SetBounds(bounds); 222 window->SetBounds(bounds);
217 } 223 }
218 224
225 void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded(
226 Window* window) {
227 if (!GetTrackedByWorkspace(window))
228 return;
229
230 if (SetMaximizedOrFullscreenBounds(window))
231 return;
232
233 gfx::Rect bounds = window->bounds();
234 int min_width = bounds.width() * kMinimumPercentOnScreenArea;
235 int min_height = bounds.height() * kMinimumPercentOnScreenArea;
236 ash::wm::AdjustBoundsToEnsureWindowVisibility(
237 work_area_, min_width, min_height, &bounds);
238
239 if (window->bounds() != bounds)
240 window->SetBounds(bounds);
241 }
242
219 void WorkspaceLayoutManager::UpdateDesktopVisibility() { 243 void WorkspaceLayoutManager::UpdateDesktopVisibility() {
220 if (shelf_) 244 if (shelf_)
221 shelf_->UpdateVisibilityState(); 245 shelf_->UpdateVisibilityState();
222 FramePainter::UpdateSoloWindowHeader(window_->GetRootWindow()); 246 FramePainter::UpdateSoloWindowHeader(window_->GetRootWindow());
223 } 247 }
224 248
225 void WorkspaceLayoutManager::UpdateBoundsFromShowState(Window* window) { 249 void WorkspaceLayoutManager::UpdateBoundsFromShowState(Window* window) {
226 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in 250 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in
227 // these calculation. 251 // these calculation.
228 switch (window->GetProperty(aura::client::kShowStateKey)) { 252 switch (window->GetProperty(aura::client::kShowStateKey)) {
229 case ui::SHOW_STATE_DEFAULT: 253 case ui::SHOW_STATE_DEFAULT:
230 case ui::SHOW_STATE_NORMAL: { 254 case ui::SHOW_STATE_NORMAL: {
231 const gfx::Rect* restore = GetRestoreBoundsInScreen(window); 255 const gfx::Rect* restore = GetRestoreBoundsInScreen(window);
256 // Make sure that the part of the window is always visible
257 // when restored.
258 gfx::Rect bounds_in_parent;
232 if (restore) { 259 if (restore) {
233 gfx::Rect bounds_in_parent = 260 bounds_in_parent =
234 ScreenAsh::ConvertRectFromScreen(window->parent()->parent(), 261 ScreenAsh::ConvertRectFromScreen(window->parent()->parent(),
235 *restore); 262 *restore);
263
264 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
265 work_area_, &bounds_in_parent);
266 } else {
267 // Minimized windows have no restore bounds.
268 // Use the current bounds instead.
269 bounds_in_parent = window->bounds();
270 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
271 work_area_, &bounds_in_parent);
272 // Don't start animation if the bounds didn't change.
273 if (bounds_in_parent == window->bounds())
274 bounds_in_parent.SetRect(0, 0, 0, 0);
275 }
276 if (!bounds_in_parent.IsEmpty()) {
236 CrossFadeToBounds( 277 CrossFadeToBounds(
237 window, 278 window,
238 BaseLayoutManager::BoundsWithScreenEdgeVisible( 279 BaseLayoutManager::BoundsWithScreenEdgeVisible(
239 window->parent()->parent(), 280 window->parent()->parent(),
240 bounds_in_parent)); 281 bounds_in_parent));
241 } 282 }
242 ClearRestoreBounds(window); 283 ClearRestoreBounds(window);
243 break; 284 break;
244 } 285 }
245 286
(...skipping 29 matching lines...) Expand all
275 SetChildBoundsDirect( 316 SetChildBoundsDirect(
276 window, 317 window,
277 ScreenAsh::GetDisplayBoundsInParent(window->parent()->parent())); 318 ScreenAsh::GetDisplayBoundsInParent(window->parent()->parent()));
278 return true; 319 return true;
279 } 320 }
280 return false; 321 return false;
281 } 322 }
282 323
283 } // namespace internal 324 } // namespace internal
284 } // namespace ash 325 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698