| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/window_sizer/window_sizer.h" | 5 #include "chrome/browser/ui/window_sizer/window_sizer.h" |
| 6 | 6 |
| 7 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
| 8 #include "ash/shell.h" | 8 #include "ash/shell.h" |
| 9 #include "ash/wm/mru_window_tracker.h" | 9 #include "ash/wm/mru_window_tracker.h" |
| 10 #include "ash/wm/window_util.h" | 10 #include "ash/wm/window_util.h" |
| 11 #include "ash/wm/workspace/auto_window_management.h" |
| 11 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 12 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 13 #include "chrome/browser/browser_process.h" | 14 #include "chrome/browser/browser_process.h" |
| 14 #include "chrome/browser/ui/browser.h" | 15 #include "chrome/browser/ui/browser.h" |
| 15 #include "chrome/browser/ui/browser_list.h" | 16 #include "chrome/browser/ui/browser_list.h" |
| 16 #include "chrome/browser/ui/browser_window.h" | 17 #include "chrome/browser/ui/browser_window.h" |
| 17 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h" | 18 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h" |
| 18 #include "chrome/browser/ui/host_desktop.h" | 19 #include "chrome/browser/ui/host_desktop.h" |
| 19 #include "ui/aura/root_window.h" | 20 #include "ui/aura/root_window.h" |
| 20 #include "ui/aura/window.h" | 21 #include "ui/aura/window.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 33 // window, which intersects with the |bounds_in_screen| area of a given screen. | 34 // window, which intersects with the |bounds_in_screen| area of a given screen. |
| 34 bool IsValidBrowser(Browser* browser, const gfx::Rect& bounds_in_screen) { | 35 bool IsValidBrowser(Browser* browser, const gfx::Rect& bounds_in_screen) { |
| 35 return (browser && browser->window() && | 36 return (browser && browser->window() && |
| 36 !browser->is_type_popup() && | 37 !browser->is_type_popup() && |
| 37 !browser->window()->IsMinimized() && | 38 !browser->window()->IsMinimized() && |
| 38 browser->window()->GetNativeWindow() && | 39 browser->window()->GetNativeWindow() && |
| 39 bounds_in_screen.Intersects( | 40 bounds_in_screen.Intersects( |
| 40 browser->window()->GetNativeWindow()->GetBoundsInScreen())); | 41 browser->window()->GetNativeWindow()->GetBoundsInScreen())); |
| 41 } | 42 } |
| 42 | 43 |
| 43 // Check if the window was not created as popup or as panel, it is | |
| 44 // on the screen defined by |bounds_in_screen| and visible. | |
| 45 bool IsValidToplevelWindow(aura::Window* window, | |
| 46 const gfx::Rect& bounds_in_screen) { | |
| 47 const BrowserList* ash_browser_list = | |
| 48 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); | |
| 49 for (BrowserList::const_iterator iter = ash_browser_list->begin(); | |
| 50 iter != ash_browser_list->end(); | |
| 51 ++iter) { | |
| 52 Browser* browser = *iter; | |
| 53 if (browser && browser->window() && | |
| 54 browser->window()->GetNativeWindow() == window) { | |
| 55 return IsValidBrowser(browser, bounds_in_screen); | |
| 56 } | |
| 57 } | |
| 58 // A window which has no browser associated with it is probably not a window | |
| 59 // of which we want to copy the size from. | |
| 60 return false; | |
| 61 } | |
| 62 | |
| 63 // Get the first open (non minimized) window which is on the screen defined | |
| 64 // by |bounds_in_screen| and visible. | |
| 65 aura::Window* GetTopWindow(const gfx::Rect& bounds_in_screen) { | |
| 66 // Get the active window. | |
| 67 aura::Window* window = ash::wm::GetActiveWindow(); | |
| 68 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL && | |
| 69 window->IsVisible() && IsValidToplevelWindow(window, bounds_in_screen)) { | |
| 70 return window; | |
| 71 } | |
| 72 | |
| 73 // Get a list of all windows. | |
| 74 const std::vector<aura::Window*> windows = | |
| 75 ash::MruWindowTracker::BuildWindowList(false); | |
| 76 | |
| 77 if (windows.empty()) | |
| 78 return NULL; | |
| 79 | |
| 80 aura::Window::Windows::const_iterator iter = windows.begin(); | |
| 81 // Find the index of the current window. | |
| 82 if (window) | |
| 83 iter = std::find(windows.begin(), windows.end(), window); | |
| 84 | |
| 85 int index = (iter == windows.end()) ? 0 : (iter - windows.begin()); | |
| 86 | |
| 87 // Scan the cycle list backwards to see which is the second topmost window | |
| 88 // (and so on). Note that we might cycle a few indices twice if there is no | |
| 89 // suitable window. However - since the list is fairly small this should be | |
| 90 // very fast anyways. | |
| 91 for (int i = index + windows.size(); i >= 0; i--) { | |
| 92 aura::Window* window = windows[i % windows.size()]; | |
| 93 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL && | |
| 94 bounds_in_screen.Intersects(window->GetBoundsInScreen()) && | |
| 95 window->IsVisible() | |
| 96 && IsValidToplevelWindow(window, bounds_in_screen)) { | |
| 97 return window; | |
| 98 } | |
| 99 } | |
| 100 return NULL; | |
| 101 } | |
| 102 | |
| 103 // Return the number of valid top level windows on the screen defined by | 44 // Return the number of valid top level windows on the screen defined by |
| 104 // the |bounds_in_screen| rectangle. | 45 // the |bounds_in_screen| rectangle. |
| 105 int GetNumberOfValidTopLevelBrowserWindows(const gfx::Rect& bounds_in_screen) { | 46 int GetNumberOfValidTopLevelBrowserWindows(const gfx::Rect& bounds_in_screen) { |
| 106 int count = 0; | 47 int count = 0; |
| 107 const BrowserList* ash_browser_list = | 48 const BrowserList* ash_browser_list = |
| 108 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); | 49 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); |
| 109 for (BrowserList::const_iterator iter = ash_browser_list->begin(); | 50 for (BrowserList::const_iterator iter = ash_browser_list->begin(); |
| 110 iter != ash_browser_list->end(); | 51 iter != ash_browser_list->end(); |
| 111 ++iter) { | 52 ++iter) { |
| 112 if (IsValidBrowser(*iter, bounds_in_screen)) | 53 if (IsValidBrowser(*iter, bounds_in_screen)) |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 ui::WindowShowState passed_show_state = *show_state; | 114 ui::WindowShowState passed_show_state = *show_state; |
| 174 bool has_saved_bounds = true; | 115 bool has_saved_bounds = true; |
| 175 if (!GetSavedWindowBounds(bounds_in_screen, show_state)) { | 116 if (!GetSavedWindowBounds(bounds_in_screen, show_state)) { |
| 176 has_saved_bounds = false; | 117 has_saved_bounds = false; |
| 177 GetDefaultWindowBounds(bounds_in_screen); | 118 GetDefaultWindowBounds(bounds_in_screen); |
| 178 } | 119 } |
| 179 | 120 |
| 180 if (browser_ && browser_->is_type_tabbed()) { | 121 if (browser_ && browser_->is_type_tabbed()) { |
| 181 aura::RootWindow* active = ash::Shell::GetActiveRootWindow(); | 122 aura::RootWindow* active = ash::Shell::GetActiveRootWindow(); |
| 182 // Always open new window in the active display. | 123 // Always open new window in the active display. |
| 183 gfx::Rect active_area = active->GetBoundsInScreen(); | |
| 184 gfx::Rect work_area = | 124 gfx::Rect work_area = |
| 185 screen_->GetDisplayMatching(active_area).work_area(); | 125 screen_->GetDisplayMatching(active->GetBoundsInScreen()).work_area(); |
| 186 | 126 |
| 187 // This is a window / app. See if there is no window and try to place it. | 127 // This is a window / app. See if there is no window and try to place it. |
| 188 int count = GetNumberOfValidTopLevelBrowserWindows(work_area); | 128 int count = GetNumberOfValidTopLevelBrowserWindows(work_area); |
| 189 aura::Window* top_window = GetTopWindow(work_area); | 129 aura::Window* top_window = ash::GetTopWindowForNewWindow(active); |
| 190 // Our window should not have any impact if we are already on top. | 130 // Our window should not have any impact if we are already on top. |
| 191 if (browser_->window() && | 131 if (browser_->window() && |
| 192 top_window == browser_->window()->GetNativeWindow()) | 132 top_window == browser_->window()->GetNativeWindow()) |
| 193 top_window = NULL; | 133 top_window = NULL; |
| 194 | 134 |
| 195 // If there is no valid other window we take the coordinates as is. | 135 // If there is no valid other window we take the coordinates as is. |
| 196 if ((!count || !top_window)) { | 136 if ((!count || !top_window)) { |
| 197 if (has_saved_bounds) { | 137 if (has_saved_bounds) { |
| 198 // Restore to previous state - if there is one. | 138 // Restore to previous state - if there is one. |
| 199 bounds_in_screen->AdjustToFit(work_area); | 139 bounds_in_screen->AdjustToFit(work_area); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 213 // We ignore the saved show state, but look instead for the top level | 153 // We ignore the saved show state, but look instead for the top level |
| 214 // window's show state. | 154 // window's show state. |
| 215 if (passed_show_state == ui::SHOW_STATE_DEFAULT) { | 155 if (passed_show_state == ui::SHOW_STATE_DEFAULT) { |
| 216 *show_state = maximized ? ui::SHOW_STATE_MAXIMIZED : | 156 *show_state = maximized ? ui::SHOW_STATE_MAXIMIZED : |
| 217 ui::SHOW_STATE_DEFAULT; | 157 ui::SHOW_STATE_DEFAULT; |
| 218 } | 158 } |
| 219 | 159 |
| 220 if (maximized) | 160 if (maximized) |
| 221 return true; | 161 return true; |
| 222 | 162 |
| 223 // Use the size of the other window, and mirror the location to the | 163 // Use the size of the other window. The window's bound will be rearranged |
| 224 // opposite side. Then make sure that it is inside our work area | 164 // in ash::WorkspaceLayoutManager using this location. |
| 225 // (if possible). | |
| 226 *bounds_in_screen = top_window->GetBoundsInScreen(); | 165 *bounds_in_screen = top_window->GetBoundsInScreen(); |
| 227 | 166 |
| 228 bool move_right = | |
| 229 bounds_in_screen->CenterPoint().x() < work_area.CenterPoint().x(); | |
| 230 | |
| 231 MoveRect(work_area, *bounds_in_screen, move_right); | |
| 232 bounds_in_screen->AdjustToFit(work_area); | |
| 233 return true; | 167 return true; |
| 234 } | 168 } |
| 235 | 169 |
| 236 return false; | 170 return false; |
| 237 } | 171 } |
| 238 | 172 |
| 239 void WindowSizer::GetDefaultWindowBoundsAsh(gfx::Rect* default_bounds) const { | 173 void WindowSizer::GetDefaultWindowBoundsAsh(gfx::Rect* default_bounds) const { |
| 240 DCHECK(default_bounds); | 174 DCHECK(default_bounds); |
| 241 | 175 |
| 242 gfx::Rect work_area = screen_->GetPrimaryDisplay().work_area(); | 176 gfx::Rect work_area = screen_->GetPrimaryDisplay().work_area(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 255 if (default_width > kMaximumWindowWidth) { | 189 if (default_width > kMaximumWindowWidth) { |
| 256 // The window should get centered on the screen and not follow the grid. | 190 // The window should get centered on the screen and not follow the grid. |
| 257 offset_x = (work_area.width() - kMaximumWindowWidth) / 2; | 191 offset_x = (work_area.width() - kMaximumWindowWidth) / 2; |
| 258 default_width = kMaximumWindowWidth; | 192 default_width = kMaximumWindowWidth; |
| 259 } | 193 } |
| 260 default_bounds->SetRect(work_area.x() + offset_x, | 194 default_bounds->SetRect(work_area.x() + offset_x, |
| 261 work_area.y() + kDesktopBorderSize, | 195 work_area.y() + kDesktopBorderSize, |
| 262 default_width, | 196 default_width, |
| 263 default_height); | 197 default_height); |
| 264 } | 198 } |
| OLD | NEW |