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

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