| OLD | NEW |
| 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 <Carbon/Carbon.h> | 5 #include <Carbon/Carbon.h> |
| 6 | 6 |
| 7 #include "base/mac_util.h" | 7 #include "base/mac_util.h" |
| 8 #include "base/scoped_nsdisable_screen_updates.h" | 8 #include "base/scoped_nsdisable_screen_updates.h" |
| 9 #import "base/scoped_nsobject.h" | 9 #import "base/scoped_nsobject.h" |
| 10 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 | 348 |
| 349 // We need to deactivate the controls (in the "WebView"). To do this, get the | 349 // We need to deactivate the controls (in the "WebView"). To do this, get the |
| 350 // selected TabContents's RenderWidgetHostView and tell it to deactivate. | 350 // selected TabContents's RenderWidgetHostView and tell it to deactivate. |
| 351 if (TabContents* contents = browser_->GetSelectedTabContents()) { | 351 if (TabContents* contents = browser_->GetSelectedTabContents()) { |
| 352 if (RenderWidgetHostView* rwhv = contents->render_widget_host_view()) | 352 if (RenderWidgetHostView* rwhv = contents->render_widget_host_view()) |
| 353 rwhv->SetActive(false); | 353 rwhv->SetActive(false); |
| 354 } | 354 } |
| 355 } | 355 } |
| 356 | 356 |
| 357 // Called when the user clicks the zoom button (or selects it from the Window | 357 // Called when the user clicks the zoom button (or selects it from the Window |
| 358 // menu). Zoom to the appropriate size based on the content. Make sure we | 358 // menu) to determine the "standard size" of the window, based on the content |
| 359 // enforce a minimum width to ensure websites with small intrinsic widths | 359 // and other factors. If the current size/location differs nontrivally from the |
| 360 // (such as google.com) don't end up with a wee window. Enforce a max width | 360 // standard size, Cocoa resizes the window to the standard size, and saves the |
| 361 // that leaves room for icons on the right side. Use the full (usable) height | 361 // current size as the "user size". If the current size/location is the same (up |
| 362 // regardless. | 362 // to a fudge factor) as the standard size, Cocoa resizes the window to the |
| 363 // saved user size. (It is possible for the two to coincide.) In this way, the |
| 364 // zoom button acts as a toggle. We determine the standard size based on the |
| 365 // content, but enforce a minimum width (calculated using the dimensions of the |
| 366 // screen) to ensure websites with small intrinsic width (such as google.com) |
| 367 // don't end up with a wee window. Moreover, we always declare the standard |
| 368 // width to be at least as big as the current width, i.e., we never want zooming |
| 369 // to the standard width to shrink the window. This is consistent with other |
| 370 // browsers' behaviour, and is desirable in multi-tab situations. Note, however, |
| 371 // that the "toggle" behaviour means that the window can still be "unzoomed" to |
| 372 // the user size. |
| 363 - (NSRect)windowWillUseStandardFrame:(NSWindow*)window | 373 - (NSRect)windowWillUseStandardFrame:(NSWindow*)window |
| 364 defaultFrame:(NSRect)frame { | 374 defaultFrame:(NSRect)frame { |
| 375 // |frame| already fills the current screen. Never touch y and height since we |
| 376 // always want to fill vertically. |
| 377 |
| 365 // If the shift key is down, maximize. Hopefully this should make the | 378 // If the shift key is down, maximize. Hopefully this should make the |
| 366 // "switchers" happy. | 379 // "switchers" happy. |
| 367 if ([[[NSApplication sharedApplication] currentEvent] modifierFlags] & | 380 if ([[[NSApplication sharedApplication] currentEvent] modifierFlags] & |
| 368 NSShiftKeyMask) { | 381 NSShiftKeyMask) { |
| 369 return [[window screen] visibleFrame]; | 382 return frame; |
| 370 } | 383 } |
| 371 | 384 |
| 372 const int kMinimumIntrinsicWidth = 700; | 385 // To prevent strange results on portrait displays, the basic minimum zoomed |
| 373 const int kScrollbarWidth = 16; | 386 // width is the larger of: 60% of available width, 60% of available height |
| 374 const int kSpaceForIcons = 50; | 387 // (bounded by available width). |
| 375 const NSSize screenSize = [[window screen] visibleFrame].size; | 388 const CGFloat kProportion = 0.6; |
| 376 // Always leave room on the right for icons. | 389 CGFloat zoomedWidth = |
| 377 const int kMaxWidth = screenSize.width - kSpaceForIcons; | 390 std::max(kProportion * frame.size.width, |
| 391 std::min(kProportion * frame.size.height, frame.size.width)); |
| 378 | 392 |
| 379 TabContents* contents = browser_->tabstrip_model()->GetSelectedTabContents(); | 393 TabContents* contents = browser_->tabstrip_model()->GetSelectedTabContents(); |
| 380 if (contents) { | 394 if (contents) { |
| 381 int intrinsicWidth = contents->view()->preferred_width() + kScrollbarWidth; | 395 // If the intrinsic width is bigger, then make it the zoomed width. |
| 382 int tempWidth = std::max(intrinsicWidth, kMinimumIntrinsicWidth); | 396 const int kScrollbarWidth = 16; // FIXME(viettrungluu@gmail.com): ugh. |
| 383 frame.size.width = std::min(tempWidth, kMaxWidth); | 397 CGFloat intrinsicWidth = static_cast<CGFloat>( |
| 384 frame.size.height = screenSize.height; | 398 contents->view()->preferred_width() + kScrollbarWidth); |
| 399 zoomedWidth = std::max(zoomedWidth, |
| 400 std::min(intrinsicWidth, frame.size.width)); |
| 385 } | 401 } |
| 402 |
| 403 // Never shrink from the current size on zoom (see above). |
| 404 NSRect currentFrame = [[self window] frame]; |
| 405 zoomedWidth = std::max(zoomedWidth, currentFrame.size.width); |
| 406 |
| 407 // |frame| determines our maximum extents. We need to set the origin of the |
| 408 // frame -- and only move it left if necessary. |
| 409 if (currentFrame.origin.x + zoomedWidth > frame.origin.x + frame.size.width) |
| 410 frame.origin.x = frame.origin.x + frame.size.width - zoomedWidth; |
| 411 else |
| 412 frame.origin.x = currentFrame.origin.x; |
| 413 |
| 414 // Set the width. Don't touch y or height. |
| 415 frame.size.width = zoomedWidth; |
| 416 |
| 386 return frame; | 417 return frame; |
| 387 } | 418 } |
| 388 | 419 |
| 420 // Determine whether we should let a window zoom/unzoom to the given |newFrame|. |
| 421 // We avoid letting unzoom move windows between screens, because it's really |
| 422 // strange and unintuitive. |
| 423 - (BOOL)windowShouldZoom:(NSWindow*)window toFrame:(NSRect)newFrame { |
| 424 // Figure out which screen |newFrame| is on. |
| 425 NSScreen* newScreen = nil; |
| 426 CGFloat newScreenOverlapArea = 0.0; |
| 427 for (NSScreen* screen in [NSScreen screens]) { |
| 428 NSRect overlap = NSIntersectionRect(newFrame, [screen frame]); |
| 429 CGFloat overlapArea = overlap.size.width * overlap.size.height; |
| 430 if (overlapArea > newScreenOverlapArea) { |
| 431 newScreen = screen; |
| 432 newScreenOverlapArea = overlapArea; |
| 433 } |
| 434 } |
| 435 // If we're somehow not on any screen, allow the zoom. |
| 436 if (!newScreen) |
| 437 return YES; |
| 438 |
| 439 // If the new screen is the current screen, we can return a definitive YES. |
| 440 // Note: This check is not strictly necessary, but just short-circuits in the |
| 441 // "no-brainer" case. To test the complicated logic below, comment this out! |
| 442 NSScreen* curScreen = [window screen]; |
| 443 if (newScreen == curScreen) |
| 444 return YES; |
| 445 |
| 446 // Worry a little: What happens when a window is on two (or more) screens? |
| 447 // E.g., what happens in a 50-50 scenario? Cocoa may reasonably elect to zoom |
| 448 // to the other screen rather than staying on the officially current one. So |
| 449 // we compare overlaps with the current window frame, and see if Cocoa's |
| 450 // choice was reasonable (allowing a small rounding error). This should |
| 451 // hopefully avoid us ever erroneously denying a zoom when a window is on |
| 452 // multiple screens. |
| 453 NSRect curFrame = [window frame]; |
| 454 NSRect newScrIntersectCurFr = NSIntersectionRect([newScreen frame], curFrame); |
| 455 NSRect curScrIntersectCurFr = NSIntersectionRect([curScreen frame], curFrame); |
| 456 if (newScrIntersectCurFr.size.width*newScrIntersectCurFr.size.height >= |
| 457 (curScrIntersectCurFr.size.width*curScrIntersectCurFr.size.height - 1.0)) |
| 458 return YES; |
| 459 |
| 460 // If it wasn't reasonable, return NO. |
| 461 return NO; |
| 462 } |
| 463 |
| 389 // Main method to resize browser window subviews. This method should be called | 464 // Main method to resize browser window subviews. This method should be called |
| 390 // when resizing any child of the content view, rather than resizing the views | 465 // when resizing any child of the content view, rather than resizing the views |
| 391 // directly. If the view is already the correct height, does not force a | 466 // directly. If the view is already the correct height, does not force a |
| 392 // relayout. | 467 // relayout. |
| 393 - (void)resizeView:(NSView*)view newHeight:(float)height { | 468 - (void)resizeView:(NSView*)view newHeight:(float)height { |
| 394 // We should only ever be called for one of the following three views. | 469 // We should only ever be called for one of the following three views. |
| 395 // |downloadShelfController_| may be nil. | 470 // |downloadShelfController_| may be nil. |
| 396 DCHECK(view); | 471 DCHECK(view); |
| 397 DCHECK(view == [toolbarController_ view] || | 472 DCHECK(view == [toolbarController_ view] || |
| 398 view == [infoBarContainerController_ view] || | 473 view == [infoBarContainerController_ view] || |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1299 provider->GetNSColor(BrowserThemeProvider::COLOR_TOOLBAR); | 1374 provider->GetNSColor(BrowserThemeProvider::COLOR_TOOLBAR); |
| 1300 [theme setValue:toolbarBackgroundColor | 1375 [theme setValue:toolbarBackgroundColor |
| 1301 forAttribute:@"backgroundColor" | 1376 forAttribute:@"backgroundColor" |
| 1302 style:GTMThemeStyleToolBar | 1377 style:GTMThemeStyleToolBar |
| 1303 state:GTMThemeStateActiveWindow]; | 1378 state:GTMThemeStateActiveWindow]; |
| 1304 | 1379 |
| 1305 return theme; | 1380 return theme; |
| 1306 } | 1381 } |
| 1307 @end | 1382 @end |
| 1308 | 1383 |
| OLD | NEW |