| 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/display/display_controller.h" | 7 #include "ash/display/display_controller.h" |
| 8 #include "ash/root_window_controller.h" | 8 #include "ash/root_window_controller.h" |
| 9 #include "ash/screen_ash.h" | 9 #include "ash/screen_ash.h" |
| 10 #include "ash/shelf/shelf_layout_manager.h" | 10 #include "ash/shelf/shelf_layout_manager.h" |
| 11 #include "ash/shell.h" | 11 #include "ash/shell.h" |
| 12 #include "ash/wm/always_on_top_controller.h" | 12 #include "ash/wm/always_on_top_controller.h" |
| 13 #include "ash/wm/base_layout_manager.h" | 13 #include "ash/wm/base_layout_manager.h" |
| 14 #include "ash/wm/frame_painter.h" | 14 #include "ash/wm/frame_painter.h" |
| 15 #include "ash/wm/window_animations.h" | 15 #include "ash/wm/window_animations.h" |
| 16 #include "ash/wm/window_properties.h" | 16 #include "ash/wm/window_properties.h" |
| 17 #include "ash/wm/window_settings.h" | 17 #include "ash/wm/window_state.h" |
| 18 #include "ash/wm/window_util.h" | 18 #include "ash/wm/window_util.h" |
| 19 #include "ash/wm/workspace/auto_window_management.h" | 19 #include "ash/wm/workspace/auto_window_management.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_observer.h" | 23 #include "ui/aura/window_observer.h" |
| 24 #include "ui/base/ui_base_types.h" | 24 #include "ui/base/ui_base_types.h" |
| 25 #include "ui/events/event.h" | 25 #include "ui/events/event.h" |
| 26 #include "ui/views/corewm/window_util.h" | 26 #include "ui/views/corewm/window_util.h" |
| 27 | 27 |
| 28 using aura::Window; | 28 using aura::Window; |
| 29 | 29 |
| 30 namespace ash { | 30 namespace ash { |
| 31 | 31 |
| 32 namespace internal { | 32 namespace internal { |
| 33 | 33 |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 // This specifies how much percent 30% of a window rect (width / height) | 36 // This specifies how much percent 30% of a window rect (width / height) |
| 37 // must be visible when the window is added to the workspace. | 37 // must be visible when the window is added to the workspace. |
| 38 const float kMinimumPercentOnScreenArea = 0.3f; | 38 const float kMinimumPercentOnScreenArea = 0.3f; |
| 39 | 39 |
| 40 bool IsMaximizedState(ui::WindowShowState state) { | 40 void MoveToDisplayForRestore(wm::WindowState* window_state) { |
| 41 return state == ui::SHOW_STATE_MAXIMIZED || | 41 if (!window_state->HasRestoreBounds()) |
| 42 state == ui::SHOW_STATE_FULLSCREEN; | |
| 43 } | |
| 44 | |
| 45 void MoveToDisplayForRestore(aura::Window* window) { | |
| 46 const gfx::Rect* restore_bounds = GetRestoreBoundsInScreen(window); | |
| 47 if (!restore_bounds) | |
| 48 return; | 42 return; |
| 43 const gfx::Rect& restore_bounds = window_state->GetRestoreBoundsInScreen(); |
| 49 | 44 |
| 50 // Move only if the restore bounds is outside of | 45 // Move only if the restore bounds is outside of |
| 51 // the display. There is no information about in which | 46 // the display. There is no information about in which |
| 52 // display it should be restored, so this is best guess. | 47 // display it should be restored, so this is best guess. |
| 53 // TODO(oshima): Restore information should contain the | 48 // TODO(oshima): Restore information should contain the |
| 54 // work area information like WindowResizer does for the | 49 // work area information like WindowResizer does for the |
| 55 // last window location. | 50 // last window location. |
| 56 gfx::Rect display_area = | 51 gfx::Rect display_area = Shell::GetScreen()->GetDisplayNearestWindow( |
| 57 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds(); | 52 window_state->window()).bounds(); |
| 58 | 53 |
| 59 if (!display_area.Intersects(*restore_bounds)) { | 54 if (!display_area.Intersects(restore_bounds)) { |
| 60 DisplayController* display_controller = | 55 DisplayController* display_controller = |
| 61 Shell::GetInstance()->display_controller(); | 56 Shell::GetInstance()->display_controller(); |
| 62 const gfx::Display& display = | 57 const gfx::Display& display = |
| 63 display_controller->GetDisplayMatching(*restore_bounds); | 58 display_controller->GetDisplayMatching(restore_bounds); |
| 64 aura::RootWindow* new_root = | 59 aura::RootWindow* new_root = |
| 65 display_controller->GetRootWindowForDisplayId(display.id()); | 60 display_controller->GetRootWindowForDisplayId(display.id()); |
| 66 if (new_root != window->GetRootWindow()) { | 61 if (new_root != window_state->window()->GetRootWindow()) { |
| 67 aura::Window* new_container = | 62 aura::Window* new_container = |
| 68 Shell::GetContainer(new_root, window->parent()->id()); | 63 Shell::GetContainer(new_root, window_state->window()->parent()->id()); |
| 69 new_container->AddChild(window); | 64 new_container->AddChild(window_state->window()); |
| 70 } | 65 } |
| 71 } | 66 } |
| 72 } | 67 } |
| 73 | 68 |
| 74 } // namespace | 69 } // namespace |
| 75 | 70 |
| 76 WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window) | 71 WorkspaceLayoutManager::WorkspaceLayoutManager(aura::Window* window) |
| 77 : BaseLayoutManager(window->GetRootWindow()), | 72 : BaseLayoutManager(window->GetRootWindow()), |
| 78 shelf_(NULL), | 73 shelf_(NULL), |
| 79 window_(window), | 74 window_(window), |
| 80 work_area_(ScreenAsh::GetDisplayWorkAreaBoundsInParent( | 75 work_area_(ScreenAsh::GetDisplayWorkAreaBoundsInParent( |
| 81 window->parent())) { | 76 window->parent())) { |
| 82 } | 77 } |
| 83 | 78 |
| 84 WorkspaceLayoutManager::~WorkspaceLayoutManager() { | 79 WorkspaceLayoutManager::~WorkspaceLayoutManager() { |
| 85 } | 80 } |
| 86 | 81 |
| 87 void WorkspaceLayoutManager::SetShelf(internal::ShelfLayoutManager* shelf) { | 82 void WorkspaceLayoutManager::SetShelf(internal::ShelfLayoutManager* shelf) { |
| 88 shelf_ = shelf; | 83 shelf_ = shelf; |
| 89 } | 84 } |
| 90 | 85 |
| 91 void WorkspaceLayoutManager::OnWindowAddedToLayout(Window* child) { | 86 void WorkspaceLayoutManager::OnWindowAddedToLayout(Window* child) { |
| 92 AdjustWindowBoundsWhenAdded(child); | 87 AdjustWindowBoundsWhenAdded(wm::GetWindowState(child)); |
| 93 BaseLayoutManager::OnWindowAddedToLayout(child); | 88 BaseLayoutManager::OnWindowAddedToLayout(child); |
| 94 UpdateDesktopVisibility(); | 89 UpdateDesktopVisibility(); |
| 95 RearrangeVisibleWindowOnShow(child); | 90 RearrangeVisibleWindowOnShow(child); |
| 96 } | 91 } |
| 97 | 92 |
| 98 void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout(Window* child) { | 93 void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout(Window* child) { |
| 99 BaseLayoutManager::OnWillRemoveWindowFromLayout(child); | 94 BaseLayoutManager::OnWillRemoveWindowFromLayout(child); |
| 100 if (child->TargetVisibility()) | 95 if (child->TargetVisibility()) |
| 101 RearrangeVisibleWindowOnHideOrRemove(child); | 96 RearrangeVisibleWindowOnHideOrRemove(child); |
| 102 } | 97 } |
| 103 | 98 |
| 104 void WorkspaceLayoutManager::OnWindowRemovedFromLayout(Window* child) { | 99 void WorkspaceLayoutManager::OnWindowRemovedFromLayout(Window* child) { |
| 105 BaseLayoutManager::OnWindowRemovedFromLayout(child); | 100 BaseLayoutManager::OnWindowRemovedFromLayout(child); |
| 106 UpdateDesktopVisibility(); | 101 UpdateDesktopVisibility(); |
| 107 } | 102 } |
| 108 | 103 |
| 109 void WorkspaceLayoutManager::OnChildWindowVisibilityChanged(Window* child, | 104 void WorkspaceLayoutManager::OnChildWindowVisibilityChanged(Window* child, |
| 110 bool visible) { | 105 bool visible) { |
| 111 BaseLayoutManager::OnChildWindowVisibilityChanged(child, visible); | 106 BaseLayoutManager::OnChildWindowVisibilityChanged(child, visible); |
| 112 if (child->TargetVisibility()) | 107 if (child->TargetVisibility()) |
| 113 RearrangeVisibleWindowOnShow(child); | 108 RearrangeVisibleWindowOnShow(child); |
| 114 else | 109 else |
| 115 RearrangeVisibleWindowOnHideOrRemove(child); | 110 RearrangeVisibleWindowOnHideOrRemove(child); |
| 116 UpdateDesktopVisibility(); | 111 UpdateDesktopVisibility(); |
| 117 } | 112 } |
| 118 | 113 |
| 119 void WorkspaceLayoutManager::SetChildBounds( | 114 void WorkspaceLayoutManager::SetChildBounds( |
| 120 Window* child, | 115 Window* child, |
| 121 const gfx::Rect& requested_bounds) { | 116 const gfx::Rect& requested_bounds) { |
| 122 if (!wm::GetWindowSettings(child)->tracked_by_workspace()) { | 117 if (!wm::GetWindowState(child)->tracked_by_workspace()) { |
| 123 SetChildBoundsDirect(child, requested_bounds); | 118 SetChildBoundsDirect(child, requested_bounds); |
| 124 return; | 119 return; |
| 125 } | 120 } |
| 126 gfx::Rect child_bounds(requested_bounds); | 121 gfx::Rect child_bounds(requested_bounds); |
| 127 // Some windows rely on this to set their initial bounds. | 122 // Some windows rely on this to set their initial bounds. |
| 128 if (!SetMaximizedOrFullscreenBounds(child)) { | 123 if (!SetMaximizedOrFullscreenBounds(wm::GetWindowState(child))) { |
| 129 // Non-maximized/full-screen windows have their size constrained to the | 124 // Non-maximized/full-screen windows have their size constrained to the |
| 130 // work-area. | 125 // work-area. |
| 131 child_bounds.set_width(std::min(work_area_.width(), child_bounds.width())); | 126 child_bounds.set_width(std::min(work_area_.width(), child_bounds.width())); |
| 132 child_bounds.set_height( | 127 child_bounds.set_height( |
| 133 std::min(work_area_.height(), child_bounds.height())); | 128 std::min(work_area_.height(), child_bounds.height())); |
| 134 SetChildBoundsDirect(child, child_bounds); | 129 SetChildBoundsDirect(child, child_bounds); |
| 135 } | 130 } |
| 136 UpdateDesktopVisibility(); | 131 UpdateDesktopVisibility(); |
| 137 } | 132 } |
| 138 | 133 |
| 139 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() { | 134 void WorkspaceLayoutManager::OnDisplayWorkAreaInsetsChanged() { |
| 140 const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent( | 135 const gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent( |
| 141 window_->parent())); | 136 window_->parent())); |
| 142 if (work_area != work_area_) { | 137 if (work_area != work_area_) { |
| 143 AdjustAllWindowsBoundsForWorkAreaChange( | 138 AdjustAllWindowsBoundsForWorkAreaChange( |
| 144 ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED); | 139 ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED); |
| 145 } | 140 } |
| 146 } | 141 } |
| 147 | 142 |
| 148 void WorkspaceLayoutManager::OnTrackedByWorkspaceChanged(Window* window, | 143 void WorkspaceLayoutManager::OnTrackedByWorkspaceChanged(Window* window, |
| 149 bool old){ | 144 bool old){ |
| 150 if (wm::GetWindowSettings(window)->tracked_by_workspace()) | 145 if (wm::GetWindowState(window)->tracked_by_workspace()) |
| 151 SetMaximizedOrFullscreenBounds(window); | 146 SetMaximizedOrFullscreenBounds(wm::GetWindowState(window)); |
| 152 } | 147 } |
| 153 | 148 |
| 154 void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window, | 149 void WorkspaceLayoutManager::OnWindowPropertyChanged(Window* window, |
| 155 const void* key, | 150 const void* key, |
| 156 intptr_t old) { | 151 intptr_t old) { |
| 152 wm::WindowState* window_state = wm::GetWindowState(window); |
| 157 if (key == aura::client::kShowStateKey) { | 153 if (key == aura::client::kShowStateKey) { |
| 158 ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old); | 154 ui::WindowShowState old_state = static_cast<ui::WindowShowState>(old); |
| 159 ui::WindowShowState new_state = | 155 ui::WindowShowState new_state = window_state->GetShowState(); |
| 160 window->GetProperty(aura::client::kShowStateKey); | |
| 161 if (old_state != ui::SHOW_STATE_MINIMIZED && | 156 if (old_state != ui::SHOW_STATE_MINIMIZED && |
| 162 GetRestoreBoundsInScreen(window) == NULL && | 157 !window_state->HasRestoreBounds() && |
| 163 IsMaximizedState(new_state) && | 158 window_state->IsMaximizedOrFullscreen() && |
| 164 !IsMaximizedState(old_state)) { | 159 !wm::WindowState::IsMaximizedOrFullscreenState(old_state)) { |
| 165 SetRestoreBoundsInParent(window, window->bounds()); | 160 window_state->SaveCurrentBoundsForRestore(); |
| 166 } | 161 } |
| 167 // When restoring from a minimized state, we want to restore to the | 162 // When restoring from a minimized state, we want to restore to the |
| 168 // previous (maybe L/R maximized) state. Since we do also want to keep the | 163 // previous (maybe L/R maximized) state. Since we do also want to keep the |
| 169 // restore rectangle, we set the restore rectangle to the rectangle we want | 164 // restore rectangle, we set the restore rectangle to the rectangle we want |
| 170 // to restore to and restore it after we switched so that it is preserved. | 165 // to restore to and restore it after we switched so that it is preserved. |
| 171 gfx::Rect restore; | 166 gfx::Rect restore; |
| 172 if (old_state == ui::SHOW_STATE_MINIMIZED && | 167 if (old_state == ui::SHOW_STATE_MINIMIZED && |
| 173 (new_state == ui::SHOW_STATE_NORMAL || | 168 (new_state == ui::SHOW_STATE_NORMAL || |
| 174 new_state == ui::SHOW_STATE_DEFAULT) && | 169 new_state == ui::SHOW_STATE_DEFAULT) && |
| 175 GetRestoreBoundsInScreen(window) && | 170 window_state->HasRestoreBounds() && |
| 176 !GetWindowAlwaysRestoresToRestoreBounds(window)) { | 171 !window_state->always_restores_to_restore_bounds()) { |
| 177 restore = *GetRestoreBoundsInScreen(window); | 172 restore = window_state->GetRestoreBoundsInScreen(); |
| 178 SetRestoreBoundsInScreen(window, window->GetBoundsInScreen()); | 173 window_state->SaveCurrentBoundsForRestore(); |
| 179 } | 174 } |
| 180 | 175 |
| 181 UpdateBoundsFromShowState(window, old_state); | 176 UpdateBoundsFromShowState(window_state, old_state); |
| 182 ShowStateChanged(window, old_state); | 177 ShowStateChanged(window_state, old_state); |
| 183 | 178 |
| 184 // Set the restore rectangle to the previously set restore rectangle. | 179 // Set the restore rectangle to the previously set restore rectangle. |
| 185 if (!restore.IsEmpty()) | 180 if (!restore.IsEmpty()) |
| 186 SetRestoreBoundsInScreen(window, restore); | 181 window_state->SetRestoreBoundsInScreen(restore); |
| 187 } | 182 } |
| 188 | 183 |
| 189 if (key == aura::client::kAlwaysOnTopKey && | 184 if (key == aura::client::kAlwaysOnTopKey && |
| 190 window->GetProperty(aura::client::kAlwaysOnTopKey)) { | 185 window->GetProperty(aura::client::kAlwaysOnTopKey)) { |
| 191 internal::AlwaysOnTopController* controller = | 186 GetRootWindowController(window->GetRootWindow())-> |
| 192 GetRootWindowController(window->GetRootWindow())-> | 187 always_on_top_controller()->GetContainer(window)->AddChild(window); |
| 193 always_on_top_controller(); | |
| 194 controller->GetContainer(window)->AddChild(window); | |
| 195 } | 188 } |
| 196 } | 189 } |
| 197 | 190 |
| 198 void WorkspaceLayoutManager::ShowStateChanged( | 191 void WorkspaceLayoutManager::ShowStateChanged( |
| 199 Window* window, | 192 wm::WindowState* state, |
| 200 ui::WindowShowState last_show_state) { | 193 ui::WindowShowState last_show_state) { |
| 201 BaseLayoutManager::ShowStateChanged(window, last_show_state); | 194 BaseLayoutManager::ShowStateChanged(state, last_show_state); |
| 202 UpdateDesktopVisibility(); | 195 UpdateDesktopVisibility(); |
| 203 } | 196 } |
| 204 | 197 |
| 205 void WorkspaceLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange( | 198 void WorkspaceLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange( |
| 206 AdjustWindowReason reason) { | 199 AdjustWindowReason reason) { |
| 207 work_area_ = ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_->parent()); | 200 work_area_ = ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_->parent()); |
| 208 BaseLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(reason); | 201 BaseLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange(reason); |
| 209 } | 202 } |
| 210 | 203 |
| 211 void WorkspaceLayoutManager::AdjustWindowBoundsForWorkAreaChange( | 204 void WorkspaceLayoutManager::AdjustWindowBoundsForWorkAreaChange( |
| 212 Window* window, | 205 wm::WindowState* window_state, |
| 213 AdjustWindowReason reason) { | 206 AdjustWindowReason reason) { |
| 214 if (!wm::GetWindowSettings(window)->tracked_by_workspace()) | 207 if (!window_state->tracked_by_workspace()) |
| 215 return; | 208 return; |
| 216 | 209 |
| 217 // Do not cross fade here: the window's layer hierarchy may be messed up for | 210 // Do not cross fade here: the window's layer hierarchy may be messed up for |
| 218 // the transition between mirroring and extended. See also: crbug.com/267698 | 211 // the transition between mirroring and extended. See also: crbug.com/267698 |
| 219 // TODO(oshima): Differentiate display change and shelf visibility change, and | 212 // TODO(oshima): Differentiate display change and shelf visibility change, and |
| 220 // bring back CrossFade animation. | 213 // bring back CrossFade animation. |
| 221 if (wm::IsWindowMaximized(window) && | 214 if (window_state->IsMaximized() && |
| 222 reason == ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED) { | 215 reason == ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED) { |
| 223 SetChildBoundsDirect(window, ScreenAsh::GetMaximizedWindowBoundsInParent( | 216 SetChildBoundsDirect(window_state->window(), |
| 224 window->parent()->parent())); | 217 ScreenAsh::GetMaximizedWindowBoundsInParent( |
| 218 window_state->window()->parent()->parent())); |
| 225 return; | 219 return; |
| 226 } | 220 } |
| 227 | 221 |
| 228 if (SetMaximizedOrFullscreenBounds(window)) | 222 if (SetMaximizedOrFullscreenBounds(window_state)) |
| 229 return; | 223 return; |
| 230 | 224 |
| 231 gfx::Rect bounds = window->bounds(); | 225 gfx::Rect bounds = window_state->window()->bounds(); |
| 232 switch (reason) { | 226 switch (reason) { |
| 233 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED: | 227 case ADJUST_WINDOW_DISPLAY_SIZE_CHANGED: |
| 234 // The work area may be smaller than the full screen. Put as much of the | 228 // The work area may be smaller than the full screen. Put as much of the |
| 235 // window as possible within the display area. | 229 // window as possible within the display area. |
| 236 bounds.AdjustToFit(work_area_); | 230 bounds.AdjustToFit(work_area_); |
| 237 break; | 231 break; |
| 238 case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED: | 232 case ADJUST_WINDOW_WORK_AREA_INSETS_CHANGED: |
| 239 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area_, &bounds); | 233 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area_, &bounds); |
| 240 break; | 234 break; |
| 241 } | 235 } |
| 242 if (window->bounds() != bounds) | 236 if (window_state->window()->bounds() != bounds) |
| 243 window->SetBounds(bounds); | 237 window_state->window()->SetBounds(bounds); |
| 244 } | 238 } |
| 245 | 239 |
| 246 void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded( | 240 void WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded( |
| 247 Window* window) { | 241 wm::WindowState* window_state) { |
| 248 // Don't adjust window bounds if the bounds are empty as this | 242 // Don't adjust window bounds if the bounds are empty as this |
| 249 // happens when a new views::Widget is created. | 243 // happens when a new views::Widget is created. |
| 250 // When a window is dragged and dropped onto a different | 244 // When a window is dragged and dropped onto a different |
| 251 // root window, the bounds will be updated after they are added | 245 // root window, the bounds will be updated after they are added |
| 252 // to the root window. | 246 // to the root window. |
| 253 if (window->bounds().IsEmpty()) | 247 if (window_state->window()->bounds().IsEmpty()) |
| 254 return; | 248 return; |
| 255 | 249 |
| 256 if (!wm::GetWindowSettings(window)->tracked_by_workspace()) | 250 if (!window_state->tracked_by_workspace()) |
| 257 return; | 251 return; |
| 258 | 252 |
| 259 if (SetMaximizedOrFullscreenBounds(window)) | 253 if (SetMaximizedOrFullscreenBounds(window_state)) |
| 260 return; | 254 return; |
| 261 | 255 |
| 256 Window* window = window_state->window(); |
| 262 gfx::Rect bounds = window->bounds(); | 257 gfx::Rect bounds = window->bounds(); |
| 263 int min_width = bounds.width() * kMinimumPercentOnScreenArea; | 258 int min_width = bounds.width() * kMinimumPercentOnScreenArea; |
| 264 int min_height = bounds.height() * kMinimumPercentOnScreenArea; | 259 int min_height = bounds.height() * kMinimumPercentOnScreenArea; |
| 265 // Use entire display instead of workarea because the workarea can | 260 // Use entire display instead of workarea because the workarea can |
| 266 // be further shrunk by the docked area. The logic ensures 30% | 261 // be further shrunk by the docked area. The logic ensures 30% |
| 267 // visibility which should be enough to see where the window gets | 262 // visibility which should be enough to see where the window gets |
| 268 // moved. | 263 // moved. |
| 269 gfx::Rect display_area = | 264 gfx::Rect display_area = |
| 270 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds(); | 265 Shell::GetScreen()->GetDisplayNearestWindow(window).bounds(); |
| 271 ash::wm::AdjustBoundsToEnsureWindowVisibility( | 266 ash::wm::AdjustBoundsToEnsureWindowVisibility( |
| 272 display_area, min_width, min_height, &bounds); | 267 display_area, min_width, min_height, &bounds); |
| 273 if (window->bounds() != bounds) | 268 if (window->bounds() != bounds) |
| 274 window->SetBounds(bounds); | 269 window->SetBounds(bounds); |
| 275 } | 270 } |
| 276 | 271 |
| 277 void WorkspaceLayoutManager::UpdateDesktopVisibility() { | 272 void WorkspaceLayoutManager::UpdateDesktopVisibility() { |
| 278 if (shelf_) | 273 if (shelf_) |
| 279 shelf_->UpdateVisibilityState(); | 274 shelf_->UpdateVisibilityState(); |
| 280 FramePainter::UpdateSoloWindowHeader(window_->GetRootWindow()); | 275 FramePainter::UpdateSoloWindowHeader(window_->GetRootWindow()); |
| 281 } | 276 } |
| 282 | 277 |
| 283 void WorkspaceLayoutManager::UpdateBoundsFromShowState( | 278 void WorkspaceLayoutManager::UpdateBoundsFromShowState( |
| 284 Window* window, | 279 wm::WindowState* window_state, |
| 285 ui::WindowShowState last_show_state) { | 280 ui::WindowShowState last_show_state) { |
| 281 aura::Window* window = window_state->window(); |
| 286 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in | 282 // See comment in SetMaximizedOrFullscreenBounds() as to why we use parent in |
| 287 // these calculation. | 283 // these calculation. |
| 288 switch (window->GetProperty(aura::client::kShowStateKey)) { | 284 switch (window_state->GetShowState()) { |
| 289 case ui::SHOW_STATE_DEFAULT: | 285 case ui::SHOW_STATE_DEFAULT: |
| 290 case ui::SHOW_STATE_NORMAL: { | 286 case ui::SHOW_STATE_NORMAL: { |
| 291 const gfx::Rect* restore = GetRestoreBoundsInScreen(window); | |
| 292 // Make sure that the part of the window is always visible | 287 // Make sure that the part of the window is always visible |
| 293 // when restored. | 288 // when restored. |
| 294 gfx::Rect bounds_in_parent; | 289 gfx::Rect bounds_in_parent; |
| 295 if (restore) { | 290 if (window_state->HasRestoreBounds()) { |
| 296 bounds_in_parent = | 291 bounds_in_parent = window_state->GetRestoreBoundsInParent(); |
| 297 ScreenAsh::ConvertRectFromScreen(window->parent()->parent(), | |
| 298 *restore); | |
| 299 | |
| 300 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( | 292 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( |
| 301 work_area_, &bounds_in_parent); | 293 work_area_, &bounds_in_parent); |
| 302 } else { | 294 } else { |
| 303 // Minimized windows have no restore bounds. | 295 // Minimized windows have no restore bounds. |
| 304 // Use the current bounds instead. | 296 // Use the current bounds instead. |
| 305 bounds_in_parent = window->bounds(); | 297 bounds_in_parent = window->bounds(); |
| 306 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( | 298 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( |
| 307 work_area_, &bounds_in_parent); | 299 work_area_, &bounds_in_parent); |
| 308 // Don't start animation if the bounds didn't change. | 300 // Don't start animation if the bounds didn't change. |
| 309 if (bounds_in_parent == window->bounds()) | 301 if (bounds_in_parent == window->bounds()) |
| 310 bounds_in_parent.SetRect(0, 0, 0, 0); | 302 bounds_in_parent.SetRect(0, 0, 0, 0); |
| 311 } | 303 } |
| 312 if (!bounds_in_parent.IsEmpty()) { | 304 if (!bounds_in_parent.IsEmpty()) { |
| 313 gfx::Rect new_bounds = BaseLayoutManager::BoundsWithScreenEdgeVisible( | 305 gfx::Rect new_bounds = BaseLayoutManager::BoundsWithScreenEdgeVisible( |
| 314 window->parent()->parent(), | 306 window->parent()->parent(), |
| 315 bounds_in_parent); | 307 bounds_in_parent); |
| 316 if (last_show_state == ui::SHOW_STATE_MINIMIZED) | 308 if (last_show_state == ui::SHOW_STATE_MINIMIZED) |
| 317 SetChildBoundsDirect(window, new_bounds); | 309 SetChildBoundsDirect(window, new_bounds); |
| 318 else | 310 else |
| 319 CrossFadeToBounds(window, new_bounds); | 311 CrossFadeToBounds(window, new_bounds); |
| 320 } | 312 } |
| 321 ClearRestoreBounds(window); | 313 window_state->ClearRestoreBounds(); |
| 322 break; | 314 break; |
| 323 } | 315 } |
| 324 | 316 |
| 325 case ui::SHOW_STATE_MAXIMIZED: { | 317 case ui::SHOW_STATE_MAXIMIZED: { |
| 326 MoveToDisplayForRestore(window); | 318 MoveToDisplayForRestore(window_state); |
| 327 gfx::Rect new_bounds = ScreenAsh::GetMaximizedWindowBoundsInParent( | 319 gfx::Rect new_bounds = ScreenAsh::GetMaximizedWindowBoundsInParent( |
| 328 window->parent()->parent()); | 320 window->parent()->parent()); |
| 329 // If the window is restored from minimized state, do not make the cross | 321 // If the window is restored from minimized state, do not make the cross |
| 330 // fade animation and set the child bounds directly. The restoring | 322 // fade animation and set the child bounds directly. The restoring |
| 331 // animation will be done by ash/wm/window_animations.cc. | 323 // animation will be done by ash/wm/window_animations.cc. |
| 332 if (last_show_state == ui::SHOW_STATE_MINIMIZED) | 324 if (last_show_state == ui::SHOW_STATE_MINIMIZED) |
| 333 SetChildBoundsDirect(window, new_bounds); | 325 SetChildBoundsDirect(window, new_bounds); |
| 334 else | 326 else |
| 335 CrossFadeToBounds(window, new_bounds); | 327 CrossFadeToBounds(window, new_bounds); |
| 336 break; | 328 break; |
| 337 } | 329 } |
| 338 | 330 |
| 339 case ui::SHOW_STATE_FULLSCREEN: { | 331 case ui::SHOW_STATE_FULLSCREEN: { |
| 340 MoveToDisplayForRestore(window); | 332 MoveToDisplayForRestore(window_state); |
| 341 gfx::Rect new_bounds = ScreenAsh::GetDisplayBoundsInParent( | 333 gfx::Rect new_bounds = ScreenAsh::GetDisplayBoundsInParent( |
| 342 window->parent()->parent()); | 334 window->parent()->parent()); |
| 343 if (window->GetProperty(kAnimateToFullscreenKey) && | 335 if (window->GetProperty(kAnimateToFullscreenKey) && |
| 344 last_show_state != ui::SHOW_STATE_MINIMIZED) { | 336 last_show_state != ui::SHOW_STATE_MINIMIZED) { |
| 345 CrossFadeToBounds(window, new_bounds); | 337 CrossFadeToBounds(window, new_bounds); |
| 346 } else { | 338 } else { |
| 347 SetChildBoundsDirect(window, new_bounds); | 339 SetChildBoundsDirect(window, new_bounds); |
| 348 } | 340 } |
| 349 break; | 341 break; |
| 350 } | 342 } |
| 351 | 343 |
| 352 default: | 344 default: |
| 353 break; | 345 break; |
| 354 } | 346 } |
| 355 } | 347 } |
| 356 | 348 |
| 357 bool WorkspaceLayoutManager::SetMaximizedOrFullscreenBounds( | 349 bool WorkspaceLayoutManager::SetMaximizedOrFullscreenBounds( |
| 358 aura::Window* window) { | 350 wm::WindowState* window_state) { |
| 359 if (!wm::GetWindowSettings(window)->tracked_by_workspace()) | 351 if (!window_state->tracked_by_workspace()) |
| 360 return false; | 352 return false; |
| 361 | 353 |
| 362 // During animations there is a transform installed on the workspace | 354 // During animations there is a transform installed on the workspace |
| 363 // windows. For this reason this code uses the parent so that the transform is | 355 // windows. For this reason this code uses the parent so that the transform is |
| 364 // ignored. | 356 // ignored. |
| 365 if (wm::IsWindowMaximized(window)) { | 357 if (window_state->IsMaximized()) { |
| 366 SetChildBoundsDirect( | 358 SetChildBoundsDirect( |
| 367 window, ScreenAsh::GetMaximizedWindowBoundsInParent( | 359 window_state->window(), ScreenAsh::GetMaximizedWindowBoundsInParent( |
| 368 window->parent()->parent())); | 360 window_state->window()->parent()->parent())); |
| 369 return true; | 361 return true; |
| 370 } | 362 } |
| 371 if (wm::IsWindowFullscreen(window)) { | 363 if (window_state->IsFullscreen()) { |
| 372 SetChildBoundsDirect( | 364 SetChildBoundsDirect( |
| 373 window, | 365 window_state->window(), |
| 374 ScreenAsh::GetDisplayBoundsInParent(window->parent()->parent())); | 366 ScreenAsh::GetDisplayBoundsInParent( |
| 367 window_state->window()->parent()->parent())); |
| 375 return true; | 368 return true; |
| 376 } | 369 } |
| 377 return false; | 370 return false; |
| 378 } | 371 } |
| 379 | 372 |
| 380 } // namespace internal | 373 } // namespace internal |
| 381 } // namespace ash | 374 } // namespace ash |
| OLD | NEW |