| 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/wm/window_positioner.h" | 5 #include "ash/wm/window_positioner.h" |
| 6 | 6 |
| 7 #include "ash/screen_util.h" | 7 #include "ash/wm/common/window_positioning_utils.h" |
| 8 #include "ash/shell.h" | 8 #include "ash/wm/common/wm_globals.h" |
| 9 #include "ash/shell_delegate.h" | 9 #include "ash/wm/common/wm_screen_util.h" |
| 10 #include "ash/shell_window_ids.h" | 10 #include "ash/wm/common/wm_window.h" |
| 11 #include "ash/wm/mru_window_tracker.h" | |
| 12 #include "ash/wm/window_resizer.h" | |
| 13 #include "ash/wm/window_state.h" | 11 #include "ash/wm/window_state.h" |
| 14 #include "ash/wm/window_state_aura.h" | |
| 15 #include "ash/wm/window_util.h" | |
| 16 #include "ui/aura/window.h" | |
| 17 #include "ui/aura/window_delegate.h" | |
| 18 #include "ui/aura/window_event_dispatcher.h" | |
| 19 #include "ui/compositor/layer.h" | 12 #include "ui/compositor/layer.h" |
| 20 #include "ui/compositor/scoped_layer_animation_settings.h" | 13 #include "ui/gfx/geometry/insets.h" |
| 21 #include "ui/gfx/screen.h" | 14 #include "ui/gfx/screen.h" |
| 22 #include "ui/wm/core/window_animations.h" | |
| 23 #include "ui/wm/core/window_util.h" | |
| 24 | 15 |
| 25 namespace ash { | 16 namespace ash { |
| 26 | 17 |
| 27 const int WindowPositioner::kMinimumWindowOffset = 32; | 18 const int WindowPositioner::kMinimumWindowOffset = 32; |
| 28 | 19 |
| 29 // The number of pixels which are kept free top, left and right when a window | 20 // The number of pixels which are kept free top, left and right when a window |
| 30 // gets positioned to its default location. | 21 // gets positioned to its default location. |
| 31 // static | 22 // static |
| 32 const int WindowPositioner::kDesktopBorderSize = 16; | 23 const int WindowPositioner::kDesktopBorderSize = 16; |
| 33 | 24 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 47 const int kWindowAutoMoveDurationMS = 125; | 38 const int kWindowAutoMoveDurationMS = 125; |
| 48 | 39 |
| 49 // If set to true all window repositioning actions will be ignored. Set through | 40 // If set to true all window repositioning actions will be ignored. Set through |
| 50 // WindowPositioner::SetIgnoreActivations(). | 41 // WindowPositioner::SetIgnoreActivations(). |
| 51 static bool disable_auto_positioning = false; | 42 static bool disable_auto_positioning = false; |
| 52 | 43 |
| 53 // If set to true, by default the first window in ASH will be maximized. | 44 // If set to true, by default the first window in ASH will be maximized. |
| 54 static bool maximize_first_window = false; | 45 static bool maximize_first_window = false; |
| 55 | 46 |
| 56 // Check if any management should be performed (with a given |window|). | 47 // Check if any management should be performed (with a given |window|). |
| 57 bool UseAutoWindowManager(const aura::Window* window) { | 48 bool UseAutoWindowManager(const wm::WmWindow* window) { |
| 58 if (disable_auto_positioning) | 49 if (disable_auto_positioning) |
| 59 return false; | 50 return false; |
| 60 const wm::WindowState* window_state = wm::GetWindowState(window); | 51 const wm::WindowState* window_state = window->GetWindowState(); |
| 61 return !window_state->is_dragged() && window_state->window_position_managed(); | 52 return !window_state->is_dragged() && window_state->window_position_managed(); |
| 62 } | 53 } |
| 63 | 54 |
| 64 // Check if a given |window| can be managed. This includes that its | 55 // Check if a given |window| can be managed. This includes that its |
| 65 // state is not minimized/maximized/fullscreen/the user has changed | 56 // state is not minimized/maximized/fullscreen/the user has changed |
| 66 // its size by hand already. It furthermore checks for the | 57 // its size by hand already. It furthermore checks for the |
| 67 // WindowIsManaged status. | 58 // WindowIsManaged status. |
| 68 bool WindowPositionCanBeManaged(const aura::Window* window) { | 59 bool WindowPositionCanBeManaged(const wm::WmWindow* window) { |
| 69 if (disable_auto_positioning) | 60 if (disable_auto_positioning) |
| 70 return false; | 61 return false; |
| 71 const wm::WindowState* window_state = wm::GetWindowState(window); | 62 const wm::WindowState* window_state = window->GetWindowState(); |
| 72 return window_state->window_position_managed() && | 63 return window_state->window_position_managed() && |
| 73 !window_state->IsMinimized() && !window_state->IsMaximized() && | 64 !window_state->IsMinimized() && !window_state->IsMaximized() && |
| 74 !window_state->IsFullscreen() && | 65 !window_state->IsFullscreen() && |
| 75 !window_state->bounds_changed_by_user(); | 66 !window_state->bounds_changed_by_user(); |
| 76 } | 67 } |
| 77 | 68 |
| 78 // Get the work area for a given |window| in parent coordinates. | |
| 79 gfx::Rect GetWorkAreaForWindowInParent(aura::Window* window) { | |
| 80 #if defined(OS_WIN) | |
| 81 // On Win 8, the host window can't be resized, so | |
| 82 // use window's bounds instead. | |
| 83 // TODO(oshima): Emulate host window resize on win8. | |
| 84 gfx::Rect work_area = gfx::Rect(window->parent()->bounds().size()); | |
| 85 work_area.Inset( | |
| 86 gfx::Screen::GetScreen() | |
| 87 ->GetDisplayMatching(window->parent()->GetBoundsInScreen()) | |
| 88 .GetWorkAreaInsets()); | |
| 89 return work_area; | |
| 90 #else | |
| 91 return ScreenUtil::GetDisplayWorkAreaBoundsInParent(window); | |
| 92 #endif | |
| 93 } | |
| 94 | |
| 95 // Move the given |bounds| on the available |work_area| in the direction | 69 // Move the given |bounds| on the available |work_area| in the direction |
| 96 // indicated by |move_right|. If |move_right| is true, the rectangle gets moved | 70 // indicated by |move_right|. If |move_right| is true, the rectangle gets moved |
| 97 // to the right edge, otherwise to the left one. | 71 // to the right edge, otherwise to the left one. |
| 98 bool MoveRectToOneSide(const gfx::Rect& work_area, | 72 bool MoveRectToOneSide(const gfx::Rect& work_area, |
| 99 bool move_right, | 73 bool move_right, |
| 100 gfx::Rect* bounds) { | 74 gfx::Rect* bounds) { |
| 101 if (move_right) { | 75 if (move_right) { |
| 102 if (work_area.right() > bounds->right()) { | 76 if (work_area.right() > bounds->right()) { |
| 103 bounds->set_x(work_area.right() - bounds->width()); | 77 bounds->set_x(work_area.right() - bounds->width()); |
| 104 return true; | 78 return true; |
| 105 } | 79 } |
| 106 } else { | 80 } else { |
| 107 if (work_area.x() < bounds->x()) { | 81 if (work_area.x() < bounds->x()) { |
| 108 bounds->set_x(work_area.x()); | 82 bounds->set_x(work_area.x()); |
| 109 return true; | 83 return true; |
| 110 } | 84 } |
| 111 } | 85 } |
| 112 return false; | 86 return false; |
| 113 } | 87 } |
| 114 | 88 |
| 115 // Move a |window| to new |bounds|. Animate if desired by user. | 89 // Move a |window| to new |bounds|. Animate if desired by user. |
| 116 // Moves the transient children of the |window| as well by the same |offset| as | 90 // Moves the transient children of the |window| as well by the same |offset| as |
| 117 // the parent |window|. | 91 // the parent |window|. |
| 118 void SetBoundsAndOffsetTransientChildren(aura::Window* window, | 92 void SetBoundsAndOffsetTransientChildren(wm::WmWindow* window, |
| 119 const gfx::Rect& bounds, | 93 const gfx::Rect& bounds, |
| 120 const gfx::Rect& work_area, | 94 const gfx::Rect& work_area, |
| 121 const gfx::Vector2d& offset) { | 95 const gfx::Vector2d& offset) { |
| 122 aura::Window::Windows transient_children = | 96 std::vector<wm::WmWindow*> transient_children = |
| 123 ::wm::GetTransientChildren(window); | 97 window->GetTransientChildren(); |
| 124 for (aura::Window::Windows::iterator iter = transient_children.begin(); | 98 for (wm::WmWindow* transient_child : transient_children) { |
| 125 iter != transient_children.end(); ++iter) { | 99 gfx::Rect child_bounds = transient_child->GetBounds(); |
| 126 aura::Window* transient_child = *iter; | |
| 127 gfx::Rect child_bounds = transient_child->bounds(); | |
| 128 gfx::Rect new_child_bounds = child_bounds + offset; | 100 gfx::Rect new_child_bounds = child_bounds + offset; |
| 129 if ((child_bounds.x() <= work_area.x() && | 101 if ((child_bounds.x() <= work_area.x() && |
| 130 new_child_bounds.x() <= work_area.x()) || | 102 new_child_bounds.x() <= work_area.x()) || |
| 131 (child_bounds.right() >= work_area.right() && | 103 (child_bounds.right() >= work_area.right() && |
| 132 new_child_bounds.right() >= work_area.right())) { | 104 new_child_bounds.right() >= work_area.right())) { |
| 133 continue; | 105 continue; |
| 134 } | 106 } |
| 135 if (new_child_bounds.right() > work_area.right()) | 107 if (new_child_bounds.right() > work_area.right()) |
| 136 new_child_bounds.set_x(work_area.right() - bounds.width()); | 108 new_child_bounds.set_x(work_area.right() - bounds.width()); |
| 137 else if (new_child_bounds.x() < work_area.x()) | 109 else if (new_child_bounds.x() < work_area.x()) |
| 138 new_child_bounds.set_x(work_area.x()); | 110 new_child_bounds.set_x(work_area.x()); |
| 139 SetBoundsAndOffsetTransientChildren(transient_child, | 111 SetBoundsAndOffsetTransientChildren(transient_child, |
| 140 new_child_bounds, work_area, offset); | 112 new_child_bounds, work_area, offset); |
| 141 } | 113 } |
| 142 | 114 |
| 143 if (::wm::WindowAnimationsDisabled(window)) { | 115 window->SetBoundsWithTransitionDelay( |
| 144 window->SetBounds(bounds); | 116 bounds, base::TimeDelta::FromMilliseconds(kWindowAutoMoveDurationMS)); |
| 145 return; | |
| 146 } | |
| 147 | |
| 148 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); | |
| 149 settings.SetTransitionDuration( | |
| 150 base::TimeDelta::FromMilliseconds(kWindowAutoMoveDurationMS)); | |
| 151 window->SetBounds(bounds); | |
| 152 } | 117 } |
| 153 | 118 |
| 154 // Move a |window| to new |bounds|. Animate if desired by user. | 119 // Move a |window| to new |bounds|. Animate if desired by user. |
| 155 // 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. |
| 156 void SetBoundsAnimated(aura::Window* window, | 121 void SetBoundsAnimated(wm::WmWindow* window, |
| 157 const gfx::Rect& bounds, | 122 const gfx::Rect& bounds, |
| 158 const gfx::Rect& work_area) { | 123 const gfx::Rect& work_area) { |
| 159 gfx::Rect old_bounds = window->GetTargetBounds(); | 124 gfx::Rect old_bounds = window->GetTargetBounds(); |
| 160 if (bounds == old_bounds) | 125 if (bounds == old_bounds) |
| 161 return; | 126 return; |
| 162 gfx::Vector2d offset(bounds.origin() - old_bounds.origin()); | 127 gfx::Vector2d offset(bounds.origin() - old_bounds.origin()); |
| 163 SetBoundsAndOffsetTransientChildren(window, bounds, work_area, offset); | 128 SetBoundsAndOffsetTransientChildren(window, bounds, work_area, offset); |
| 164 } | 129 } |
| 165 | 130 |
| 166 // 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 |
| 167 // position. | 132 // position. |
| 168 void AutoPlaceSingleWindow(aura::Window* window, bool animated) { | 133 void AutoPlaceSingleWindow(wm::WmWindow* window, bool animated) { |
| 169 gfx::Rect work_area = GetWorkAreaForWindowInParent(window); | 134 gfx::Rect work_area = GetDisplayWorkAreaBoundsInParent(window); |
| 170 gfx::Rect bounds = window->bounds(); | 135 gfx::Rect bounds = window->GetBounds(); |
| 171 const gfx::Rect* user_defined_area = | 136 const gfx::Rect* user_defined_area = |
| 172 wm::GetWindowState(window)->pre_auto_manage_window_bounds(); | 137 window->GetWindowState()->pre_auto_manage_window_bounds(); |
| 173 if (user_defined_area) { | 138 if (user_defined_area) { |
| 174 bounds = *user_defined_area; | 139 bounds = *user_defined_area; |
| 175 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area, &bounds); | 140 wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area, &bounds); |
| 176 } else { | 141 } else { |
| 177 // Center the window (only in x). | 142 // Center the window (only in x). |
| 178 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); |
| 179 } | 144 } |
| 180 | 145 |
| 181 if (animated) | 146 if (animated) |
| 182 SetBoundsAnimated(window, bounds, work_area); | 147 SetBoundsAnimated(window, bounds, work_area); |
| 183 else | 148 else |
| 184 window->SetBounds(bounds); | 149 window->SetBounds(bounds); |
| 185 } | 150 } |
| 186 | 151 |
| 187 // 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. |
| 188 aura::Window* GetReferenceWindow(const aura::Window* root_window, | 153 wm::WmWindow* GetReferenceWindow(const wm::WmWindow* root_window, |
| 189 const aura::Window* exclude, | 154 const wm::WmWindow* exclude, |
| 190 bool *single_window) { | 155 bool* single_window) { |
| 191 if (single_window) | 156 if (single_window) |
| 192 *single_window = true; | 157 *single_window = true; |
| 193 // Get the active window. | 158 // Get the active window. |
| 194 aura::Window* active = ash::wm::GetActiveWindow(); | 159 wm::WmWindow* active = root_window->GetGlobals()->GetActiveWindow(); |
| 195 if (active && active->GetRootWindow() != root_window) | 160 if (active && active->GetRootWindow() != root_window) |
| 196 active = NULL; | 161 active = NULL; |
| 197 | 162 |
| 198 // Get a list of all windows. | 163 // Get a list of all windows. |
| 199 const std::vector<aura::Window*> windows = ash::Shell::GetInstance()-> | 164 const std::vector<wm::WmWindow*> windows = |
| 200 mru_window_tracker()->BuildWindowListIgnoreModal(); | 165 root_window->GetGlobals()->GetMruWindowListIgnoreModals(); |
| 201 | 166 |
| 202 if (windows.empty()) | 167 if (windows.empty()) |
| 203 return NULL; | 168 return nullptr; |
| 204 | 169 |
| 205 aura::Window::Windows::const_iterator iter = windows.begin(); | 170 int index = 0; |
| 206 // Find the index of the current active window. | 171 // Find the index of the current active window. |
| 207 if (active) | 172 if (active) |
| 208 iter = std::find(windows.begin(), windows.end(), active); | 173 index = std::find(windows.begin(), windows.end(), active) - windows.begin(); |
| 209 | |
| 210 int index = (iter == windows.end()) ? 0 : (iter - windows.begin()); | |
| 211 | 174 |
| 212 // 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 |
| 213 // (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 |
| 214 // 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 |
| 215 // very fast anyways. | 178 // very fast anyways. |
| 216 aura::Window* found = NULL; | 179 wm::WmWindow* found = nullptr; |
| 217 for (int i = index + windows.size(); i >= 0; i--) { | 180 for (int i = index + windows.size(); i >= 0; i--) { |
| 218 aura::Window* window = windows[i % windows.size()]; | 181 wm::WmWindow* window = windows[i % windows.size()]; |
| 219 while (::wm::GetTransientParent(window)) | 182 while (window->GetTransientParent()) |
| 220 window = ::wm::GetTransientParent(window); | 183 window = window->GetTransientParent(); |
| 221 if (window != exclude && window->type() == ui::wm::WINDOW_TYPE_NORMAL && | 184 if (window != exclude && window->GetType() == ui::wm::WINDOW_TYPE_NORMAL && |
| 222 window->GetRootWindow() == root_window && window->TargetVisibility() && | 185 window->GetRootWindow() == root_window && |
| 223 wm::GetWindowState(window)->window_position_managed()) { | 186 window->GetTargetVisibility() && |
| 187 window->GetWindowState()->window_position_managed()) { |
| 224 if (found && found != window) { | 188 if (found && found != window) { |
| 225 // no need to check !single_window because the function must have | 189 // no need to check !single_window because the function must have |
| 226 // been already returned in the "if (!single_window)" below. | 190 // been already returned in the "if (!single_window)" below. |
| 227 *single_window = false; | 191 *single_window = false; |
| 228 return found; | 192 return found; |
| 229 } | 193 } |
| 230 found = window; | 194 found = window; |
| 231 // If there is no need to check single window, return now. | 195 // If there is no need to check single window, return now. |
| 232 if (!single_window) | 196 if (!single_window) |
| 233 return found; | 197 return found; |
| 234 } | 198 } |
| 235 } | 199 } |
| 236 return found; | 200 return found; |
| 237 } | 201 } |
| 238 | 202 |
| 239 } // namespace | 203 } // namespace |
| 240 | 204 |
| 241 // static | 205 // static |
| 242 int WindowPositioner::GetForceMaximizedWidthLimit() { | 206 int WindowPositioner::GetForceMaximizedWidthLimit() { |
| 243 return kForceMaximizeWidthLimit; | 207 return kForceMaximizeWidthLimit; |
| 244 } | 208 } |
| 245 | 209 |
| 246 // static | 210 // static |
| 247 void WindowPositioner::GetBoundsAndShowStateForNewWindow( | 211 void WindowPositioner::GetBoundsAndShowStateForNewWindow( |
| 248 const gfx::Screen* screen, | 212 const wm::WmWindow* new_window, |
| 249 const aura::Window* new_window, | |
| 250 bool is_saved_bounds, | 213 bool is_saved_bounds, |
| 251 ui::WindowShowState show_state_in, | 214 ui::WindowShowState show_state_in, |
| 252 gfx::Rect* bounds_in_out, | 215 gfx::Rect* bounds_in_out, |
| 253 ui::WindowShowState* show_state_out) { | 216 ui::WindowShowState* show_state_out) { |
| 254 // Always open new window in the target display. | 217 // Always open new window in the target display. |
| 255 aura::Window* target = Shell::GetTargetRootWindow(); | 218 wm::WmWindow* target = wm::WmGlobals::Get()->GetRootWindowForNewWindows(); |
| 256 | 219 |
| 257 aura::Window* top_window = GetReferenceWindow(target, NULL, NULL); | 220 wm::WmWindow* top_window = GetReferenceWindow(target, nullptr, nullptr); |
| 258 // 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. |
| 259 if (top_window == new_window) | 222 if (top_window == new_window) |
| 260 top_window = NULL; | 223 top_window = nullptr; |
| 261 | 224 |
| 262 // 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 |
| 263 // and show state. | 226 // and show state. |
| 264 if (!top_window) { | 227 if (!top_window) { |
| 265 gfx::Rect work_area = screen->GetDisplayNearestWindow(target).work_area(); | 228 gfx::Rect work_area = target->GetDisplayNearestWindow().work_area(); |
| 266 | 229 |
| 267 bounds_in_out->AdjustToFit(work_area); | 230 bounds_in_out->AdjustToFit(work_area); |
| 268 // Use adjusted saved bounds, if there is one. | 231 // Use adjusted saved bounds, if there is one. |
| 269 if (is_saved_bounds) | 232 if (is_saved_bounds) |
| 270 return; | 233 return; |
| 271 | 234 |
| 272 if (show_state_in == ui::SHOW_STATE_DEFAULT) { | 235 if (show_state_in == ui::SHOW_STATE_DEFAULT) { |
| 273 const bool maximize_first_window_on_first_run = | 236 const bool maximize_first_window_on_first_run = |
| 274 Shell::GetInstance()->delegate()->IsForceMaximizeOnFirstRun(); | 237 target->GetGlobals()->IsForceMaximizeOnFirstRun(); |
| 275 // 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 |
| 276 // tells us to. | 239 // tells us to. |
| 277 const bool set_maximized = | 240 const bool set_maximized = |
| 278 maximize_first_window || | 241 maximize_first_window || |
| 279 ((work_area.width() <= GetForceMaximizedWidthLimit() || | 242 ((work_area.width() <= GetForceMaximizedWidthLimit() || |
| 280 maximize_first_window_on_first_run) && | 243 maximize_first_window_on_first_run) && |
| 281 (!new_window || !wm::GetWindowState(new_window)->IsFullscreen())); | 244 (!new_window || !new_window->GetWindowState()->IsFullscreen())); |
| 282 | 245 |
| 283 if (set_maximized) | 246 if (set_maximized) |
| 284 *show_state_out = ui::SHOW_STATE_MAXIMIZED; | 247 *show_state_out = ui::SHOW_STATE_MAXIMIZED; |
| 285 } | 248 } |
| 286 return; | 249 return; |
| 287 } | 250 } |
| 288 | 251 |
| 289 wm::WindowState* top_window_state = wm::GetWindowState(top_window); | 252 wm::WindowState* top_window_state = top_window->GetWindowState(); |
| 290 bool maximized = top_window_state->IsMaximized(); | 253 bool maximized = top_window_state->IsMaximized(); |
| 291 // We ignore the saved show state, but look instead for the top level | 254 // We ignore the saved show state, but look instead for the top level |
| 292 // window's show state. | 255 // window's show state. |
| 293 if (show_state_in == ui::SHOW_STATE_DEFAULT) { | 256 if (show_state_in == ui::SHOW_STATE_DEFAULT) { |
| 294 *show_state_out = maximized ? ui::SHOW_STATE_MAXIMIZED : | 257 *show_state_out = maximized ? ui::SHOW_STATE_MAXIMIZED : |
| 295 ui::SHOW_STATE_DEFAULT; | 258 ui::SHOW_STATE_DEFAULT; |
| 296 } | 259 } |
| 297 | 260 |
| 298 if (maximized || top_window_state->IsFullscreen()) { | 261 if (maximized || top_window_state->IsFullscreen()) { |
| 299 bool has_restore_bounds = top_window_state->HasRestoreBounds(); | 262 bool has_restore_bounds = top_window_state->HasRestoreBounds(); |
| 300 if (has_restore_bounds) { | 263 if (has_restore_bounds) { |
| 301 // For a maximized/fullscreen window ignore the real bounds of | 264 // For a maximized/fullscreen window ignore the real bounds of |
| 302 // the top level window and use its restore bounds | 265 // the top level window and use its restore bounds |
| 303 // instead. Offset the bounds to prevent the windows from | 266 // instead. Offset the bounds to prevent the windows from |
| 304 // overlapping exactly when restored. | 267 // overlapping exactly when restored. |
| 305 *bounds_in_out = top_window_state->GetRestoreBoundsInScreen() + | 268 *bounds_in_out = top_window_state->GetRestoreBoundsInScreen() + |
| 306 gfx::Vector2d(kMinimumWindowOffset, kMinimumWindowOffset); | 269 gfx::Vector2d(kMinimumWindowOffset, kMinimumWindowOffset); |
| 307 } | 270 } |
| 308 if (is_saved_bounds || has_restore_bounds) { | 271 if (is_saved_bounds || has_restore_bounds) { |
| 309 gfx::Rect work_area = screen->GetDisplayNearestWindow(target).work_area(); | 272 gfx::Rect work_area = target->GetDisplayNearestWindow().work_area(); |
| 310 bounds_in_out->AdjustToFit(work_area); | 273 bounds_in_out->AdjustToFit(work_area); |
| 311 // Use adjusted saved bounds or restore bounds, if there is one. | 274 // Use adjusted saved bounds or restore bounds, if there is one. |
| 312 return; | 275 return; |
| 313 } | 276 } |
| 314 } | 277 } |
| 315 | 278 |
| 316 // Use the size of the other window. The window's bound will be rearranged | 279 // Use the size of the other window. The window's bound will be rearranged |
| 317 // in ash::WorkspaceLayoutManager using this location. | 280 // in ash::WorkspaceLayoutManager using this location. |
| 318 *bounds_in_out = top_window->GetBoundsInScreen(); | 281 *bounds_in_out = top_window->GetBoundsInScreen(); |
| 319 } | 282 } |
| 320 | 283 |
| 321 // static | 284 // static |
| 322 void WindowPositioner::RearrangeVisibleWindowOnHideOrRemove( | 285 void WindowPositioner::RearrangeVisibleWindowOnHideOrRemove( |
| 323 const aura::Window* removed_window) { | 286 const wm::WmWindow* removed_window) { |
| 324 if (!UseAutoWindowManager(removed_window)) | 287 if (!UseAutoWindowManager(removed_window)) |
| 325 return; | 288 return; |
| 326 // Find a single open browser window. | 289 // Find a single open browser window. |
| 327 bool single_window; | 290 bool single_window; |
| 328 aura::Window* other_shown_window = GetReferenceWindow( | 291 wm::WmWindow* other_shown_window = GetReferenceWindow( |
| 329 removed_window->GetRootWindow(), removed_window, &single_window); | 292 removed_window->GetRootWindow(), removed_window, &single_window); |
| 330 if (!other_shown_window || !single_window || | 293 if (!other_shown_window || !single_window || |
| 331 !WindowPositionCanBeManaged(other_shown_window)) | 294 !WindowPositionCanBeManaged(other_shown_window)) |
| 332 return; | 295 return; |
| 333 AutoPlaceSingleWindow(other_shown_window, true); | 296 AutoPlaceSingleWindow(other_shown_window, true); |
| 334 } | 297 } |
| 335 | 298 |
| 336 // static | 299 // static |
| 337 bool WindowPositioner::DisableAutoPositioning(bool ignore) { | 300 bool WindowPositioner::DisableAutoPositioning(bool ignore) { |
| 338 bool old_state = disable_auto_positioning; | 301 bool old_state = disable_auto_positioning; |
| 339 disable_auto_positioning = ignore; | 302 disable_auto_positioning = ignore; |
| 340 return old_state; | 303 return old_state; |
| 341 } | 304 } |
| 342 | 305 |
| 343 // static | 306 // static |
| 344 void WindowPositioner::RearrangeVisibleWindowOnShow( | 307 void WindowPositioner::RearrangeVisibleWindowOnShow( |
| 345 aura::Window* added_window) { | 308 wm::WmWindow* added_window) { |
| 346 wm::WindowState* added_window_state = wm::GetWindowState(added_window); | 309 wm::WindowState* added_window_state = added_window->GetWindowState(); |
| 347 if (!added_window->TargetVisibility()) | 310 if (!added_window->GetTargetVisibility()) |
| 348 return; | 311 return; |
| 349 | 312 |
| 350 if (!UseAutoWindowManager(added_window) || | 313 if (!UseAutoWindowManager(added_window) || |
| 351 added_window_state->bounds_changed_by_user()) { | 314 added_window_state->bounds_changed_by_user()) { |
| 352 if (added_window_state->minimum_visibility()) { | 315 if (added_window_state->minimum_visibility()) { |
| 353 // Guarantee minimum visibility within the work area. | 316 // Guarantee minimum visibility within the work area. |
| 354 gfx::Rect work_area = GetWorkAreaForWindowInParent(added_window); | 317 gfx::Rect work_area = GetDisplayWorkAreaBoundsInParent(added_window); |
| 355 gfx::Rect bounds = added_window->bounds(); | 318 gfx::Rect bounds = added_window->GetBounds(); |
| 356 gfx::Rect new_bounds = bounds; | 319 gfx::Rect new_bounds = bounds; |
| 357 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area, | 320 wm::AdjustBoundsToEnsureMinimumWindowVisibility(work_area, &new_bounds); |
| 358 &new_bounds); | |
| 359 if (new_bounds != bounds) | 321 if (new_bounds != bounds) |
| 360 added_window->SetBounds(new_bounds); | 322 added_window->SetBounds(new_bounds); |
| 361 } | 323 } |
| 362 return; | 324 return; |
| 363 } | 325 } |
| 364 // Find a single open managed window. | 326 // Find a single open managed window. |
| 365 bool single_window; | 327 bool single_window; |
| 366 aura::Window* other_shown_window = GetReferenceWindow( | 328 wm::WmWindow* other_shown_window = GetReferenceWindow( |
| 367 added_window->GetRootWindow(), added_window, &single_window); | 329 added_window->GetRootWindow(), added_window, &single_window); |
| 368 | 330 |
| 369 if (!other_shown_window) { | 331 if (!other_shown_window) { |
| 370 // 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. |
| 371 if (!WindowPositionCanBeManaged(added_window) || other_shown_window) | 333 if (!WindowPositionCanBeManaged(added_window) || other_shown_window) |
| 372 return; | 334 return; |
| 373 // 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 |
| 374 // window to a good default. | 336 // window to a good default. |
| 375 AutoPlaceSingleWindow(added_window, false); | 337 AutoPlaceSingleWindow(added_window, false); |
| 376 return; | 338 return; |
| 377 } | 339 } |
| 378 | 340 |
| 379 gfx::Rect other_bounds = other_shown_window->bounds(); | 341 gfx::Rect other_bounds = other_shown_window->GetBounds(); |
| 380 gfx::Rect work_area = GetWorkAreaForWindowInParent(added_window); | 342 gfx::Rect work_area = GetDisplayWorkAreaBoundsInParent(added_window); |
| 381 bool move_other_right = | 343 bool move_other_right = |
| 382 other_bounds.CenterPoint().x() > work_area.x() + work_area.width() / 2; | 344 other_bounds.CenterPoint().x() > work_area.x() + work_area.width() / 2; |
| 383 | 345 |
| 384 // 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. |
| 385 if (single_window) { | 347 if (single_window) { |
| 386 // When going from one to two windows both windows loose their | 348 // When going from one to two windows both windows loose their |
| 387 // "positioned by user" flags. | 349 // "positioned by user" flags. |
| 388 added_window_state->set_bounds_changed_by_user(false); | 350 added_window_state->set_bounds_changed_by_user(false); |
| 389 wm::WindowState* other_window_state = | 351 wm::WindowState* other_window_state = other_shown_window->GetWindowState(); |
| 390 wm::GetWindowState(other_shown_window); | |
| 391 other_window_state->set_bounds_changed_by_user(false); | 352 other_window_state->set_bounds_changed_by_user(false); |
| 392 | 353 |
| 393 if (WindowPositionCanBeManaged(other_shown_window)) { | 354 if (WindowPositionCanBeManaged(other_shown_window)) { |
| 394 // Don't override pre auto managed bounds as the current bounds | 355 // Don't override pre auto managed bounds as the current bounds |
| 395 // may not be original. | 356 // may not be original. |
| 396 if (!other_window_state->pre_auto_manage_window_bounds()) | 357 if (!other_window_state->pre_auto_manage_window_bounds()) |
| 397 other_window_state->SetPreAutoManageWindowBounds(other_bounds); | 358 other_window_state->SetPreAutoManageWindowBounds(other_bounds); |
| 398 | 359 |
| 399 // Push away the other window after remembering its current position. | 360 // Push away the other window after remembering its current position. |
| 400 if (MoveRectToOneSide(work_area, move_other_right, &other_bounds)) | 361 if (MoveRectToOneSide(work_area, move_other_right, &other_bounds)) |
| 401 SetBoundsAnimated(other_shown_window, other_bounds, work_area); | 362 SetBoundsAnimated(other_shown_window, other_bounds, work_area); |
| 402 } | 363 } |
| 403 } | 364 } |
| 404 | 365 |
| 405 // 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 |
| 406 // 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 |
| 407 // being shown, we do not need to animate it. | 368 // being shown, we do not need to animate it. |
| 408 gfx::Rect added_bounds = added_window->bounds(); | 369 gfx::Rect added_bounds = added_window->GetBounds(); |
| 409 if (!added_window_state->pre_auto_manage_window_bounds()) | 370 if (!added_window_state->pre_auto_manage_window_bounds()) |
| 410 added_window_state->SetPreAutoManageWindowBounds(added_bounds); | 371 added_window_state->SetPreAutoManageWindowBounds(added_bounds); |
| 411 if (MoveRectToOneSide(work_area, !move_other_right, &added_bounds)) | 372 if (MoveRectToOneSide(work_area, !move_other_right, &added_bounds)) |
| 412 added_window->SetBounds(added_bounds); | 373 added_window->SetBounds(added_bounds); |
| 413 } | 374 } |
| 414 | 375 |
| 415 WindowPositioner::WindowPositioner() | 376 WindowPositioner::WindowPositioner(wm::WmGlobals* globals) |
| 416 : pop_position_offset_increment_x(0), | 377 : globals_(globals), |
| 378 pop_position_offset_increment_x(0), |
| 417 pop_position_offset_increment_y(0), | 379 pop_position_offset_increment_y(0), |
| 418 popup_position_offset_from_screen_corner_x(0), | 380 popup_position_offset_from_screen_corner_x(0), |
| 419 popup_position_offset_from_screen_corner_y(0), | 381 popup_position_offset_from_screen_corner_y(0), |
| 420 last_popup_position_x_(0), | 382 last_popup_position_x_(0), |
| 421 last_popup_position_y_(0) { | 383 last_popup_position_y_(0) {} |
| 422 } | |
| 423 | 384 |
| 424 WindowPositioner::~WindowPositioner() { | 385 WindowPositioner::~WindowPositioner() { |
| 425 } | 386 } |
| 426 | 387 |
| 427 gfx::Rect WindowPositioner::GetDefaultWindowBounds( | 388 gfx::Rect WindowPositioner::GetDefaultWindowBounds( |
| 428 const gfx::Display& display) { | 389 const gfx::Display& display) { |
| 429 const gfx::Rect work_area = display.work_area(); | 390 const gfx::Rect work_area = display.work_area(); |
| 430 // There should be a 'desktop' border around the window at the left and right | 391 // There should be a 'desktop' border around the window at the left and right |
| 431 // side. | 392 // side. |
| 432 int default_width = work_area.width() - 2 * kDesktopBorderSize; | 393 int default_width = work_area.width() - 2 * kDesktopBorderSize; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 452 if (!pop_position_offset_increment_x) { | 413 if (!pop_position_offset_increment_x) { |
| 453 // When the popup position increment is 0, the last popup position | 414 // When the popup position increment is 0, the last popup position |
| 454 // was not yet initialized. | 415 // was not yet initialized. |
| 455 last_popup_position_x_ = popup_position_offset_from_screen_corner_x; | 416 last_popup_position_x_ = popup_position_offset_from_screen_corner_x; |
| 456 last_popup_position_y_ = popup_position_offset_from_screen_corner_y; | 417 last_popup_position_y_ = popup_position_offset_from_screen_corner_y; |
| 457 } | 418 } |
| 458 pop_position_offset_increment_x = grid; | 419 pop_position_offset_increment_x = grid; |
| 459 pop_position_offset_increment_y = grid; | 420 pop_position_offset_increment_y = grid; |
| 460 // We handle the Multi monitor support by retrieving the active window's | 421 // We handle the Multi monitor support by retrieving the active window's |
| 461 // work area. | 422 // work area. |
| 462 aura::Window* window = wm::GetActiveWindow(); | 423 wm::WmWindow* window = globals_->GetActiveWindow(); |
| 463 const gfx::Rect work_area = | 424 const gfx::Rect work_area = |
| 464 window && window->IsVisible() | 425 window && window->IsVisible() |
| 465 ? gfx::Screen::GetScreen() | 426 ? window->GetDisplayNearestWindow().work_area() |
| 466 ->GetDisplayNearestWindow(window) | |
| 467 .work_area() | |
| 468 : gfx::Screen::GetScreen()->GetPrimaryDisplay().work_area(); | 427 : gfx::Screen::GetScreen()->GetPrimaryDisplay().work_area(); |
| 469 // Only try to reposition the popup when it is not spanning the entire | 428 // Only try to reposition the popup when it is not spanning the entire |
| 470 // screen. | 429 // screen. |
| 471 if ((old_pos.width() + popup_position_offset_from_screen_corner_x >= | 430 if ((old_pos.width() + popup_position_offset_from_screen_corner_x >= |
| 472 work_area.width()) || | 431 work_area.width()) || |
| 473 (old_pos.height() + popup_position_offset_from_screen_corner_y >= | 432 (old_pos.height() + popup_position_offset_from_screen_corner_y >= |
| 474 work_area.height())) | 433 work_area.height())) |
| 475 return AlignPopupPosition(old_pos, work_area, grid); | 434 return AlignPopupPosition(old_pos, work_area, grid); |
| 476 const gfx::Rect result = SmartPopupPosition(old_pos, work_area, grid); | 435 const gfx::Rect result = SmartPopupPosition(old_pos, work_area, grid); |
| 477 if (!result.IsEmpty()) | 436 if (!result.IsEmpty()) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 last_popup_position_x_ += pop_position_offset_increment_x; | 473 last_popup_position_x_ += pop_position_offset_increment_x; |
| 515 last_popup_position_y_ += pop_position_offset_increment_y; | 474 last_popup_position_y_ += pop_position_offset_increment_y; |
| 516 } | 475 } |
| 517 return gfx::Rect(x + work_area.x(), y + work_area.y(), w, h); | 476 return gfx::Rect(x + work_area.x(), y + work_area.y(), w, h); |
| 518 } | 477 } |
| 519 | 478 |
| 520 gfx::Rect WindowPositioner::SmartPopupPosition( | 479 gfx::Rect WindowPositioner::SmartPopupPosition( |
| 521 const gfx::Rect& old_pos, | 480 const gfx::Rect& old_pos, |
| 522 const gfx::Rect& work_area, | 481 const gfx::Rect& work_area, |
| 523 int grid) { | 482 int grid) { |
| 524 const std::vector<aura::Window*> windows = ash::Shell::GetInstance()-> | 483 const std::vector<wm::WmWindow*> windows = |
| 525 mru_window_tracker()->BuildWindowListIgnoreModal(); | 484 globals_->GetMruWindowListIgnoreModals(); |
| 526 | 485 |
| 527 std::vector<const gfx::Rect*> regions; | 486 std::vector<const gfx::Rect*> regions; |
| 528 // Process the window list and check if we can bail immediately. | 487 // Process the window list and check if we can bail immediately. |
| 529 for (size_t i = 0; i < windows.size(); i++) { | 488 for (size_t i = 0; i < windows.size(); i++) { |
| 530 // We only include opaque and visible windows. | 489 // We only include opaque and visible windows. |
| 531 if (windows[i] && windows[i]->IsVisible() && windows[i]->layer() && | 490 if (windows[i] && windows[i]->IsVisible() && windows[i]->GetLayer() && |
| 532 (!windows[i]->transparent() || | 491 (windows[i]->GetLayer()->fills_bounds_opaquely() || |
| 533 windows[i]->layer()->GetTargetOpacity() == 1.0)) { | 492 windows[i]->GetLayer()->GetTargetOpacity() == 1.0)) { |
| 534 wm::WindowState* window_state = wm::GetWindowState(windows[i]); | 493 wm::WindowState* window_state = windows[i]->GetWindowState(); |
| 535 // When any window is maximized we cannot find any free space. | 494 // When any window is maximized we cannot find any free space. |
| 536 if (window_state->IsMaximizedOrFullscreen()) | 495 if (window_state->IsMaximizedOrFullscreen()) |
| 537 return gfx::Rect(0, 0, 0, 0); | 496 return gfx::Rect(0, 0, 0, 0); |
| 538 if (window_state->IsNormalOrSnapped()) | 497 if (window_state->IsNormalOrSnapped()) |
| 539 regions.push_back(&windows[i]->bounds()); | 498 regions.push_back(&windows[i]->GetBounds()); |
| 540 } | 499 } |
| 541 } | 500 } |
| 542 | 501 |
| 543 if (regions.empty()) | 502 if (regions.empty()) |
| 544 return gfx::Rect(0, 0, 0, 0); | 503 return gfx::Rect(0, 0, 0, 0); |
| 545 | 504 |
| 546 int w = old_pos.width(); | 505 int w = old_pos.width(); |
| 547 int h = old_pos.height(); | 506 int h = old_pos.height(); |
| 548 int x_end = work_area.width() / 2; | 507 int x_end = work_area.width() / 2; |
| 549 int x, x_increment; | 508 int x, x_increment; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 // If the alignment was pushing the window out of the screen, we ignore the | 559 // If the alignment was pushing the window out of the screen, we ignore the |
| 601 // alignment for that call. | 560 // alignment for that call. |
| 602 if (abs(pos.right() - work_area.right()) < grid) | 561 if (abs(pos.right() - work_area.right()) < grid) |
| 603 x = work_area.right() - w; | 562 x = work_area.right() - w; |
| 604 if (abs(pos.bottom() - work_area.bottom()) < grid) | 563 if (abs(pos.bottom() - work_area.bottom()) < grid) |
| 605 y = work_area.bottom() - h; | 564 y = work_area.bottom() - h; |
| 606 return gfx::Rect(x, y, w, h); | 565 return gfx::Rect(x, y, w, h); |
| 607 } | 566 } |
| 608 | 567 |
| 609 } // namespace ash | 568 } // namespace ash |
| OLD | NEW |