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

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

Issue 160246: Reposition and/or resize window if it becomes off-screen.... (Closed) Base URL: svn://chrome-svn.corp.google.com/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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
« no previous file with comments | « chrome/browser/window_sizer.h ('k') | chrome/browser/window_sizer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/window_sizer.h" 5 #include "chrome/browser/window_sizer.h"
6 6
7 #include "chrome/browser/browser.h" 7 #include "chrome/browser/browser.h"
8 #include "chrome/browser/browser_list.h" 8 #include "chrome/browser/browser_list.h"
9 #include "chrome/browser/browser_process.h" 9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/browser_window.h" 10 #include "chrome/browser/browser_window.h"
11 #include "chrome/common/pref_names.h" 11 #include "chrome/common/pref_names.h"
12 #include "chrome/common/pref_service.h" 12 #include "chrome/common/pref_service.h"
13 13
14 /////////////////////////////////////////////////////////////////////////////// 14 ///////////////////////////////////////////////////////////////////////////////
15 // An implementation of WindowSizer::StateProvider that gets the last active 15 // An implementation of WindowSizer::StateProvider that gets the last active
16 // and persistent state from the browser window and the user's profile. 16 // and persistent state from the browser window and the user's profile.
17 class DefaultStateProvider : public WindowSizer::StateProvider { 17 class DefaultStateProvider : public WindowSizer::StateProvider {
18 public: 18 public:
19 explicit DefaultStateProvider(const std::wstring& app_name, Browser* browser) 19 explicit DefaultStateProvider(const std::wstring& app_name, Browser* browser)
20 : app_name_(app_name), 20 : app_name_(app_name),
21 browser_(browser) { 21 browser_(browser) {
22 } 22 }
23 23
24 // Overridden from WindowSizer::StateProvider: 24 // Overridden from WindowSizer::StateProvider:
25 virtual bool GetPersistentState(gfx::Rect* bounds, bool* maximized) const { 25 virtual bool GetPersistentState(gfx::Rect* bounds,
26 bool* maximized,
27 gfx::Rect* work_area) const {
26 DCHECK(bounds && maximized); 28 DCHECK(bounds && maximized);
27 29
28 std::wstring key(prefs::kBrowserWindowPlacement); 30 std::wstring key(prefs::kBrowserWindowPlacement);
29 if (!app_name_.empty()) { 31 if (!app_name_.empty()) {
30 key.append(L"_"); 32 key.append(L"_");
31 key.append(app_name_); 33 key.append(app_name_);
32 } 34 }
33 35
34 if (!g_browser_process->local_state()) 36 if (!g_browser_process->local_state())
35 return false; 37 return false;
36 38
37 const DictionaryValue* wp_pref = 39 const DictionaryValue* wp_pref =
38 g_browser_process->local_state()->GetDictionary(key.c_str()); 40 g_browser_process->local_state()->GetDictionary(key.c_str());
39 int top = 0, left = 0, bottom = 0, right = 0; 41 int top = 0, left = 0, bottom = 0, right = 0;
40 bool has_prefs = 42 bool has_prefs =
41 wp_pref && 43 wp_pref &&
42 wp_pref->GetInteger(L"top", &top) && 44 wp_pref->GetInteger(L"top", &top) &&
43 wp_pref->GetInteger(L"left", &left) && 45 wp_pref->GetInteger(L"left", &left) &&
44 wp_pref->GetInteger(L"bottom", &bottom) && 46 wp_pref->GetInteger(L"bottom", &bottom) &&
45 wp_pref->GetInteger(L"right", &right) && 47 wp_pref->GetInteger(L"right", &right) &&
46 wp_pref->GetBoolean(L"maximized", maximized); 48 wp_pref->GetBoolean(L"maximized", maximized);
47 bounds->SetRect(left, top, std::max(0, right - left), 49 bounds->SetRect(left, top, std::max(0, right - left),
48 std::max(0, bottom - top)); 50 std::max(0, bottom - top));
51
52 int work_area_top = 0;
53 int work_area_left = 0;
54 int work_area_bottom = 0;
55 int work_area_right = 0;
56 if (wp_pref) {
57 wp_pref->GetInteger(L"work_area_top", &work_area_top);
58 wp_pref->GetInteger(L"work_area_left", &work_area_left);
59 wp_pref->GetInteger(L"work_area_bottom", &work_area_bottom);
60 wp_pref->GetInteger(L"work_area_right", &work_area_right);
61 }
62 work_area->SetRect(work_area_left, work_area_top,
63 std::max(0, work_area_right - work_area_left),
64 std::max(0, work_area_bottom - work_area_top));
65
49 return has_prefs; 66 return has_prefs;
50 } 67 }
51 68
52 virtual bool GetLastActiveWindowState(gfx::Rect* bounds) const { 69 virtual bool GetLastActiveWindowState(gfx::Rect* bounds) const {
53 // Applications are always restored with the same position. 70 // Applications are always restored with the same position.
54 if (!app_name_.empty()) 71 if (!app_name_.empty())
55 return false; 72 return false;
56 73
57 // If a reference browser is set, use its window. Otherwise find last 74 // If a reference browser is set, use its window. Otherwise find last
58 // active. 75 // active.
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 } 162 }
146 } 163 }
147 } 164 }
148 165
149 bool WindowSizer::GetLastWindowBounds(gfx::Rect* bounds) const { 166 bool WindowSizer::GetLastWindowBounds(gfx::Rect* bounds) const {
150 DCHECK(bounds); 167 DCHECK(bounds);
151 if (!state_provider_ || !state_provider_->GetLastActiveWindowState(bounds)) 168 if (!state_provider_ || !state_provider_->GetLastActiveWindowState(bounds))
152 return false; 169 return false;
153 gfx::Rect last_window_bounds = *bounds; 170 gfx::Rect last_window_bounds = *bounds;
154 bounds->Offset(kWindowTilePixels, kWindowTilePixels); 171 bounds->Offset(kWindowTilePixels, kWindowTilePixels);
155 AdjustBoundsToBeVisibleOnMonitorContaining(last_window_bounds, bounds); 172 AdjustBoundsToBeVisibleOnMonitorContaining(last_window_bounds,
173 gfx::Rect(),
174 bounds);
156 return true; 175 return true;
157 } 176 }
158 177
159 bool WindowSizer::GetSavedWindowBounds(gfx::Rect* bounds, 178 bool WindowSizer::GetSavedWindowBounds(gfx::Rect* bounds,
160 bool* maximized) const { 179 bool* maximized) const {
161 DCHECK(bounds && maximized); 180 DCHECK(bounds && maximized);
181 gfx::Rect saved_work_area;
162 if (!state_provider_ || 182 if (!state_provider_ ||
163 !state_provider_->GetPersistentState(bounds, maximized)) 183 !state_provider_->GetPersistentState(bounds, maximized, &saved_work_area))
164 return false; 184 return false;
165 AdjustBoundsToBeVisibleOnMonitorContaining(*bounds, bounds); 185 AdjustBoundsToBeVisibleOnMonitorContaining(*bounds, saved_work_area, bounds);
166 return true; 186 return true;
167 } 187 }
168 188
169 void WindowSizer::GetDefaultWindowBounds(gfx::Rect* default_bounds) const { 189 void WindowSizer::GetDefaultWindowBounds(gfx::Rect* default_bounds) const {
170 DCHECK(default_bounds); 190 DCHECK(default_bounds);
171 DCHECK(monitor_info_provider_); 191 DCHECK(monitor_info_provider_);
172 192
173 gfx::Rect work_area = monitor_info_provider_->GetPrimaryMonitorWorkArea(); 193 gfx::Rect work_area = monitor_info_provider_->GetPrimaryMonitorWorkArea();
174 194
175 // The default size is either some reasonably wide width, or if the work 195 // The default size is either some reasonably wide width, or if the work
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 } 246 }
227 247
228 namespace { 248 namespace {
229 // Minimum height of the visible part of a window. 249 // Minimum height of the visible part of a window.
230 static const int kMinVisibleHeight = 30; 250 static const int kMinVisibleHeight = 30;
231 // Minimum width of the visible part of a window. 251 // Minimum width of the visible part of a window.
232 static const int kMinVisibleWidth = 30; 252 static const int kMinVisibleWidth = 30;
233 } 253 }
234 254
235 void WindowSizer::AdjustBoundsToBeVisibleOnMonitorContaining( 255 void WindowSizer::AdjustBoundsToBeVisibleOnMonitorContaining(
236 const gfx::Rect& other_bounds, gfx::Rect* bounds) const { 256 const gfx::Rect& other_bounds,
257 const gfx::Rect& saved_work_area,
258 gfx::Rect* bounds) const {
237 DCHECK(bounds); 259 DCHECK(bounds);
238 DCHECK(monitor_info_provider_); 260 DCHECK(monitor_info_provider_);
239 261
240 // Find the size of the work area of the monitor that intersects the bounds 262 // Find the size of the work area of the monitor that intersects the bounds
241 // of the anchor window. 263 // of the anchor window.
242 gfx::Rect work_area = 264 gfx::Rect work_area =
243 monitor_info_provider_->GetMonitorWorkAreaMatching(other_bounds); 265 monitor_info_provider_->GetMonitorWorkAreaMatching(other_bounds);
244 266
245 // If height or width are 0, reset to the default size. 267 // If height or width are 0, reset to the default size.
246 gfx::Rect default_bounds; 268 gfx::Rect default_bounds;
247 GetDefaultWindowBounds(&default_bounds); 269 GetDefaultWindowBounds(&default_bounds);
248 if (bounds->height() <= 0) 270 if (bounds->height() <= 0)
249 bounds->set_height(default_bounds.height()); 271 bounds->set_height(default_bounds.height());
250 if (bounds->width() <= 0) 272 if (bounds->width() <= 0)
251 bounds->set_width(default_bounds.width()); 273 bounds->set_width(default_bounds.width());
252 274
253 // Ensure the minimum height and width. 275 // Ensure the minimum height and width.
254 bounds->set_height(std::max(kMinVisibleHeight, bounds->height())); 276 bounds->set_height(std::max(kMinVisibleHeight, bounds->height()));
255 bounds->set_width(std::max(kMinVisibleWidth, bounds->width())); 277 bounds->set_width(std::max(kMinVisibleWidth, bounds->width()));
256 278
279 // Ensure that the title bar is not above the work area.
280 if (bounds->y() < work_area.y())
281 bounds->set_y(work_area.y());
282
283 // Reposition and resize the bounds if the saved_work_area is different from
284 // the current work area and the current work area doesn't completely contain
285 // the bounds.
286 if (!saved_work_area.IsEmpty() &&
287 saved_work_area != work_area &&
288 !work_area.Contains(*bounds)) {
289 bounds->set_width(std::min(bounds->width(), work_area.width()));
290 bounds->set_height(std::min(bounds->height(), work_area.height()));
291 bounds->set_x(
292 std::max(work_area.x(),
293 std::min(bounds->x(), work_area.right() - bounds->width())));
294 bounds->set_y(
295 std::max(work_area.y(),
296 std::min(bounds->y(), work_area.bottom() - bounds->height())));
297 }
298
257 #if defined(OS_MACOSX) 299 #if defined(OS_MACOSX)
258 // Limit the maximum height. On the Mac the sizer is on the 300 // Limit the maximum height. On the Mac the sizer is on the
259 // bottom-right of the window, and a window cannot be moved "up" 301 // bottom-right of the window, and a window cannot be moved "up"
260 // past the menubar. If the window is too tall you'll never be able 302 // past the menubar. If the window is too tall you'll never be able
261 // to shrink it again. Windows does not have this limitation 303 // to shrink it again. Windows does not have this limitation
262 // (e.g. can be resized from the top). 304 // (e.g. can be resized from the top).
263 bounds->set_height(std::min(work_area.height(), bounds->height())); 305 bounds->set_height(std::min(work_area.height(), bounds->height()));
264 #endif // defined(OS_MACOSX) 306 #endif // defined(OS_MACOSX)
265 307
266 // Ensure at least kMinVisibleWidth * kMinVisibleHeight is visible. 308 // Ensure at least kMinVisibleWidth * kMinVisibleHeight is visible.
267 const int min_y = work_area.y() + kMinVisibleHeight - bounds->height(); 309 const int min_y = work_area.y() + kMinVisibleHeight - bounds->height();
268 const int min_x = work_area.x() + kMinVisibleWidth - bounds->width(); 310 const int min_x = work_area.x() + kMinVisibleWidth - bounds->width();
269 const int max_y = work_area.bottom() - kMinVisibleHeight; 311 const int max_y = work_area.bottom() - kMinVisibleHeight;
270 const int max_x = work_area.right() - kMinVisibleWidth; 312 const int max_x = work_area.right() - kMinVisibleWidth;
271 bounds->set_y(std::max(min_y, std::min(max_y, bounds->y()))); 313 bounds->set_y(std::max(min_y, std::min(max_y, bounds->y())));
272 bounds->set_x(std::max(min_x, std::min(max_x, bounds->x()))); 314 bounds->set_x(std::max(min_x, std::min(max_x, bounds->x())));
273 } 315 }
OLDNEW
« no previous file with comments | « chrome/browser/window_sizer.h ('k') | chrome/browser/window_sizer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698