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