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

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: Addressed 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/window.h" 15 #include "ui/aura/window.h"
16 #include "ui/aura/window_delegate.h" 16 #include "ui/aura/window_delegate.h"
17 #include "ui/gfx/screen.h" 17 #include "ui/gfx/screen.h"
18 18
19 namespace { 19 namespace {
20 20
21 // Check if the window was not created as popup or as panel. 21 // Check if the given browser is 'valid': It is a tabbed, non minimized
22 bool IsValidToplevelWindow(aura::Window* window) { 22 // window, which intersects with the |bounds| area of a given screen.
23 bool IsValidBrowser(Browser* browser, const gfx::Rect& bounds) {
24 return (browser && browser->window() &&
25 !(browser->is_type_popup() || browser->is_type_panel()) &&
26 !browser->window()->IsMinimized() &&
27 browser->window()->GetNativeWindow() &&
28 bounds.Intersects(
29 browser->window()->GetNativeWindow()->GetBoundsInScreen()));
30
sky 2012/09/13 17:32:02 remove this newline.
Mr4D (OOO till 08-26) 2012/09/13 18:56:59 Done.
31 }
32
33 // Check if the window was not created as popup or as panel, it is
34 // on the screen defined by |bounds| and visible.
35 bool IsValidToplevelWindow(aura::Window* window, const gfx::Rect& bounds) {
23 for (BrowserList::const_iterator iter = BrowserList::begin(); 36 for (BrowserList::const_iterator iter = BrowserList::begin();
24 iter != BrowserList::end(); 37 iter != BrowserList::end();
25 ++iter) { 38 ++iter) {
26 Browser* browser = *iter; 39 Browser* browser = *iter;
27 if (browser && browser->window() && 40 if (browser && browser->window() &&
28 browser->window()->GetNativeWindow() == window) { 41 browser->window()->GetNativeWindow() == window)
29 return (!(browser->is_type_popup() || browser->is_type_panel())); 42 return IsValidBrowser(browser, bounds);
30 }
31 } 43 }
32 // A window which has no browser associated with it is probably not a window 44 // A window which has no browser associated with it is probably not a window
33 // of which we want to copy the size from. 45 // of which we want to copy the size from.
34 return false; 46 return false;
35 } 47 }
36 48
37 // Get the first open window in the stack on the screen. 49 // Get the first open (non minimized) window which is on the screen defined
38 aura::Window* GetTopWindow() { 50 // by |bounds| and visible.
51 aura::Window* GetTopWindow(const gfx::Rect& bounds) {
39 // Get the active window. 52 // Get the active window.
40 aura::Window* window = ash::wm::GetActiveWindow(); 53 aura::Window* window = ash::wm::GetActiveWindow();
41 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL && 54 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL &&
42 window->IsVisible() && IsValidToplevelWindow(window)) 55 window->IsVisible() && IsValidToplevelWindow(window, bounds))
43 return window; 56 return window;
44 57
45 // Get a list of all windows. 58 // Get a list of all windows.
46 const std::vector<aura::Window*> windows = 59 const std::vector<aura::Window*> windows =
47 ash::WindowCycleController::BuildWindowList(NULL); 60 ash::WindowCycleController::BuildWindowList(NULL);
48 61
49 if (windows.empty()) 62 if (windows.empty())
50 return NULL; 63 return NULL;
51 64
52 aura::Window::Windows::const_iterator iter = windows.begin(); 65 aura::Window::Windows::const_iterator iter = windows.begin();
53 // Find the index of the current window. 66 // Find the index of the current window.
54 if (window) 67 if (window)
55 iter = std::find(windows.begin(), windows.end(), window); 68 iter = std::find(windows.begin(), windows.end(), window);
56 69
57 int index = (iter == windows.end()) ? 0 : (iter - windows.begin()); 70 int index = (iter == windows.end()) ? 0 : (iter - windows.begin());
58 71
59 // Scan the cycle list backwards to see which is the second topmost window 72 // 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 73 // (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 74 // suitable window. However - since the list is fairly small this should be
62 // very fast anyways. 75 // very fast anyways.
63 for (int i = index + windows.size(); i >= 0; i--) { 76 for (int i = index + windows.size(); i >= 0; i--) {
64 aura::Window* window = windows[i % windows.size()]; 77 aura::Window* window = windows[i % windows.size()];
65 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL && 78 if (window && window->type() == aura::client::WINDOW_TYPE_NORMAL &&
66 window->IsVisible() && IsValidToplevelWindow(window)) 79 bounds.Intersects(window->GetBoundsInScreen()) &&
80 window->IsVisible() && IsValidToplevelWindow(window, bounds))
67 return window; 81 return window;
68 } 82 }
69 return NULL; 83 return NULL;
70 } 84 }
71 85
86 // Return the number of valid top level windows on the screen defined by
87 // the |bounds| rectangle.
88 int GetNumberOfValidTopLevelBrowserWindows(const gfx::Rect& bounds) {
89 int count = 0;
90 for (BrowserList::const_iterator iter = BrowserList::begin();
91 iter != BrowserList::end();
92 ++iter) {
93 if (IsValidBrowser(*iter, bounds))
94 count++;
95 }
96 return count;
97 }
98
99 // Move the given |bounds| on the available |work_area| to the direction.
100 // If |move_right| is true, the rectangle gets moved to the right corner.
101 // otherwise to the left side.
102 bool MoveRect(const gfx::Rect& work_area, gfx::Rect& bounds, bool move_right) {
103 if (move_right) {
104 if (work_area.right() > bounds.right()) {
105 bounds.set_x(work_area.right() - bounds.width());
106 return true;
107 }
108 } else {
109 if (work_area.x() < bounds.x()) {
110 bounds.set_x(work_area.x());
111 return true;
112 }
113 }
114 return false;
115 }
116
72 } // namespace 117 } // namespace
73 118
74 bool WindowSizer::GetBoundsIgnoringPreviousStateAsh( 119 bool WindowSizer::GetBoundsOverrideAsh(const gfx::Rect& specified_bounds,
75 const gfx::Rect& specified_bounds, 120 gfx::Rect* bounds) const {
76 gfx::Rect* bounds) const {
77 *bounds = specified_bounds; 121 *bounds = specified_bounds;
78 DCHECK(bounds->IsEmpty()); 122 DCHECK(bounds->IsEmpty());
123
124 if (!GetSavedWindowBounds(bounds))
125 GetDefaultWindowBounds(bounds);
126
79 if (browser_ != NULL && browser_->type() == Browser::TYPE_TABBED) { 127 if (browser_ != NULL && browser_->type() == Browser::TYPE_TABBED) {
128 gfx::Rect work_area =
129 monitor_info_provider_->GetMonitorWorkAreaMatching(*bounds);
80 // This is a window / app. See if there is no window and try to place it. 130 // This is a window / app. See if there is no window and try to place it.
81 aura::Window* top_window = GetTopWindow(); 131 int count = GetNumberOfValidTopLevelBrowserWindows(work_area);
82 // If there are no windows we have a special case and try to 132 aura::Window* top_window = GetTopWindow(work_area);
83 // maximize which leaves a 'border' which shows the desktop. 133
84 if (top_window == NULL) { 134 // If there is no valid other window we take the coordinates as is.
85 GetDefaultWindowBounds(bounds); 135 if (!count || !top_window || ash::wm::IsWindowMaximized(top_window))
86 } else { 136 return true;
87 *bounds = top_window->GetBoundsInScreen(); 137
88 gfx::Rect work_area = 138 gfx::Rect other_bounds = top_window->bounds();
89 monitor_info_provider_->GetMonitorWorkAreaMatching(*bounds); 139 bool move_right =
90 *bounds = bounds->AdjustToFit(work_area); 140 other_bounds.CenterPoint().x() < work_area.CenterPoint().x();
141
142 // In case we have only one window, we move the other window fully to the
143 // "other side" - making room for this new window.
144 if (count == 1) {
145 if (MoveRect(work_area, other_bounds, !move_right))
sky 2012/09/13 17:32:02 You're comparing screen bounds and non-screen boun
Mr4D (OOO till 08-26) 2012/09/13 18:56:59 Thanks for your explanations of the term 'screen'
146 top_window->SetBounds(other_bounds);
sky 2012/09/13 17:32:02 Moving a window makes me nervous. Consider the cas
Mr4D (OOO till 08-26) 2012/09/13 18:56:59 Well - this automatic movement was requested by Al
91 } 147 }
148 // Use the size of the other window, and mirror the location to the
149 // opposite side. Then make sure that it is inside our work area
150 // (if possible).
151 *bounds = other_bounds;
152 MoveRect(work_area, *bounds, move_right);
153 if (bounds->bottom() > work_area.bottom())
154 bounds->set_y(std::max(work_area.y(),
155 work_area.bottom() - bounds->height()));
92 return true; 156 return true;
93 // If both fail we will continue the default path.
94 } 157 }
95 158
96 return false; 159 return false;
97 } 160 }
98 161
99 void WindowSizer::GetDefaultWindowBoundsAsh(gfx::Rect* default_bounds) const { 162 void WindowSizer::GetDefaultWindowBoundsAsh(gfx::Rect* default_bounds) const {
100 DCHECK(default_bounds); 163 DCHECK(default_bounds);
101 DCHECK(monitor_info_provider_.get()); 164 DCHECK(monitor_info_provider_.get());
102 165
103 gfx::Rect work_area = monitor_info_provider_->GetPrimaryDisplayWorkArea(); 166 gfx::Rect work_area = monitor_info_provider_->GetPrimaryDisplayWorkArea();
(...skipping 12 matching lines...) Expand all
116 if (default_width > kMaximumWindowWidth) { 179 if (default_width > kMaximumWindowWidth) {
117 // The window should get centered on the screen and not follow the grid. 180 // The window should get centered on the screen and not follow the grid.
118 offset_x = (work_area.width() - kMaximumWindowWidth) / 2; 181 offset_x = (work_area.width() - kMaximumWindowWidth) / 2;
119 default_width = kMaximumWindowWidth; 182 default_width = kMaximumWindowWidth;
120 } 183 }
121 default_bounds->SetRect(work_area.x() + offset_x, 184 default_bounds->SetRect(work_area.x() + offset_x,
122 work_area.y() + kDesktopBorderSize, 185 work_area.y() + kDesktopBorderSize,
123 default_width, 186 default_width,
124 default_height); 187 default_height);
125 } 188 }
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