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