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 |