Home | History | Annotate | Download | only in cocoa
      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