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

Side by Side Diff: chrome/browser/cocoa/browser_window_controller.mm

Issue 173254: Mac: Fix zoom (green maximize) button. (Closed)
Patch Set: Added comments about arbitrary constants. Created 11 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
« no previous file with comments | « no previous file | chrome/browser/cocoa/browser_window_controller_unittest.mm » ('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 <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
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
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
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/cocoa/browser_window_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698