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

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

Issue 102773002: Open non browser window on the target display (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years 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 "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/prefs/pref_service.h" 9 #include "base/prefs/pref_service.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.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 "chrome/browser/ui/browser_window_state.h" 15 #include "chrome/browser/ui/browser_window_state.h"
16 #include "chrome/browser/ui/host_desktop.h" 16 #include "chrome/browser/ui/host_desktop.h"
17 #include "chrome/common/chrome_switches.h" 17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/pref_names.h" 18 #include "chrome/common/pref_names.h"
19 #include "ui/gfx/screen.h" 19 #include "ui/gfx/screen.h"
20 20
21 #if defined(USE_ASH) 21 #if defined(USE_ASH)
22 #include "ash/shell.h" 22 #include "ash/shell.h"
23 #include "ash/wm/window_positioner.h" 23 #include "ash/wm/window_positioner.h"
24 #include "chrome/browser/ui/ash/ash_init.h" 24 #include "chrome/browser/ui/ash/ash_init.h"
25 #endif 25 #endif
26 26
27 namespace {
28
27 // Minimum height of the visible part of a window. 29 // Minimum height of the visible part of a window.
28 const int kMinVisibleHeight = 30; 30 const int kMinVisibleHeight = 30;
29 // Minimum width of the visible part of a window. 31 // Minimum width of the visible part of a window.
30 const int kMinVisibleWidth = 30; 32 const int kMinVisibleWidth = 30;
31 33
32 /////////////////////////////////////////////////////////////////////////////// 34 ///////////////////////////////////////////////////////////////////////////////
33 // An implementation of WindowSizer::StateProvider that gets the last active 35 // An implementation of WindowSizer::StateProvider that gets the last active
34 // and persistent state from the browser window and the user's profile. 36 // and persistent state from the browser window and the user's profile.
35 class DefaultStateProvider : public WindowSizer::StateProvider { 37 class DefaultStateProvider : public WindowSizer::StateProvider {
36 public: 38 public:
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 } 130 }
129 131
130 private: 132 private:
131 std::string app_name_; 133 std::string app_name_;
132 134
133 // If set, is used as the reference browser for GetLastActiveWindowState. 135 // If set, is used as the reference browser for GetLastActiveWindowState.
134 const Browser* browser_; 136 const Browser* browser_;
135 DISALLOW_COPY_AND_ASSIGN(DefaultStateProvider); 137 DISALLOW_COPY_AND_ASSIGN(DefaultStateProvider);
136 }; 138 };
137 139
140 class DefaultTargetDisplayProvider : public WindowSizer::TargetDisplayProvider {
141 public:
142 DefaultTargetDisplayProvider() {}
143 virtual ~DefaultTargetDisplayProvider() {}
144
145 virtual gfx::Display GetTargetDisplay(
146 const gfx::Screen* screen,
147 const gfx::Rect& bounds) const OVERRIDE {
148 #if defined(USE_ASH)
149 // Use the target display on ash.
150 if (chrome::ShouldOpenAshOnStartup()) {
151 aura::Window* target = ash::Shell::GetTargetRootWindow();
152 return screen->GetDisplayNearestWindow(target);
153 }
154 #endif
155 // Find the size of the work area of the monitor that intersects the bounds
156 // of the anchor window.
157 return screen->GetDisplayMatching(bounds);
158 }
159
160 private:
161 const gfx::Screen* screen_;
sky 2013/12/07 00:40:28 I don't think you use this.
oshima 2013/12/07 01:01:38 oops, removed.
162
163 DISALLOW_COPY_AND_ASSIGN(DefaultTargetDisplayProvider);
164 };
165
166 } // namespace
167
138 /////////////////////////////////////////////////////////////////////////////// 168 ///////////////////////////////////////////////////////////////////////////////
139 // WindowSizer, public: 169 // WindowSizer, public:
140 170
141 WindowSizer::WindowSizer(StateProvider* state_provider, const Browser* browser) 171 WindowSizer::WindowSizer(StateProvider* state_provider,
172 TargetDisplayProvider* target_display_provider,
173 const Browser* browser)
142 : state_provider_(state_provider), 174 : state_provider_(state_provider),
175 target_display_provider_(target_display_provider),
143 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312 176 // TODO(scottmg): NativeScreen is wrong. http://crbug.com/133312
144 screen_(gfx::Screen::GetNativeScreen()), 177 screen_(gfx::Screen::GetNativeScreen()),
145 browser_(browser) { 178 browser_(browser) {
146 } 179 }
147 180
148 WindowSizer::WindowSizer(StateProvider* state_provider, 181 WindowSizer::WindowSizer(StateProvider* state_provider,
182 TargetDisplayProvider* target_display_provider,
149 gfx::Screen* screen, 183 gfx::Screen* screen,
150 const Browser* browser) 184 const Browser* browser)
151 : state_provider_(state_provider), 185 : state_provider_(state_provider),
186 target_display_provider_(target_display_provider),
152 screen_(screen), 187 screen_(screen),
153 browser_(browser) { 188 browser_(browser) {
154 DCHECK(screen_); 189 DCHECK(screen_);
155 } 190 }
156 191
157 WindowSizer::~WindowSizer() { 192 WindowSizer::~WindowSizer() {
158 } 193 }
159 194
160 // static 195 // static
161 void WindowSizer::GetBrowserWindowBoundsAndShowState( 196 void WindowSizer::GetBrowserWindowBoundsAndShowState(
162 const std::string& app_name, 197 const std::string& app_name,
163 const gfx::Rect& specified_bounds, 198 const gfx::Rect& specified_bounds,
164 const Browser* browser, 199 const Browser* browser,
165 gfx::Rect* window_bounds, 200 gfx::Rect* window_bounds,
166 ui::WindowShowState* show_state) { 201 ui::WindowShowState* show_state) {
167 const WindowSizer sizer(new DefaultStateProvider(app_name, browser), browser); 202 const WindowSizer sizer(new DefaultStateProvider(app_name, browser),
203 new DefaultTargetDisplayProvider,
204 browser);
168 sizer.DetermineWindowBoundsAndShowState(specified_bounds, 205 sizer.DetermineWindowBoundsAndShowState(specified_bounds,
169 window_bounds, 206 window_bounds,
170 show_state); 207 show_state);
171 } 208 }
172 209
173 /////////////////////////////////////////////////////////////////////////////// 210 ///////////////////////////////////////////////////////////////////////////////
174 // WindowSizer, private: 211 // WindowSizer, private:
175 212
176 void WindowSizer::DetermineWindowBoundsAndShowState( 213 void WindowSizer::DetermineWindowBoundsAndShowState(
177 const gfx::Rect& specified_bounds, 214 const gfx::Rect& specified_bounds,
(...skipping 11 matching lines...) Expand all
189 GetTabbedBrowserBoundsAsh(bounds, show_state); 226 GetTabbedBrowserBoundsAsh(bounds, show_state);
190 return; 227 return;
191 } else if (browser_ && browser_->host_desktop_type() == 228 } else if (browser_ && browser_->host_desktop_type() ==
192 chrome::HOST_DESKTOP_TYPE_ASH) { 229 chrome::HOST_DESKTOP_TYPE_ASH) {
193 // In ash, saved show state takes precidence. If you have a 230 // In ash, saved show state takes precidence. If you have a
194 // question or an issue, please contact oshima@chromium.org. 231 // question or an issue, please contact oshima@chromium.org.
195 GetSavedWindowBounds(bounds, show_state); 232 GetSavedWindowBounds(bounds, show_state);
196 } 233 }
197 #endif 234 #endif
198 // See if there's last active window's placement information. 235 // See if there's last active window's placement information.
199 if (GetLastWindowBounds(bounds, show_state)) 236 if (GetLastActiveWindowBounds(bounds, show_state))
200 return; 237 return;
201 // See if there's saved placement information. 238 // See if there's saved placement information.
202 if (GetSavedWindowBounds(bounds, show_state)) 239 if (GetSavedWindowBounds(bounds, show_state))
203 return; 240 return;
204 // No saved placement, figure out some sensible default size based on 241 // No saved placement, figure out some sensible default size based on
205 // the user's screen size. 242 // the user's screen size.
206 GetDefaultWindowBounds(screen_->GetPrimaryDisplay(), bounds); 243 GetDefaultWindowBounds(GetTargetDisplay(gfx::Rect()), bounds);
207 } else { 244 } else {
208 #if defined(USE_ASH) 245 #if defined(USE_ASH)
209 // In case of a popup with an 'unspecified' location in ash, we are 246 // In case of a popup with an 'unspecified' location in ash, we are
210 // looking for a good screen location. We are interpreting (0,0) as an 247 // looking for a good screen location. We are interpreting (0,0) as an
211 // unspecified location. 248 // unspecified location.
212 if (IsPopupBrowserInAsh() && bounds->origin().IsOrigin()) { 249 if (IsPopupBrowserInAsh() && bounds->origin().IsOrigin()) {
213 *bounds = ash::Shell::GetInstance()->window_positioner()-> 250 *bounds = ash::Shell::GetInstance()->window_positioner()->
214 GetPopupPosition(*bounds); 251 GetPopupPosition(*bounds);
215 return; 252 return;
216 } 253 }
217 #endif 254 #endif
218 // In case that there was a bound given we need to make sure that it is 255 // In case that there was a bound given we need to make sure that it is
219 // visible and fits on the screen. 256 // visible and fits on the screen.
220 // Find the size of the work area of the monitor that intersects the bounds 257 // Find the size of the work area of the monitor that intersects the bounds
221 // of the anchor window. Note: AdjustBoundsToBeVisibleOnMonitorContaining 258 // of the anchor window. Note: AdjustBoundsToBeVisibleOnMonitorContaining
222 // does not exactly what we want: It makes only sure that "a minimal part" 259 // does not exactly what we want: It makes only sure that "a minimal part"
223 // is visible on the screen. 260 // is visible on the screen.
224 gfx::Rect work_area = screen_->GetDisplayMatching(*bounds).work_area(); 261 gfx::Rect work_area = screen_->GetDisplayMatching(*bounds).work_area();
225 // Resize so that it fits. 262 // Resize so that it fits.
226 bounds->AdjustToFit(work_area); 263 bounds->AdjustToFit(work_area);
227 } 264 }
228 } 265 }
229 266
230 bool WindowSizer::GetLastWindowBounds(gfx::Rect* bounds, 267 bool WindowSizer::GetLastActiveWindowBounds(
231 ui::WindowShowState* show_state) const { 268 gfx::Rect* bounds,
269 ui::WindowShowState* show_state) const {
232 DCHECK(bounds); 270 DCHECK(bounds);
233 DCHECK(show_state); 271 DCHECK(show_state);
234 if (!state_provider_.get() || 272 if (!state_provider_.get() ||
235 !state_provider_->GetLastActiveWindowState(bounds, show_state)) 273 !state_provider_->GetLastActiveWindowState(bounds, show_state))
236 return false; 274 return false;
237 gfx::Rect last_window_bounds = *bounds; 275 gfx::Rect last_window_bounds = *bounds;
238 bounds->Offset(kWindowTilePixels, kWindowTilePixels); 276 bounds->Offset(kWindowTilePixels, kWindowTilePixels);
239 AdjustBoundsToBeVisibleOnMonitorContaining(last_window_bounds, 277 AdjustBoundsToBeVisibleOnDisplay(screen_->GetDisplayMatching(*bounds),
240 gfx::Rect(), 278 gfx::Rect(),
241 bounds); 279 bounds);
242 return true; 280 return true;
243 } 281 }
244 282
245 bool WindowSizer::GetSavedWindowBounds(gfx::Rect* bounds, 283 bool WindowSizer::GetSavedWindowBounds(gfx::Rect* bounds,
246 ui::WindowShowState* show_state) const { 284 ui::WindowShowState* show_state) const {
247 DCHECK(bounds); 285 DCHECK(bounds);
248 DCHECK(show_state); 286 DCHECK(show_state);
249 gfx::Rect saved_work_area; 287 gfx::Rect saved_work_area;
250 if (!state_provider_.get() || 288 if (!state_provider_.get() ||
251 !state_provider_->GetPersistentState(bounds, 289 !state_provider_->GetPersistentState(bounds,
252 &saved_work_area, 290 &saved_work_area,
253 show_state)) 291 show_state))
254 return false; 292 return false;
255 AdjustBoundsToBeVisibleOnMonitorContaining(*bounds, saved_work_area, bounds); 293 AdjustBoundsToBeVisibleOnDisplay(GetTargetDisplay(*bounds),
294 saved_work_area,
295 bounds);
256 return true; 296 return true;
257 } 297 }
258 298
259 void WindowSizer::GetDefaultWindowBounds(const gfx::Display& display, 299 void WindowSizer::GetDefaultWindowBounds(const gfx::Display& display,
260 gfx::Rect* default_bounds) const { 300 gfx::Rect* default_bounds) const {
261 DCHECK(default_bounds); 301 DCHECK(default_bounds);
262 #if defined(USE_ASH) 302 #if defined(USE_ASH)
263 // TODO(beng): insufficient but currently necessary. http://crbug.com/133312 303 // TODO(beng): insufficient but currently necessary. http://crbug.com/133312
264 if (chrome::ShouldOpenAshOnStartup()) { 304 if (chrome::ShouldOpenAshOnStartup()) {
265 *default_bounds = ash::WindowPositioner::GetDefaultWindowBounds( 305 *default_bounds = ash::WindowPositioner::GetDefaultWindowBounds(display);
266 display);
267 return; 306 return;
268 } 307 }
269 #endif 308 #endif
270 gfx::Rect work_area = display.work_area(); 309 gfx::Rect work_area = display.work_area();
271 310
272 // The default size is either some reasonably wide width, or if the work 311 // The default size is either some reasonably wide width, or if the work
273 // area is narrower, then the work area width less some aesthetic padding. 312 // area is narrower, then the work area width less some aesthetic padding.
274 int default_width = std::min(work_area.width() - 2 * kWindowTilePixels, 1050); 313 int default_width = std::min(work_area.width() - 2 * kWindowTilePixels, 1050);
275 int default_height = work_area.height() - 2 * kWindowTilePixels; 314 int default_height = work_area.height() - 2 * kWindowTilePixels;
276 315
(...skipping 13 matching lines...) Expand all
290 // The padding is set so that two windows, side by side have 329 // The padding is set so that two windows, side by side have
291 // kWindowTilePixels between screen edge and each other. 330 // kWindowTilePixels between screen edge and each other.
292 default_width = static_cast<int>(work_area.width() / 2. - 331 default_width = static_cast<int>(work_area.width() / 2. -
293 1.5 * kWindowTilePixels); 332 1.5 * kWindowTilePixels);
294 } 333 }
295 default_bounds->SetRect(kWindowTilePixels + work_area.x(), 334 default_bounds->SetRect(kWindowTilePixels + work_area.x(),
296 kWindowTilePixels + work_area.y(), 335 kWindowTilePixels + work_area.y(),
297 default_width, default_height); 336 default_width, default_height);
298 } 337 }
299 338
300 void WindowSizer::AdjustBoundsToBeVisibleOnMonitorContaining( 339 void WindowSizer::AdjustBoundsToBeVisibleOnDisplay(
301 const gfx::Rect& other_bounds, 340 const gfx::Display& display,
302 const gfx::Rect& saved_work_area, 341 const gfx::Rect& saved_work_area,
303 gfx::Rect* bounds) const { 342 gfx::Rect* bounds) const {
304 DCHECK(bounds); 343 DCHECK(bounds);
305 344
306 // Find the size of the work area of the monitor that intersects the bounds 345 // If |bounds| is empty, reset to the default size.
307 // of the anchor window. 346 if (bounds->IsEmpty()) {
308 gfx::Display display = screen_->GetDisplayMatching(other_bounds); 347 gfx::Rect default_bounds;
309 348 GetDefaultWindowBounds(display, &default_bounds);
310 // If height or width are 0, reset to the default size. 349 if (bounds->height() <= 0)
311 gfx::Rect default_bounds; 350 bounds->set_height(default_bounds.height());
312 GetDefaultWindowBounds(display, &default_bounds); 351 if (bounds->width() <= 0)
313 if (bounds->height() <= 0) 352 bounds->set_width(default_bounds.width());
314 bounds->set_height(default_bounds.height()); 353 }
315 if (bounds->width() <= 0)
316 bounds->set_width(default_bounds.width());
317 354
318 // Ensure the minimum height and width. 355 // Ensure the minimum height and width.
319 bounds->set_height(std::max(kMinVisibleHeight, bounds->height())); 356 bounds->set_height(std::max(kMinVisibleHeight, bounds->height()));
320 bounds->set_width(std::max(kMinVisibleWidth, bounds->width())); 357 bounds->set_width(std::max(kMinVisibleWidth, bounds->width()));
321 358
322 gfx::Rect work_area = display.work_area(); 359 gfx::Rect work_area = display.work_area();
323 // Ensure that the title bar is not above the work area. 360 // Ensure that the title bar is not above the work area.
324 if (bounds->y() < work_area.y()) 361 if (bounds->y() < work_area.y())
325 bounds->set_y(work_area.y()); 362 bounds->set_y(work_area.y());
326 363
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 // ensure that at least kMinVisibleWidth * kMinVisibleHeight is visible. 400 // ensure that at least kMinVisibleWidth * kMinVisibleHeight is visible.
364 const int min_y = work_area.y() + kMinVisibleHeight - bounds->height(); 401 const int min_y = work_area.y() + kMinVisibleHeight - bounds->height();
365 const int min_x = work_area.x() + kMinVisibleWidth - bounds->width(); 402 const int min_x = work_area.x() + kMinVisibleWidth - bounds->width();
366 const int max_y = work_area.bottom() - kMinVisibleHeight; 403 const int max_y = work_area.bottom() - kMinVisibleHeight;
367 const int max_x = work_area.right() - kMinVisibleWidth; 404 const int max_x = work_area.right() - kMinVisibleWidth;
368 bounds->set_y(std::max(min_y, std::min(max_y, bounds->y()))); 405 bounds->set_y(std::max(min_y, std::min(max_y, bounds->y())));
369 bounds->set_x(std::max(min_x, std::min(max_x, bounds->x()))); 406 bounds->set_x(std::max(min_x, std::min(max_x, bounds->x())));
370 #endif // defined(OS_MACOSX) 407 #endif // defined(OS_MACOSX)
371 } 408 }
372 409
410 gfx::Display WindowSizer::GetTargetDisplay(const gfx::Rect& bounds) const {
411 return target_display_provider_->GetTargetDisplay(screen_, bounds);
412 }
413
373 ui::WindowShowState WindowSizer::GetWindowDefaultShowState() const { 414 ui::WindowShowState WindowSizer::GetWindowDefaultShowState() const {
374 if (!browser_) 415 if (!browser_)
375 return ui::SHOW_STATE_DEFAULT; 416 return ui::SHOW_STATE_DEFAULT;
376 417
377 // Only tabbed browsers use the command line or preference state, with the 418 // Only tabbed browsers use the command line or preference state, with the
378 // exception of devtools. 419 // exception of devtools.
379 bool show_state = !browser_->is_type_tabbed() && !browser_->is_devtools(); 420 bool show_state = !browser_->is_type_tabbed() && !browser_->is_devtools();
380 421
381 #if defined(USE_AURA) 422 #if defined(USE_AURA)
382 // We use the apps save state on aura. 423 // We use the apps save state on aura.
(...skipping 19 matching lines...) Expand all
402 browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH && 443 browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH &&
403 browser_->is_type_tabbed(); 444 browser_->is_type_tabbed();
404 } 445 }
405 446
406 bool WindowSizer::IsPopupBrowserInAsh() const { 447 bool WindowSizer::IsPopupBrowserInAsh() const {
407 return browser_ && 448 return browser_ &&
408 browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH && 449 browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH &&
409 browser_->is_type_popup(); 450 browser_->is_type_popup();
410 } 451 }
411 #endif 452 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698