Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(584)

Side by Side Diff: chrome/browser/ui/window_sizer/window_sizer_ash.cc

Issue 10911274: Adding new window management (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cahnged the SetBounds to SetBoundsInScreen Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/shell.h" 7 #include "ash/shell.h"
8 #include "ash/wm/window_cycle_controller.h" 8 #include "ash/wm/window_cycle_controller.h"
9 #include "ash/wm/window_util.h" 9 #include "ash/wm/window_util.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
11 #include "chrome/browser/browser_process.h" 11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/ui/browser.h" 12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_list.h" 13 #include "chrome/browser/ui/browser_list.h"
14 #include "chrome/browser/ui/browser_window.h" 14 #include "chrome/browser/ui/browser_window.h"
15 #include "ui/aura/root_window.h"
15 #include "ui/aura/window.h" 16 #include "ui/aura/window.h"
16 #include "ui/aura/window_delegate.h" 17 #include "ui/aura/window_delegate.h"
17 #include "ui/gfx/screen.h" 18 #include "ui/gfx/screen.h"
18 19
19 namespace { 20 namespace {
20 21
21 // Check if the window was not created as popup or as panel. 22 // Check if the given browser is 'valid': It is a tabbed, non minimized
22 bool IsValidToplevelWindow(aura::Window* window) { 23 // window, which intersects with the |bounds_in_screen| area of a given screen.
24 bool IsValidBrowser(Browser* browser, const gfx::Rect& bounds_in_screen) {
25 return (browser && browser->window() &&
26 !(browser->is_type_popup() || browser->is_type_panel()) &&
27 !browser->window()->IsMinimized() &&
28 browser->window()->GetNativeWindow() &&
29 bounds_in_screen.Intersects(
30 browser->window()->GetNativeWindow()->GetBoundsInScreen()));
31 }
32
33 // Check if the window was not created as popup or as panel, it is
34 // on the screen defined by |bounds_in_screen| and visible.
35 bool IsValidToplevelWindow(aura::Window* window,
36 const gfx::Rect& bounds_in_screen) {
23 for (BrowserList::const_iterator iter = BrowserList::begin(); 37 for (BrowserList::const_iterator iter = BrowserList::begin();
24 iter != BrowserList::end(); 38 iter != BrowserList::end();
25 ++iter) { 39 ++iter) {
26 Browser* browser = *iter; 40 Browser* browser = *iter;
27 if (browser && browser->window() && 41 if (browser && browser->window() &&
28 browser->window()->GetNativeWindow() == window) { 42 browser->window()->GetNativeWindow() == window)
29 return (!(browser->is_type_popup() || browser->is_type_panel())); 43 return IsValidBrowser(browser, bounds_in_screen);
30 }
31 } 44 }
32 // A window which has no browser associated with it is probably not a window 45 // A window which has no browser associated with it is probably not a window
33 // of which we want to copy the size from. 46 // of which we want to copy the size from.
34 return false; 47 return false;
35 } 48 }
36 49
37 // Get the first open window in the stack on the screen. 50 // Get the first open (non minimized) window which is on the screen defined
38 aura::Window* GetTopWindow() { 51 // by |bounds_in_screen| and visible.
52 aura::Window* GetTopWindow(const gfx::Rect& bounds_in_screen) {
39 // Get the active window. 53 // Get the active window.
40 aura::Window* window = ash::wm::GetActiveWindow(); 54 aura::Window* window = ash::wm::GetActiveWindow();
41 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL && 55 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL &&
42 window->IsVisible() && IsValidToplevelWindow(window)) 56 window->IsVisible() && IsValidToplevelWindow(window, bounds_in_screen))
43 return window; 57 return window;
44 58
45 // Get a list of all windows. 59 // Get a list of all windows.
46 const std::vector<aura::Window*> windows = 60 const std::vector<aura::Window*> windows =
47 ash::WindowCycleController::BuildWindowList(NULL); 61 ash::WindowCycleController::BuildWindowList(NULL);
48 62
49 if (windows.empty()) 63 if (windows.empty())
50 return NULL; 64 return NULL;
51 65
52 aura::Window::Windows::const_iterator iter = windows.begin(); 66 aura::Window::Windows::const_iterator iter = windows.begin();
53 // Find the index of the current window. 67 // Find the index of the current window.
54 if (window) 68 if (window)
55 iter = std::find(windows.begin(), windows.end(), window); 69 iter = std::find(windows.begin(), windows.end(), window);
56 70
57 int index = (iter == windows.end()) ? 0 : (iter - windows.begin()); 71 int index = (iter == windows.end()) ? 0 : (iter - windows.begin());
58 72
59 // Scan the cycle list backwards to see which is the second topmost window 73 // Scan the cycle list backwards to see which is the second topmost window
60 // (and so on). Note that we might cycle a few indices twice if there is no 74 // (and so on). Note that we might cycle a few indices twice if there is no
61 // suitable window. However - since the list is fairly small this should be 75 // suitable window. However - since the list is fairly small this should be
62 // very fast anyways. 76 // very fast anyways.
63 for (int i = index + windows.size(); i >= 0; i--) { 77 for (int i = index + windows.size(); i >= 0; i--) {
64 aura::Window* window = windows[i % windows.size()]; 78 aura::Window* window = windows[i % windows.size()];
65 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL && 79 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL &&
66 window->IsVisible() && IsValidToplevelWindow(window)) 80 bounds_in_screen.Intersects(window->GetBoundsInScreen()) &&
81 window->IsVisible() && IsValidToplevelWindow(window, bounds_in_screen))
67 return window; 82 return window;
68 } 83 }
69 return NULL; 84 return NULL;
70 } 85 }
71 86
87 // Return the number of valid top level windows on the screen defined by
88 // the |bounds_in_screen| rectangle.
89 int GetNumberOfValidTopLevelBrowserWindows(const gfx::Rect& bounds_in_screen) {
90 int count = 0;
91 for (BrowserList::const_iterator iter = BrowserList::begin();
92 iter != BrowserList::end();
93 ++iter) {
94 if (IsValidBrowser(*iter, bounds_in_screen))
95 count++;
96 }
97 return count;
98 }
99
100 // Move the given |bounds_in_screen| on the available |work_area| to the
101 // direction. If |move_right| is true, the rectangle gets moved to the right
102 // corner. Otherwise to the left side.
103 bool MoveRect(const gfx::Rect& work_area,
104 gfx::Rect& bounds_in_screen,
105 bool move_right) {
106 if (move_right) {
107 if (work_area.right() > bounds_in_screen.right()) {
108 bounds_in_screen.set_x(work_area.right() - bounds_in_screen.width());
109 return true;
110 }
111 } else {
112 if (work_area.x() < bounds_in_screen.x()) {
113 bounds_in_screen.set_x(work_area.x());
114 return true;
115 }
116 }
117 return false;
118 }
119
72 } // namespace 120 } // namespace
73 121
74 bool WindowSizer::GetBoundsIgnoringPreviousStateAsh( 122 bool WindowSizer::GetBoundsOverrideAsh(const gfx::Rect& specified_bounds,
75 const gfx::Rect& specified_bounds, 123 gfx::Rect* bounds_in_screen) const {
76 gfx::Rect* bounds) const { 124 *bounds_in_screen = specified_bounds;
77 *bounds = specified_bounds; 125 DCHECK(bounds_in_screen->IsEmpty());
78 DCHECK(bounds->IsEmpty()); 126
127 if (!GetSavedWindowBounds(bounds_in_screen))
128 GetDefaultWindowBounds(bounds_in_screen);
129
79 if (browser_ != NULL && browser_->type() == Browser::TYPE_TABBED) { 130 if (browser_ != NULL && browser_->type() == Browser::TYPE_TABBED) {
131 gfx::Rect work_area =
132 monitor_info_provider_->GetMonitorWorkAreaMatching(*bounds_in_screen);
80 // This is a window / app. See if there is no window and try to place it. 133 // This is a window / app. See if there is no window and try to place it.
81 aura::Window* top_window = GetTopWindow(); 134 int count = GetNumberOfValidTopLevelBrowserWindows(work_area);
82 // If there are no windows we have a special case and try to 135 aura::Window* top_window = GetTopWindow(work_area);
83 // maximize which leaves a 'border' which shows the desktop. 136
84 if (top_window == NULL) { 137 // If there is no valid other window we take the coordinates as is.
85 GetDefaultWindowBounds(bounds); 138 if (!count || !top_window || ash::wm::IsWindowMaximized(top_window))
86 } else { 139 return true;
87 *bounds = top_window->GetBoundsInScreen(); 140
88 gfx::Rect work_area = 141 gfx::Rect other_bounds_in_screen = top_window->GetBoundsInScreen();
89 monitor_info_provider_->GetMonitorWorkAreaMatching(*bounds); 142 bool move_right =
90 *bounds = bounds->AdjustToFit(work_area); 143 other_bounds_in_screen.CenterPoint().x() < work_area.CenterPoint().x();
144
145 // In case we have only one window, we move the other window fully to the
146 // "other side" - making room for this new window.
147 if (count == 1) {
148 gfx::Display display =
149 gfx::Screen::GetDisplayMatching(
150 top_window->GetRootWindow()->GetBoundsInScreen());
151 if (MoveRect(work_area, other_bounds_in_screen, !move_right))
152 top_window->SetBoundsInScreen(other_bounds_in_screen, display);
91 } 153 }
154 // Use the size of the other window, and mirror the location to the
155 // opposite side. Then make sure that it is inside our work area
156 // (if possible).
157 *bounds_in_screen = other_bounds_in_screen;
158 MoveRect(work_area, *bounds_in_screen, move_right);
159 if (bounds_in_screen->bottom() > work_area.bottom())
160 bounds_in_screen->set_y(std::max(work_area.y(),
161 work_area.bottom() - bounds_in_screen->height()));
92 return true; 162 return true;
93 // If both fail we will continue the default path.
94 } 163 }
95 164
96 return false; 165 return false;
97 } 166 }
98 167
99 void WindowSizer::GetDefaultWindowBoundsAsh(gfx::Rect* default_bounds) const { 168 void WindowSizer::GetDefaultWindowBoundsAsh(gfx::Rect* default_bounds) const {
100 DCHECK(default_bounds); 169 DCHECK(default_bounds);
101 DCHECK(monitor_info_provider_.get()); 170 DCHECK(monitor_info_provider_.get());
102 171
103 gfx::Rect work_area = monitor_info_provider_->GetPrimaryDisplayWorkArea(); 172 gfx::Rect work_area = monitor_info_provider_->GetPrimaryDisplayWorkArea();
(...skipping 12 matching lines...) Expand all
116 if (default_width > kMaximumWindowWidth) { 185 if (default_width > kMaximumWindowWidth) {
117 // The window should get centered on the screen and not follow the grid. 186 // The window should get centered on the screen and not follow the grid.
118 offset_x = (work_area.width() - kMaximumWindowWidth) / 2; 187 offset_x = (work_area.width() - kMaximumWindowWidth) / 2;
119 default_width = kMaximumWindowWidth; 188 default_width = kMaximumWindowWidth;
120 } 189 }
121 default_bounds->SetRect(work_area.x() + offset_x, 190 default_bounds->SetRect(work_area.x() + offset_x,
122 work_area.y() + kDesktopBorderSize, 191 work_area.y() + kDesktopBorderSize,
123 default_width, 192 default_width,
124 default_height); 193 default_height);
125 } 194 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/window_sizer/window_sizer.cc ('k') | chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698