1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#import "chrome/browser/ui/cocoa/version_independent_window.h" 6 7#include "base/command_line.h" 8#include "base/logging.h" 9#include "base/mac/mac_util.h" 10#include "chrome/common/chrome_switches.h" 11 12@interface VersionIndependentWindow () 13 14+ (BOOL)shouldUseFullSizeContentViewForStyle:(NSUInteger)windowStyle; 15 16- (NSView*)chromeWindowView; 17 18@end 19 20// This view always takes the size of its superview. It is intended to be used 21// as a NSWindow's contentView. It is needed because NSWindow's implementation 22// explicitly resizes the contentView at inopportune times. 23@interface FullSizeContentView : NSView 24@end 25 26@implementation FullSizeContentView 27 28// This method is directly called by NSWindow during a window resize on OSX 29// 10.10.0, beta 2. We must override it to prevent the content view from 30// shrinking. 31- (void)setFrameSize:(NSSize)size { 32 if ([self superview]) 33 size = [[self superview] bounds].size; 34 [super setFrameSize:size]; 35} 36 37// The contentView gets moved around during certain full-screen operations. 38// This is less than ideal, and should eventually be removed. 39- (void)viewDidMoveToSuperview { 40 [self setFrame:[[self superview] bounds]]; 41} 42 43@end 44 45@implementation NSWindow (VersionIndependentWindow) 46 47- (NSView*)cr_windowView { 48 if ([self isKindOfClass:[VersionIndependentWindow class]]) { 49 VersionIndependentWindow* window = 50 static_cast<VersionIndependentWindow*>(self); 51 NSView* chromeWindowView = [window chromeWindowView]; 52 if (chromeWindowView) 53 return chromeWindowView; 54 } 55 56 return [[self contentView] superview]; 57} 58 59@end 60 61@implementation VersionIndependentWindow 62 63#pragma mark - Lifecycle 64 65- (instancetype)init { 66 NOTREACHED(); 67 return nil; 68} 69 70- (instancetype)initWithContentRect:(NSRect)contentRect 71 styleMask:(NSUInteger)windowStyle 72 backing:(NSBackingStoreType)bufferingType 73 defer:(BOOL)deferCreation { 74 self = [super initWithContentRect:contentRect 75 styleMask:windowStyle 76 backing:bufferingType 77 defer:deferCreation]; 78 if (self) { 79 if ([VersionIndependentWindow 80 shouldUseFullSizeContentViewForStyle:windowStyle]) { 81 chromeWindowView_.reset([[FullSizeContentView alloc] init]); 82 [chromeWindowView_ 83 setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; 84 [chromeWindowView_ setFrame:[[[self contentView] superview] bounds]]; 85 [self setContentView:chromeWindowView_]; 86 } 87 } 88 return self; 89} 90 91#pragma mark - Private Methods 92 93+ (BOOL)shouldUseFullSizeContentViewForStyle:(NSUInteger)windowStyle { 94 // TODO(erikchen): Once OSX Yosemite is released, consider removing this 95 // class entirely. 96 // http://crbug.com/398574 97 if (!CommandLine::ForCurrentProcess()->HasSwitch( 98 switches::kEnableFullSizeContentView)) 99 return NO; 100 return (windowStyle & NSTitledWindowMask) && base::mac::IsOSYosemiteOrLater(); 101} 102 103- (NSView*)chromeWindowView { 104 return chromeWindowView_; 105} 106 107#pragma mark - NSWindow Overrides 108 109#ifndef NDEBUG 110 111- (void)setContentSize:(NSSize)size { 112 DCHECK(!chromeWindowView_); 113 [super setContentSize:size]; 114} 115 116- (void)setContentMinSize:(NSSize)size { 117 DCHECK(!chromeWindowView_); 118 [super setContentMinSize:size]; 119} 120 121- (void)setContentMaxSize:(NSSize)size { 122 DCHECK(!chromeWindowView_); 123 [super setContentMaxSize:size]; 124} 125 126- (void)setContentAspectRatio:(NSSize)ratio { 127 DCHECK(!chromeWindowView_); 128 [super setContentAspectRatio:ratio]; 129} 130 131#endif // NDEBUG 132 133+ (NSRect)frameRectForContentRect:(NSRect)cRect styleMask:(NSUInteger)aStyle { 134 if ([self shouldUseFullSizeContentViewForStyle:aStyle]) 135 return cRect; 136 return [super frameRectForContentRect:cRect styleMask:aStyle]; 137} 138 139- (NSRect)frameRectForContentRect:(NSRect)contentRect { 140 if (chromeWindowView_) 141 return contentRect; 142 return [super frameRectForContentRect:contentRect]; 143} 144 145+ (NSRect)contentRectForFrameRect:(NSRect)fRect styleMask:(NSUInteger)aStyle { 146 if ([self shouldUseFullSizeContentViewForStyle:aStyle]) 147 return fRect; 148 return [super contentRectForFrameRect:fRect styleMask:aStyle]; 149} 150 151- (NSRect)contentRectForFrameRect:(NSRect)frameRect { 152 if (chromeWindowView_) 153 return frameRect; 154 return [super contentRectForFrameRect:frameRect]; 155} 156 157@end 158