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