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

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

Issue 165173: Merge 21946 - Move window to workarea origin if it is completely offscreen.... (Closed) Base URL: svn://chrome-svn/chrome/branches/195/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 | Annotate | Revision Log
« 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')
Property Changes:
Modified: svn:mergeinfo
Merged /trunk/src/chrome/browser/window_sizer.cc:r21946
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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 } 248 }
229 249
230 namespace { 250 namespace {
231 // Minimum height of the visible part of a window. 251 // Minimum height of the visible part of a window.
232 static const int kMinVisibleHeight = 30; 252 static const int kMinVisibleHeight = 30;
233 // Minimum width of the visible part of a window. 253 // Minimum width of the visible part of a window.
234 static const int kMinVisibleWidth = 30; 254 static const int kMinVisibleWidth = 30;
235 } 255 }
236 256
237 void WindowSizer::AdjustBoundsToBeVisibleOnMonitorContaining( 257 void WindowSizer::AdjustBoundsToBeVisibleOnMonitorContaining(
238 const gfx::Rect& other_bounds, gfx::Rect* bounds) const { 258 const gfx::Rect& other_bounds,
259 const gfx::Rect& saved_work_area,
260 gfx::Rect* bounds) const {
239 DCHECK(bounds); 261 DCHECK(bounds);
240 DCHECK(monitor_info_provider_); 262 DCHECK(monitor_info_provider_);
241 263
242 // Find the size of the work area of the monitor that intersects the bounds 264 // Find the size of the work area of the monitor that intersects the bounds
243 // of the anchor window. 265 // of the anchor window.
244 gfx::Rect work_area = 266 gfx::Rect work_area =
245 monitor_info_provider_->GetMonitorWorkAreaMatching(other_bounds); 267 monitor_info_provider_->GetMonitorWorkAreaMatching(other_bounds);
246 268
247 // If height or width are 0, reset to the default size. 269 // If height or width are 0, reset to the default size.
248 gfx::Rect default_bounds; 270 gfx::Rect default_bounds;
249 GetDefaultWindowBounds(&default_bounds); 271 GetDefaultWindowBounds(&default_bounds);
250 if (bounds->height() <= 0) 272 if (bounds->height() <= 0)
251 bounds->set_height(default_bounds.height()); 273 bounds->set_height(default_bounds.height());
252 if (bounds->width() <= 0) 274 if (bounds->width() <= 0)
253 bounds->set_width(default_bounds.width()); 275 bounds->set_width(default_bounds.width());
254 276
255 // Ensure the minimum height and width. 277 // Ensure the minimum height and width.
256 bounds->set_height(std::max(kMinVisibleHeight, bounds->height())); 278 bounds->set_height(std::max(kMinVisibleHeight, bounds->height()));
257 bounds->set_width(std::max(kMinVisibleWidth, bounds->width())); 279 bounds->set_width(std::max(kMinVisibleWidth, bounds->width()));
258 280
281 // Ensure that the title bar is not above the work area.
282 if (bounds->y() < work_area.y())
283 bounds->set_y(work_area.y());
284
285 // Reposition and resize the bounds if the saved_work_area is different from
286 // the current work area and the current work area doesn't completely contain
287 // the bounds.
288 if (!saved_work_area.IsEmpty() &&
289 saved_work_area != work_area &&
290 !work_area.Contains(*bounds)) {
291 bounds->set_width(std::min(bounds->width(), work_area.width()));
292 bounds->set_height(std::min(bounds->height(), work_area.height()));
293 bounds->set_x(
294 std::max(work_area.x(),
295 std::min(bounds->x(), work_area.right() - bounds->width())));
296 bounds->set_y(
297 std::max(work_area.y(),
298 std::min(bounds->y(), work_area.bottom() - bounds->height())));
299 }
300
259 #if defined(OS_MACOSX) 301 #if defined(OS_MACOSX)
260 // Limit the maximum height. On the Mac the sizer is on the 302 // Limit the maximum height. On the Mac the sizer is on the
261 // bottom-right of the window, and a window cannot be moved "up" 303 // bottom-right of the window, and a window cannot be moved "up"
262 // past the menubar. If the window is too tall you'll never be able 304 // past the menubar. If the window is too tall you'll never be able
263 // to shrink it again. Windows does not have this limitation 305 // to shrink it again. Windows does not have this limitation
264 // (e.g. can be resized from the top). 306 // (e.g. can be resized from the top).
265 bounds->set_height(std::min(work_area.height(), bounds->height())); 307 bounds->set_height(std::min(work_area.height(), bounds->height()));
266 #endif // defined(OS_MACOSX) 308 #endif // defined(OS_MACOSX)
267 309
268 // Ensure at least kMinVisibleWidth * kMinVisibleHeight is visible. 310 // Ensure at least kMinVisibleWidth * kMinVisibleHeight is visible.
269 const int min_y = work_area.y() + kMinVisibleHeight - bounds->height(); 311 const int min_y = work_area.y() + kMinVisibleHeight - bounds->height();
270 const int min_x = work_area.x() + kMinVisibleWidth - bounds->width(); 312 const int min_x = work_area.x() + kMinVisibleWidth - bounds->width();
271 const int max_y = work_area.bottom() - kMinVisibleHeight; 313 const int max_y = work_area.bottom() - kMinVisibleHeight;
272 const int max_x = work_area.right() - kMinVisibleWidth; 314 const int max_x = work_area.right() - kMinVisibleWidth;
273 bounds->set_y(std::max(min_y, std::min(max_y, bounds->y()))); 315 bounds->set_y(std::max(min_y, std::min(max_y, bounds->y())));
274 bounds->set_x(std::max(min_x, std::min(max_x, bounds->x()))); 316 bounds->set_x(std::max(min_x, std::min(max_x, bounds->x())));
275 } 317 }
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