| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/common/wm/window_positioner.h" | 5 #include "ash/common/wm/window_positioner.h" |
| 6 | 6 |
| 7 #include "ash/common/wm/window_positioning_utils.h" | 7 #include "ash/common/wm/window_positioning_utils.h" |
| 8 #include "ash/common/wm/window_state.h" | 8 #include "ash/common/wm/window_state.h" |
| 9 #include "ash/common/wm/wm_globals.h" | |
| 10 #include "ash/common/wm/wm_screen_util.h" | 9 #include "ash/common/wm/wm_screen_util.h" |
| 11 #include "ash/common/wm/wm_window.h" | 10 #include "ash/common/wm_shell.h" |
| 11 #include "ash/common/wm_window.h" |
| 12 #include "ui/compositor/layer.h" | 12 #include "ui/compositor/layer.h" |
| 13 #include "ui/display/display.h" | 13 #include "ui/display/display.h" |
| 14 #include "ui/display/screen.h" | 14 #include "ui/display/screen.h" |
| 15 #include "ui/gfx/geometry/insets.h" | 15 #include "ui/gfx/geometry/insets.h" |
| 16 | 16 |
| 17 namespace ash { | 17 namespace ash { |
| 18 | 18 |
| 19 const int WindowPositioner::kMinimumWindowOffset = 32; | 19 const int WindowPositioner::kMinimumWindowOffset = 32; |
| 20 | 20 |
| 21 // The number of pixels which are kept free top, left and right when a window | 21 // The number of pixels which are kept free top, left and right when a window |
| (...skipping 17 matching lines...) Expand all Loading... |
| 39 const int kWindowAutoMoveDurationMS = 125; | 39 const int kWindowAutoMoveDurationMS = 125; |
| 40 | 40 |
| 41 // If set to true all window repositioning actions will be ignored. Set through | 41 // If set to true all window repositioning actions will be ignored. Set through |
| 42 // WindowPositioner::SetIgnoreActivations(). | 42 // WindowPositioner::SetIgnoreActivations(). |
| 43 static bool disable_auto_positioning = false; | 43 static bool disable_auto_positioning = false; |
| 44 | 44 |
| 45 // If set to true, by default the first window in ASH will be maximized. | 45 // If set to true, by default the first window in ASH will be maximized. |
| 46 static bool maximize_first_window = false; | 46 static bool maximize_first_window = false; |
| 47 | 47 |
| 48 // Check if any management should be performed (with a given |window|). | 48 // Check if any management should be performed (with a given |window|). |
| 49 bool UseAutoWindowManager(const wm::WmWindow* window) { | 49 bool UseAutoWindowManager(const WmWindow* window) { |
| 50 if (disable_auto_positioning) | 50 if (disable_auto_positioning) |
| 51 return false; | 51 return false; |
| 52 const wm::WindowState* window_state = window->GetWindowState(); | 52 const wm::WindowState* window_state = window->GetWindowState(); |
| 53 return !window_state->is_dragged() && window_state->window_position_managed(); | 53 return !window_state->is_dragged() && window_state->window_position_managed(); |
| 54 } | 54 } |
| 55 | 55 |
| 56 // Check if a given |window| can be managed. This includes that its | 56 // Check if a given |window| can be managed. This includes that its |
| 57 // state is not minimized/maximized/fullscreen/the user has changed | 57 // state is not minimized/maximized/fullscreen/the user has changed |
| 58 // its size by hand already. It furthermore checks for the | 58 // its size by hand already. It furthermore checks for the |
| 59 // WindowIsManaged status. | 59 // WindowIsManaged status. |
| 60 bool WindowPositionCanBeManaged(const wm::WmWindow* window) { | 60 bool WindowPositionCanBeManaged(const WmWindow* window) { |
| 61 if (disable_auto_positioning) | 61 if (disable_auto_positioning) |
| 62 return false; | 62 return false; |
| 63 const wm::WindowState* window_state = window->GetWindowState(); | 63 const wm::WindowState* window_state = window->GetWindowState(); |
| 64 return window_state->window_position_managed() && | 64 return window_state->window_position_managed() && |
| 65 !window_state->IsMinimized() && !window_state->IsMaximized() && | 65 !window_state->IsMinimized() && !window_state->IsMaximized() && |
| 66 !window_state->IsFullscreen() && | 66 !window_state->IsFullscreen() && |
| 67 !window_state->bounds_changed_by_user(); | 67 !window_state->bounds_changed_by_user(); |
| 68 } | 68 } |
| 69 | 69 |
| 70 // Move the given |bounds| on the available |work_area| in the direction | 70 // Move the given |bounds| on the available |work_area| in the direction |
| (...skipping 12 matching lines...) Expand all Loading... |
| 83 bounds->set_x(work_area.x()); | 83 bounds->set_x(work_area.x()); |
| 84 return true; | 84 return true; |
| 85 } | 85 } |
| 86 } | 86 } |
| 87 return false; | 87 return false; |
| 88 } | 88 } |
| 89 | 89 |
| 90 // Move a |window| to new |bounds|. Animate if desired by user. | 90 // Move a |window| to new |bounds|. Animate if desired by user. |
| 91 // Moves the transient children of the |window| as well by the same |offset| as | 91 // Moves the transient children of the |window| as well by the same |offset| as |
| 92 // the parent |window|. | 92 // the parent |window|. |
| 93 void SetBoundsAndOffsetTransientChildren(wm::WmWindow* window, | 93 void SetBoundsAndOffsetTransientChildren(WmWindow* window, |
| 94 const gfx::Rect& bounds, | 94 const gfx::Rect& bounds, |
| 95 const gfx::Rect& work_area, | 95 const gfx::Rect& work_area, |
| 96 const gfx::Vector2d& offset) { | 96 const gfx::Vector2d& offset) { |
| 97 std::vector<wm::WmWindow*> transient_children = | 97 std::vector<WmWindow*> transient_children = window->GetTransientChildren(); |
| 98 window->GetTransientChildren(); | 98 for (WmWindow* transient_child : transient_children) { |
| 99 for (wm::WmWindow* transient_child : transient_children) { | |
| 100 gfx::Rect child_bounds = transient_child->GetBounds(); | 99 gfx::Rect child_bounds = transient_child->GetBounds(); |
| 101 gfx::Rect new_child_bounds = child_bounds + offset; | 100 gfx::Rect new_child_bounds = child_bounds + offset; |
| 102 if ((child_bounds.x() <= work_area.x() && | 101 if ((child_bounds.x() <= work_area.x() && |
| 103 new_child_bounds.x() <= work_area.x()) || | 102 new_child_bounds.x() <= work_area.x()) || |
| 104 (child_bounds.right() >= work_area.right() && | 103 (child_bounds.right() >= work_area.right() && |
| 105 new_child_bounds.right() >= work_area.right())) { | 104 new_child_bounds.right() >= work_area.right())) { |
| 106 continue; | 105 continue; |
| 107 } | 106 } |
| 108 if (new_child_bounds.right() > work_area.right()) | 107 if (new_child_bounds.right() > work_area.right()) |
| 109 new_child_bounds.set_x(work_area.right() - bounds.width()); | 108 new_child_bounds.set_x(work_area.right() - bounds.width()); |
| 110 else if (new_child_bounds.x() < work_area.x()) | 109 else if (new_child_bounds.x() < work_area.x()) |
| 111 new_child_bounds.set_x(work_area.x()); | 110 new_child_bounds.set_x(work_area.x()); |
| 112 SetBoundsAndOffsetTransientChildren(transient_child, new_child_bounds, | 111 SetBoundsAndOffsetTransientChildren(transient_child, new_child_bounds, |
| 113 work_area, offset); | 112 work_area, offset); |
| 114 } | 113 } |
| 115 | 114 |
| 116 window->SetBoundsWithTransitionDelay( | 115 window->SetBoundsWithTransitionDelay( |
| 117 bounds, base::TimeDelta::FromMilliseconds(kWindowAutoMoveDurationMS)); | 116 bounds, base::TimeDelta::FromMilliseconds(kWindowAutoMoveDurationMS)); |
| 118 } | 117 } |
| 119 | 118 |
| 120 // Move a |window| to new |bounds|. Animate if desired by user. | 119 // Move a |window| to new |bounds|. Animate if desired by user. |
| 121 // Note: The function will do nothing if the bounds did not change. | 120 // Note: The function will do nothing if the bounds did not change. |
| 122 void SetBoundsAnimated(wm::WmWindow* window, | 121 void SetBoundsAnimated(WmWindow* window, |
| 123 const gfx::Rect& bounds, | 122 const gfx::Rect& bounds, |
| 124 const gfx::Rect& work_area) { | 123 const gfx::Rect& work_area) { |
| 125 gfx::Rect old_bounds = window->GetTargetBounds(); | 124 gfx::Rect old_bounds = window->GetTargetBounds(); |
| 126 if (bounds == old_bounds) | 125 if (bounds == old_bounds) |
| 127 return; | 126 return; |
| 128 gfx::Vector2d offset(bounds.origin() - old_bounds.origin()); | 127 gfx::Vector2d offset(bounds.origin() - old_bounds.origin()); |
| 129 SetBoundsAndOffsetTransientChildren(window, bounds, work_area, offset); | 128 SetBoundsAndOffsetTransientChildren(window, bounds, work_area, offset); |
| 130 } | 129 } |
| 131 | 130 |
| 132 // Move |window| into the center of the screen - or restore it to the previous | 131 // Move |window| into the center of the screen - or restore it to the previous |
| 133 // position. | 132 // position. |
| 134 void AutoPlaceSingleWindow(wm::WmWindow* window, bool animated) { | 133 void AutoPlaceSingleWindow(WmWindow* window, bool animated) { |
| 135 gfx::Rect work_area = GetDisplayWorkAreaBoundsInParent(window); | 134 gfx::Rect work_area = wm::GetDisplayWorkAreaBoundsInParent(window); |
| 136 gfx::Rect bounds = window->GetBounds(); | 135 gfx::Rect bounds = window->GetBounds(); |
| 137 const gfx::Rect* user_defined_area = | 136 const gfx::Rect* user_defined_area = |
| 138 window->GetWindowState()->pre_auto_manage_window_bounds(); | 137 window->GetWindowState()->pre_auto_manage_window_bounds(); |
| 139 if (user_defined_area) { | 138 if (user_defined_area) { |
| 140 bounds = *user_defined_area; | 139 bounds = *user_defined_area; |
| 141 wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area, &bounds); | 140 wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area, &bounds); |
| 142 } else { | 141 } else { |
| 143 // Center the window (only in x). | 142 // Center the window (only in x). |
| 144 bounds.set_x(work_area.x() + (work_area.width() - bounds.width()) / 2); | 143 bounds.set_x(work_area.x() + (work_area.width() - bounds.width()) / 2); |
| 145 } | 144 } |
| 146 | 145 |
| 147 if (animated) | 146 if (animated) |
| 148 SetBoundsAnimated(window, bounds, work_area); | 147 SetBoundsAnimated(window, bounds, work_area); |
| 149 else | 148 else |
| 150 window->SetBounds(bounds); | 149 window->SetBounds(bounds); |
| 151 } | 150 } |
| 152 | 151 |
| 153 // Get the first open (non minimized) window which is on the screen defined. | 152 // Get the first open (non minimized) window which is on the screen defined. |
| 154 wm::WmWindow* GetReferenceWindow(const wm::WmWindow* root_window, | 153 WmWindow* GetReferenceWindow(const WmWindow* root_window, |
| 155 const wm::WmWindow* exclude, | 154 const WmWindow* exclude, |
| 156 bool* single_window) { | 155 bool* single_window) { |
| 157 if (single_window) | 156 if (single_window) |
| 158 *single_window = true; | 157 *single_window = true; |
| 159 // Get the active window. | 158 // Get the active window. |
| 160 wm::WmWindow* active = root_window->GetGlobals()->GetActiveWindow(); | 159 WmWindow* active = root_window->GetShell()->GetActiveWindow(); |
| 161 if (active && active->GetRootWindow() != root_window) | 160 if (active && active->GetRootWindow() != root_window) |
| 162 active = NULL; | 161 active = NULL; |
| 163 | 162 |
| 164 // Get a list of all windows. | 163 // Get a list of all windows. |
| 165 const std::vector<wm::WmWindow*> windows = | 164 const std::vector<WmWindow*> windows = |
| 166 root_window->GetGlobals()->GetMruWindowListIgnoreModals(); | 165 root_window->GetShell()->GetMruWindowListIgnoreModals(); |
| 167 | 166 |
| 168 if (windows.empty()) | 167 if (windows.empty()) |
| 169 return nullptr; | 168 return nullptr; |
| 170 | 169 |
| 171 int index = 0; | 170 int index = 0; |
| 172 // Find the index of the current active window. | 171 // Find the index of the current active window. |
| 173 if (active) | 172 if (active) |
| 174 index = std::find(windows.begin(), windows.end(), active) - windows.begin(); | 173 index = std::find(windows.begin(), windows.end(), active) - windows.begin(); |
| 175 | 174 |
| 176 // Scan the cycle list backwards to see which is the second topmost window | 175 // Scan the cycle list backwards to see which is the second topmost window |
| 177 // (and so on). Note that we might cycle a few indices twice if there is no | 176 // (and so on). Note that we might cycle a few indices twice if there is no |
| 178 // suitable window. However - since the list is fairly small this should be | 177 // suitable window. However - since the list is fairly small this should be |
| 179 // very fast anyways. | 178 // very fast anyways. |
| 180 wm::WmWindow* found = nullptr; | 179 WmWindow* found = nullptr; |
| 181 for (int i = index + windows.size(); i >= 0; i--) { | 180 for (int i = index + windows.size(); i >= 0; i--) { |
| 182 wm::WmWindow* window = windows[i % windows.size()]; | 181 WmWindow* window = windows[i % windows.size()]; |
| 183 while (window->GetTransientParent()) | 182 while (window->GetTransientParent()) |
| 184 window = window->GetTransientParent(); | 183 window = window->GetTransientParent(); |
| 185 if (window != exclude && window->GetType() == ui::wm::WINDOW_TYPE_NORMAL && | 184 if (window != exclude && window->GetType() == ui::wm::WINDOW_TYPE_NORMAL && |
| 186 window->GetRootWindow() == root_window && | 185 window->GetRootWindow() == root_window && |
| 187 window->GetTargetVisibility() && | 186 window->GetTargetVisibility() && |
| 188 window->GetWindowState()->window_position_managed()) { | 187 window->GetWindowState()->window_position_managed()) { |
| 189 if (found && found != window) { | 188 if (found && found != window) { |
| 190 // no need to check !single_window because the function must have | 189 // no need to check !single_window because the function must have |
| 191 // been already returned in the "if (!single_window)" below. | 190 // been already returned in the "if (!single_window)" below. |
| 192 *single_window = false; | 191 *single_window = false; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 203 | 202 |
| 204 } // namespace | 203 } // namespace |
| 205 | 204 |
| 206 // static | 205 // static |
| 207 int WindowPositioner::GetForceMaximizedWidthLimit() { | 206 int WindowPositioner::GetForceMaximizedWidthLimit() { |
| 208 return kForceMaximizeWidthLimit; | 207 return kForceMaximizeWidthLimit; |
| 209 } | 208 } |
| 210 | 209 |
| 211 // static | 210 // static |
| 212 void WindowPositioner::GetBoundsAndShowStateForNewWindow( | 211 void WindowPositioner::GetBoundsAndShowStateForNewWindow( |
| 213 const wm::WmWindow* new_window, | 212 const WmWindow* new_window, |
| 214 bool is_saved_bounds, | 213 bool is_saved_bounds, |
| 215 ui::WindowShowState show_state_in, | 214 ui::WindowShowState show_state_in, |
| 216 gfx::Rect* bounds_in_out, | 215 gfx::Rect* bounds_in_out, |
| 217 ui::WindowShowState* show_state_out) { | 216 ui::WindowShowState* show_state_out) { |
| 218 // Always open new window in the target display. | 217 // Always open new window in the target display. |
| 219 wm::WmWindow* target = wm::WmGlobals::Get()->GetRootWindowForNewWindows(); | 218 WmWindow* target = WmShell::Get()->GetRootWindowForNewWindows(); |
| 220 | 219 |
| 221 wm::WmWindow* top_window = GetReferenceWindow(target, nullptr, nullptr); | 220 WmWindow* top_window = GetReferenceWindow(target, nullptr, nullptr); |
| 222 // Our window should not have any impact if we are already on top. | 221 // Our window should not have any impact if we are already on top. |
| 223 if (top_window == new_window) | 222 if (top_window == new_window) |
| 224 top_window = nullptr; | 223 top_window = nullptr; |
| 225 | 224 |
| 226 // If there is no valid other window we take and adjust the passed coordinates | 225 // If there is no valid other window we take and adjust the passed coordinates |
| 227 // and show state. | 226 // and show state. |
| 228 if (!top_window) { | 227 if (!top_window) { |
| 229 gfx::Rect work_area = target->GetDisplayNearestWindow().work_area(); | 228 gfx::Rect work_area = target->GetDisplayNearestWindow().work_area(); |
| 230 | 229 |
| 231 bounds_in_out->AdjustToFit(work_area); | 230 bounds_in_out->AdjustToFit(work_area); |
| 232 // Use adjusted saved bounds, if there is one. | 231 // Use adjusted saved bounds, if there is one. |
| 233 if (is_saved_bounds) | 232 if (is_saved_bounds) |
| 234 return; | 233 return; |
| 235 | 234 |
| 236 if (show_state_in == ui::SHOW_STATE_DEFAULT) { | 235 if (show_state_in == ui::SHOW_STATE_DEFAULT) { |
| 237 const bool maximize_first_window_on_first_run = | 236 const bool maximize_first_window_on_first_run = |
| 238 target->GetGlobals()->IsForceMaximizeOnFirstRun(); | 237 target->GetShell()->IsForceMaximizeOnFirstRun(); |
| 239 // We want to always open maximized on "small screens" or when policy | 238 // We want to always open maximized on "small screens" or when policy |
| 240 // tells us to. | 239 // tells us to. |
| 241 const bool set_maximized = | 240 const bool set_maximized = |
| 242 maximize_first_window || | 241 maximize_first_window || |
| 243 ((work_area.width() <= GetForceMaximizedWidthLimit() || | 242 ((work_area.width() <= GetForceMaximizedWidthLimit() || |
| 244 maximize_first_window_on_first_run) && | 243 maximize_first_window_on_first_run) && |
| 245 (!new_window || !new_window->GetWindowState()->IsFullscreen())); | 244 (!new_window || !new_window->GetWindowState()->IsFullscreen())); |
| 246 | 245 |
| 247 if (set_maximized) | 246 if (set_maximized) |
| 248 *show_state_out = ui::SHOW_STATE_MAXIMIZED; | 247 *show_state_out = ui::SHOW_STATE_MAXIMIZED; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 278 } | 277 } |
| 279 } | 278 } |
| 280 | 279 |
| 281 // Use the size of the other window. The window's bound will be rearranged | 280 // Use the size of the other window. The window's bound will be rearranged |
| 282 // in ash::WorkspaceLayoutManager using this location. | 281 // in ash::WorkspaceLayoutManager using this location. |
| 283 *bounds_in_out = top_window->GetBoundsInScreen(); | 282 *bounds_in_out = top_window->GetBoundsInScreen(); |
| 284 } | 283 } |
| 285 | 284 |
| 286 // static | 285 // static |
| 287 void WindowPositioner::RearrangeVisibleWindowOnHideOrRemove( | 286 void WindowPositioner::RearrangeVisibleWindowOnHideOrRemove( |
| 288 const wm::WmWindow* removed_window) { | 287 const WmWindow* removed_window) { |
| 289 if (!UseAutoWindowManager(removed_window)) | 288 if (!UseAutoWindowManager(removed_window)) |
| 290 return; | 289 return; |
| 291 // Find a single open browser window. | 290 // Find a single open browser window. |
| 292 bool single_window; | 291 bool single_window; |
| 293 wm::WmWindow* other_shown_window = GetReferenceWindow( | 292 WmWindow* other_shown_window = GetReferenceWindow( |
| 294 removed_window->GetRootWindow(), removed_window, &single_window); | 293 removed_window->GetRootWindow(), removed_window, &single_window); |
| 295 if (!other_shown_window || !single_window || | 294 if (!other_shown_window || !single_window || |
| 296 !WindowPositionCanBeManaged(other_shown_window)) | 295 !WindowPositionCanBeManaged(other_shown_window)) |
| 297 return; | 296 return; |
| 298 AutoPlaceSingleWindow(other_shown_window, true); | 297 AutoPlaceSingleWindow(other_shown_window, true); |
| 299 } | 298 } |
| 300 | 299 |
| 301 // static | 300 // static |
| 302 bool WindowPositioner::DisableAutoPositioning(bool ignore) { | 301 bool WindowPositioner::DisableAutoPositioning(bool ignore) { |
| 303 bool old_state = disable_auto_positioning; | 302 bool old_state = disable_auto_positioning; |
| 304 disable_auto_positioning = ignore; | 303 disable_auto_positioning = ignore; |
| 305 return old_state; | 304 return old_state; |
| 306 } | 305 } |
| 307 | 306 |
| 308 // static | 307 // static |
| 309 void WindowPositioner::RearrangeVisibleWindowOnShow( | 308 void WindowPositioner::RearrangeVisibleWindowOnShow(WmWindow* added_window) { |
| 310 wm::WmWindow* added_window) { | |
| 311 wm::WindowState* added_window_state = added_window->GetWindowState(); | 309 wm::WindowState* added_window_state = added_window->GetWindowState(); |
| 312 if (!added_window->GetTargetVisibility()) | 310 if (!added_window->GetTargetVisibility()) |
| 313 return; | 311 return; |
| 314 | 312 |
| 315 if (!UseAutoWindowManager(added_window) || | 313 if (!UseAutoWindowManager(added_window) || |
| 316 added_window_state->bounds_changed_by_user()) { | 314 added_window_state->bounds_changed_by_user()) { |
| 317 if (added_window_state->minimum_visibility()) { | 315 if (added_window_state->minimum_visibility()) { |
| 318 // Guarantee minimum visibility within the work area. | 316 // Guarantee minimum visibility within the work area. |
| 319 gfx::Rect work_area = GetDisplayWorkAreaBoundsInParent(added_window); | 317 gfx::Rect work_area = wm::GetDisplayWorkAreaBoundsInParent(added_window); |
| 320 gfx::Rect bounds = added_window->GetBounds(); | 318 gfx::Rect bounds = added_window->GetBounds(); |
| 321 gfx::Rect new_bounds = bounds; | 319 gfx::Rect new_bounds = bounds; |
| 322 wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area, &new_bounds); | 320 wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area, &new_bounds); |
| 323 if (new_bounds != bounds) | 321 if (new_bounds != bounds) |
| 324 added_window->SetBounds(new_bounds); | 322 added_window->SetBounds(new_bounds); |
| 325 } | 323 } |
| 326 return; | 324 return; |
| 327 } | 325 } |
| 328 // Find a single open managed window. | 326 // Find a single open managed window. |
| 329 bool single_window; | 327 bool single_window; |
| 330 wm::WmWindow* other_shown_window = GetReferenceWindow( | 328 WmWindow* other_shown_window = GetReferenceWindow( |
| 331 added_window->GetRootWindow(), added_window, &single_window); | 329 added_window->GetRootWindow(), added_window, &single_window); |
| 332 | 330 |
| 333 if (!other_shown_window) { | 331 if (!other_shown_window) { |
| 334 // It could be that this window is the first window joining the workspace. | 332 // It could be that this window is the first window joining the workspace. |
| 335 if (!WindowPositionCanBeManaged(added_window) || other_shown_window) | 333 if (!WindowPositionCanBeManaged(added_window) || other_shown_window) |
| 336 return; | 334 return; |
| 337 // Since we might be going from 0 to 1 window, we have to arrange the new | 335 // Since we might be going from 0 to 1 window, we have to arrange the new |
| 338 // window to a good default. | 336 // window to a good default. |
| 339 AutoPlaceSingleWindow(added_window, false); | 337 AutoPlaceSingleWindow(added_window, false); |
| 340 return; | 338 return; |
| 341 } | 339 } |
| 342 | 340 |
| 343 gfx::Rect other_bounds = other_shown_window->GetBounds(); | 341 gfx::Rect other_bounds = other_shown_window->GetBounds(); |
| 344 gfx::Rect work_area = GetDisplayWorkAreaBoundsInParent(added_window); | 342 gfx::Rect work_area = wm::GetDisplayWorkAreaBoundsInParent(added_window); |
| 345 bool move_other_right = | 343 bool move_other_right = |
| 346 other_bounds.CenterPoint().x() > work_area.x() + work_area.width() / 2; | 344 other_bounds.CenterPoint().x() > work_area.x() + work_area.width() / 2; |
| 347 | 345 |
| 348 // Push the other window to the size only if there are two windows left. | 346 // Push the other window to the size only if there are two windows left. |
| 349 if (single_window) { | 347 if (single_window) { |
| 350 // When going from one to two windows both windows loose their | 348 // When going from one to two windows both windows loose their |
| 351 // "positioned by user" flags. | 349 // "positioned by user" flags. |
| 352 added_window_state->set_bounds_changed_by_user(false); | 350 added_window_state->set_bounds_changed_by_user(false); |
| 353 wm::WindowState* other_window_state = other_shown_window->GetWindowState(); | 351 wm::WindowState* other_window_state = other_shown_window->GetWindowState(); |
| 354 other_window_state->set_bounds_changed_by_user(false); | 352 other_window_state->set_bounds_changed_by_user(false); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 368 // Remember the current location of the window if it's new and push | 366 // Remember the current location of the window if it's new and push |
| 369 // it also to the opposite location if needed. Since it is just | 367 // it also to the opposite location if needed. Since it is just |
| 370 // being shown, we do not need to animate it. | 368 // being shown, we do not need to animate it. |
| 371 gfx::Rect added_bounds = added_window->GetBounds(); | 369 gfx::Rect added_bounds = added_window->GetBounds(); |
| 372 if (!added_window_state->pre_auto_manage_window_bounds()) | 370 if (!added_window_state->pre_auto_manage_window_bounds()) |
| 373 added_window_state->SetPreAutoManageWindowBounds(added_bounds); | 371 added_window_state->SetPreAutoManageWindowBounds(added_bounds); |
| 374 if (MoveRectToOneSide(work_area, !move_other_right, &added_bounds)) | 372 if (MoveRectToOneSide(work_area, !move_other_right, &added_bounds)) |
| 375 added_window->SetBounds(added_bounds); | 373 added_window->SetBounds(added_bounds); |
| 376 } | 374 } |
| 377 | 375 |
| 378 WindowPositioner::WindowPositioner(wm::WmGlobals* globals) | 376 WindowPositioner::WindowPositioner(WmShell* shell) |
| 379 : globals_(globals), | 377 : shell_(shell), |
| 380 pop_position_offset_increment_x(0), | 378 pop_position_offset_increment_x(0), |
| 381 pop_position_offset_increment_y(0), | 379 pop_position_offset_increment_y(0), |
| 382 popup_position_offset_from_screen_corner_x(0), | 380 popup_position_offset_from_screen_corner_x(0), |
| 383 popup_position_offset_from_screen_corner_y(0), | 381 popup_position_offset_from_screen_corner_y(0), |
| 384 last_popup_position_x_(0), | 382 last_popup_position_x_(0), |
| 385 last_popup_position_y_(0) {} | 383 last_popup_position_y_(0) {} |
| 386 | 384 |
| 387 WindowPositioner::~WindowPositioner() {} | 385 WindowPositioner::~WindowPositioner() {} |
| 388 | 386 |
| 389 gfx::Rect WindowPositioner::GetDefaultWindowBounds( | 387 gfx::Rect WindowPositioner::GetDefaultWindowBounds( |
| (...skipping 22 matching lines...) Expand all Loading... |
| 412 if (!pop_position_offset_increment_x) { | 410 if (!pop_position_offset_increment_x) { |
| 413 // When the popup position increment is 0, the last popup position | 411 // When the popup position increment is 0, the last popup position |
| 414 // was not yet initialized. | 412 // was not yet initialized. |
| 415 last_popup_position_x_ = popup_position_offset_from_screen_corner_x; | 413 last_popup_position_x_ = popup_position_offset_from_screen_corner_x; |
| 416 last_popup_position_y_ = popup_position_offset_from_screen_corner_y; | 414 last_popup_position_y_ = popup_position_offset_from_screen_corner_y; |
| 417 } | 415 } |
| 418 pop_position_offset_increment_x = grid; | 416 pop_position_offset_increment_x = grid; |
| 419 pop_position_offset_increment_y = grid; | 417 pop_position_offset_increment_y = grid; |
| 420 // We handle the Multi monitor support by retrieving the active window's | 418 // We handle the Multi monitor support by retrieving the active window's |
| 421 // work area. | 419 // work area. |
| 422 wm::WmWindow* window = globals_->GetActiveWindow(); | 420 WmWindow* window = shell_->GetActiveWindow(); |
| 423 const gfx::Rect work_area = | 421 const gfx::Rect work_area = |
| 424 window && window->IsVisible() | 422 window && window->IsVisible() |
| 425 ? window->GetDisplayNearestWindow().work_area() | 423 ? window->GetDisplayNearestWindow().work_area() |
| 426 : display::Screen::GetScreen()->GetPrimaryDisplay().work_area(); | 424 : display::Screen::GetScreen()->GetPrimaryDisplay().work_area(); |
| 427 // Only try to reposition the popup when it is not spanning the entire | 425 // Only try to reposition the popup when it is not spanning the entire |
| 428 // screen. | 426 // screen. |
| 429 if ((old_pos.width() + popup_position_offset_from_screen_corner_x >= | 427 if ((old_pos.width() + popup_position_offset_from_screen_corner_x >= |
| 430 work_area.width()) || | 428 work_area.width()) || |
| 431 (old_pos.height() + popup_position_offset_from_screen_corner_y >= | 429 (old_pos.height() + popup_position_offset_from_screen_corner_y >= |
| 432 work_area.height())) | 430 work_area.height())) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 if (!reset) { | 468 if (!reset) { |
| 471 last_popup_position_x_ += pop_position_offset_increment_x; | 469 last_popup_position_x_ += pop_position_offset_increment_x; |
| 472 last_popup_position_y_ += pop_position_offset_increment_y; | 470 last_popup_position_y_ += pop_position_offset_increment_y; |
| 473 } | 471 } |
| 474 return gfx::Rect(x + work_area.x(), y + work_area.y(), w, h); | 472 return gfx::Rect(x + work_area.x(), y + work_area.y(), w, h); |
| 475 } | 473 } |
| 476 | 474 |
| 477 gfx::Rect WindowPositioner::SmartPopupPosition(const gfx::Rect& old_pos, | 475 gfx::Rect WindowPositioner::SmartPopupPosition(const gfx::Rect& old_pos, |
| 478 const gfx::Rect& work_area, | 476 const gfx::Rect& work_area, |
| 479 int grid) { | 477 int grid) { |
| 480 const std::vector<wm::WmWindow*> windows = | 478 const std::vector<WmWindow*> windows = shell_->GetMruWindowListIgnoreModals(); |
| 481 globals_->GetMruWindowListIgnoreModals(); | |
| 482 | 479 |
| 483 std::vector<const gfx::Rect*> regions; | 480 std::vector<const gfx::Rect*> regions; |
| 484 // Process the window list and check if we can bail immediately. | 481 // Process the window list and check if we can bail immediately. |
| 485 for (size_t i = 0; i < windows.size(); i++) { | 482 for (size_t i = 0; i < windows.size(); i++) { |
| 486 // We only include opaque and visible windows. | 483 // We only include opaque and visible windows. |
| 487 if (windows[i] && windows[i]->IsVisible() && windows[i]->GetLayer() && | 484 if (windows[i] && windows[i]->IsVisible() && windows[i]->GetLayer() && |
| 488 (windows[i]->GetLayer()->fills_bounds_opaquely() || | 485 (windows[i]->GetLayer()->fills_bounds_opaquely() || |
| 489 windows[i]->GetLayer()->GetTargetOpacity() == 1.0)) { | 486 windows[i]->GetLayer()->GetTargetOpacity() == 1.0)) { |
| 490 wm::WindowState* window_state = windows[i]->GetWindowState(); | 487 wm::WindowState* window_state = windows[i]->GetWindowState(); |
| 491 // When any window is maximized we cannot find any free space. | 488 // When any window is maximized we cannot find any free space. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 // If the alignment was pushing the window out of the screen, we ignore the | 552 // If the alignment was pushing the window out of the screen, we ignore the |
| 556 // alignment for that call. | 553 // alignment for that call. |
| 557 if (abs(pos.right() - work_area.right()) < grid) | 554 if (abs(pos.right() - work_area.right()) < grid) |
| 558 x = work_area.right() - w; | 555 x = work_area.right() - w; |
| 559 if (abs(pos.bottom() - work_area.bottom()) < grid) | 556 if (abs(pos.bottom() - work_area.bottom()) < grid) |
| 560 y = work_area.bottom() - h; | 557 y = work_area.bottom() - h; |
| 561 return gfx::Rect(x, y, w, h); | 558 return gfx::Rect(x, y, w, h); |
| 562 } | 559 } |
| 563 | 560 |
| 564 } // namespace ash | 561 } // namespace ash |
| OLD | NEW |