| 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_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 Loading... |
| 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 AdjustWindowBounds(child, ADJUST_WINDOW_WINDOW_ADDED); |
| 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 Loading... |
| 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 Loading... |
| 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::AdjustWindowBounds( |
| 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( | 220 case ADJUST_WINDOW_WINDOW_ADDED: { |
| 213 work_area_, min_width, min_height, &bounds); | 221 int min_width = bounds.width() * kMinimumPercentOnScreenArea; |
| 222 int min_height = bounds.height() * kMinimumPercentOnScreenArea; |
| 223 ash::wm::AdjustBoundsToEnsureWindowVisibility( |
| 224 work_area_, min_width, min_height, &bounds); |
| 225 break; |
| 226 } |
| 214 } | 227 } |
| 215 if (window->bounds() != bounds) | 228 if (window->bounds() != bounds) |
| 216 window->SetBounds(bounds); | 229 window->SetBounds(bounds); |
| 217 } | 230 } |
| 218 | 231 |
| 219 void WorkspaceLayoutManager::UpdateDesktopVisibility() { | 232 void WorkspaceLayoutManager::UpdateDesktopVisibility() { |
| 220 if (shelf_) | 233 if (shelf_) |
| 221 shelf_->UpdateVisibilityState(); | 234 shelf_->UpdateVisibilityState(); |
| 222 FramePainter::UpdateSoloWindowHeader(window_->GetRootWindow()); | 235 FramePainter::UpdateSoloWindowHeader(window_->GetRootWindow()); |
| 223 } | 236 } |
| 224 | 237 |
| 225 void WorkspaceLayoutManager::UpdateBoundsFromShowState(Window* window) { | 238 void WorkspaceLayoutManager::UpdateBoundsFromShowState(Window* window) { |
| 226 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in | 239 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in |
| 227 // these calculation. | 240 // these calculation. |
| 228 switch (window->GetProperty(aura::client::kShowStateKey)) { | 241 switch (window->GetProperty(aura::client::kShowStateKey)) { |
| 229 case ui::SHOW_STATE_DEFAULT: | 242 case ui::SHOW_STATE_DEFAULT: |
| 230 case ui::SHOW_STATE_NORMAL: { | 243 case ui::SHOW_STATE_NORMAL: { |
| 231 const gfx::Rect* restore = GetRestoreBoundsInScreen(window); | 244 const gfx::Rect* restore = GetRestoreBoundsInScreen(window); |
| 245 // Make sure that the part of the window is always visible |
| 246 // when restored. |
| 247 gfx::Rect bounds_in_parent; |
| 232 if (restore) { | 248 if (restore) { |
| 233 gfx::Rect bounds_in_parent = | 249 bounds_in_parent = |
| 234 ScreenAsh::ConvertRectFromScreen(window->parent()->parent(), | 250 ScreenAsh::ConvertRectFromScreen(window->parent()->parent(), |
| 235 *restore); | 251 *restore); |
| 252 |
| 253 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( |
| 254 work_area_, &bounds_in_parent); |
| 255 } else { |
| 256 // Minimized windows have no restore bounds. |
| 257 // Use the current bounds instead. |
| 258 bounds_in_parent = window->bounds(); |
| 259 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( |
| 260 work_area_, &bounds_in_parent); |
| 261 // Don't start animation if the bounds didn't change. |
| 262 if (bounds_in_parent == window->bounds()) |
| 263 bounds_in_parent.SetRect(0, 0, 0, 0); |
| 264 } |
| 265 if (!bounds_in_parent.IsEmpty()) { |
| 236 CrossFadeToBounds( | 266 CrossFadeToBounds( |
| 237 window, | 267 window, |
| 238 BaseLayoutManager::BoundsWithScreenEdgeVisible( | 268 BaseLayoutManager::BoundsWithScreenEdgeVisible( |
| 239 window->parent()->parent(), | 269 window->parent()->parent(), |
| 240 bounds_in_parent)); | 270 bounds_in_parent)); |
| 241 } | 271 } |
| 242 ClearRestoreBounds(window); | 272 ClearRestoreBounds(window); |
| 243 break; | 273 break; |
| 244 } | 274 } |
| 245 | 275 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 275 SetChildBoundsDirect( | 305 SetChildBoundsDirect( |
| 276 window, | 306 window, |
| 277 ScreenAsh::GetDisplayBoundsInParent(window->parent()->parent())); | 307 ScreenAsh::GetDisplayBoundsInParent(window->parent()->parent())); |
| 278 return true; | 308 return true; |
| 279 } | 309 } |
| 280 return false; | 310 return false; |
| 281 } | 311 } |
| 282 | 312 |
| 283 } // namespace internal | 313 } // namespace internal |
| 284 } // namespace ash | 314 } // namespace ash |
| OLD | NEW |